Por fin hemos llegado al último tutorial del curso de Docker. En él no aprenderemos nada nuevo ya que, básicamente, es un resumen o cheat sheet con los comandos más importantes para crear imágenes y contenedores y las líneas más utilizadas en los ficheros Dockerfile y docker-compose.yml.
Antes de ello vamos a hacer un repaso de todo lo que hemos visto a lo largo del curso:
- Docker en la teoría y conceptos importantes, donde vimos múltiples temas que después aplicamos en la práctica.
- Comandos para imágenes y contenedores, aunque no vimos absolutamente todos los comandos sí que vimos los más importantes, sobre todo para conocer un poco la maquinaria interna de Docker y cómo funciona éste internamente.
- Cómo crear imágenes con Dockerfile, aunque los comandos son útiles para conocer el funcionamiento interno de Docker, la verdad es que no se suelen utilizar mucho a la hora de crear imágenes y contenedores, lo que realmente se utiliza son los ficheros.
- Cómo configurar un conjunto de contenedores con docker-compose.yml, recuerda que este fichero utiliza, a su vez, los ficheros Dockerfile para crear imágenes y permite definir el comportamiento de los contenedores en su conjunto para que éstos trabajen de manera segura y óptima.
- Cómo desplegar contenedores Docker a la nube y publicar imágenes en Internet, el último paso necesario para que nuestras imágenes se puedan compartir y que nuestra aplicación sea accesible al público.
Seguiremos una sintaxis estándar donde, por ejemplo, los corchetes “[]” indican que el elemento es opcional.
Comandos de imágenes más utilizados
Como ya sabes, el primer paso en Docker consiste en descargar o crear una imágen para después meterla en un contenedor. En este apartado veremos los comandos relacionados con imágenes que hemos utilizado a lo largo del curso de Docker:
- docker images, permite listar y ver la información de las imágenes descargadas con el comando
pullo creadas con el comandobuilden nuestro ordenador.
Ejemplo de comando docker images para listar imagenes - docker pull imagen[:etiqueta], descarga una imagen desde una URL, recomendado utilizar etiqueta con versión específica. Podemos descargar imágenes desde repositorios de imágenes tales como Docker Hub o Azure Container Registry.
- docker push imagen:etiqueta para realizar la operación contraria a la anterior, es decir, subir una imagen a un repositorio. Es necesario estar logueado previamente con el comando
docker login. - docker image rm imagen[:etiqueta], elimina una imagen concreta en nuestro ordenador.

Ejemplo comando docker image rm para eliminar imagenes - docker build -t nombre[:etiqueta] ./. Crea una imagen con el nombre que pongamos utilizando el fichero Dockerfile que se encuentre en la ruta especificada en el último parámetro (./ para indicar carpeta actual).
Opcionalmente podemos utilizar etiquetas para versionarlas de manera similar a como lo hacemos con el código.
El parámetro -t nos permite asignar una etiqueta.
Ejemplo comando build para crear imagenes con Dockerfile - docker image prune [PARÁMETROS], elimina las imágenes “huérfanas” que están almacenadas en nuestro sistema.
Parámetros:- -a, además de eliminar las imágenes huérfanas también elimina aquellas imágenes que no se estén utilizando en algún contenedor.
- docker image save [PARÁMETROS] imagen[:etiqueta], utilizado para exportar una imagen a un fichero comprimido en .tar. Permite compartir de manera privada imágenes sin necesidad de utilizar ningún repositorio público.
Parámetros:- -o fichero.tar, para indicar el fichero de salida y su nombre.

Ejemplo docker image save para exportar imagenes - docker image load [PARÁMETROS] para crear una imagen a partir de un archivo, es la operación contraria a la anterior.
Parámetros:- -i fichero.tar para especificar el fichero del que leeremos la imagen para cargarla en nuestro sistema.

Ejemplo docker image load para crear imagenes desde ficheros - docker image tag antiguo-nombre:etiqueta nuevo-nombre:etiqueta. Crea una copia de la imagen con un nombre distinto. No es una copia completa, simplemente es un enlace a la imagen con el nombre antiguo.
Comandos para contenedores Docker
El siguiente paso a la creación de imágenes es la creación de contenedores para lo cual utilizaremos los siguientes comandos:
- docker create [PARÁMETROS] imagen[:etiqueta], crea un contenedor sin iniciarlo a partir de la imagen especificada.
Parámetros:- –name Nombre. Para asignar un nombre al contenedor y después poder referenciarlo por su nombre y no por su id.
- -e parametro=’valor’. Permite configurar y establecer variables de entorno para el contenedor.
- -p XX:YY. Para mapear puertos entre el ordenador local y el contenedor. XX es el puerto de la máquina anfitrión (público) e YY es el puerto del contenedor (privado).
- -v MyVolume:/home asigna a la carpeta /home del contenedor el volumen previamente creado “MyVolume”.
- –user=userName ejecuta el contenedor con un usuario concreto.
- -i para ejecutarlo de manera interactiva.

Ejemplo comando docker create para crear contenedores - docker start (id|nombre) inicia un contenedor dado su id o nombre, necesario especificar uno de los dos valores.
Parámetros:- -i para modo interactivo.
- docker stop (id|nombre) para parar un contenedor que se encuentra iniciado, misma nomenclatura que start, necesario indicar el identificador o el nombre del contenedor en cuestión.
- docker ps, listado de contenedores junto con información útil acerca de éstos como, por ejemplo, su id, imagen que utiliza o el estado en el que se encuentra.
Parámetros:- -a para ver todos los contenedores, incluso los detenidos.
- –size para ver el tamaño de los contenedores.

Ejemplo comando ps para listar contenedores - docker container rm (id|nombre) permite eliminar un contenedor de nuestro ordenador.
- docker logs (id|nombre) para ver los logs una vez que un contenedor se ha iniciado con start.

Comando docker logs para logs de contenedores iniciados - docker exec (id|nombre) para ejecutar comandos en un contenedor que se encuentra en estado iniciado.
Parámetros:- -it (id|nombre) sh, permite ingresar a un contenedor activo con la terminal indicada en modo interactivo (sh en este caso, pero puede ser otra).
- (id|nombre) comando, lo mismo que el anterior pero permite ejecutar solo un comando sin entrar en el contenedor en modo interactivo.

Modo interactivo en contenedor iniciado - docker container prune, elimina todos los contenedores que estén parados.
- docker cp origen destino, copia archivos entre el contenedor y el sistema operativo anfitrión.
La dirección de la operación dependerá de cómo escribamos las rutas dentro de los parámetros “origen” y “destino”:- Si escribimos “(id|nombre):/carpeta/fichero” nos estamos refiriendo a un fichero dentro del contenedor.
- Si escribimos únicamente “/carpeta/fichero” nos estamos refiriendo a un fichero de nuestro ordenador.
- Por lo tanto, si utilizamos el comando
docker cp MyContainer:/carpeta/fichero ./estaremos copiando ficheros desde el contenedor a nuestro ordenador local. - Por el contrario, utilizamos el comando
docker cp ./fichero MyContainer:/carpeta/estaremos copiando ficheros desde nuestro ordenador al contenedor.

Comando docker para copiar ficheros desde y hacia un contenedor - docker run [PARÁMETROS] imagen[:etiqueta]. Este comando, como ya hemos visto en el curso de Docker, en realidad realiza tres acciones. Primero descarga la imagen
imagen[:etiqueta]si es que no la tiene ya descargada, después crea un contenedor con la imagen anterior y, finalmente, inicia el contenedor si los pasos anteriores han ido bien.
Los parámetros del comando run son, en su mayoría, idénticos a los del comando create, algunos de los que hemos utilizado a lo largo de este curso Docker son:- -d para que nos devuelva el control de la terminal al ejecutarlo de tal manera que el contenedor se inicia y podemos seguir introduciendo comandos.
- -it para lanzarlo con una terminal en modo interactivo, hay que indicar al final la terminal a utilizar como, por ejemplo,
sh. Si utilizamos sh el comandoCMDdel Dockerfile no se ejecutará y, por lo tanto, la aplicación no se iniciará.

Ejemplo de comando run en Docker con SQL Server
Resumen del fichero Dockerfile
Como ya hemos comentado el fichero Dockerfile sirve para generar imágenes que contengan nuestro proyecto a través de instrucciones. A continuación vamos a ver la estructura y las líneas más importantes del fichero Dockerfile:
- FROM imagen:etiqueta. Imagen base de nuestra imagen.
Recuerda que en Docker los contenedores comparten el núcleo del sistema operativo con el sistema anfitrión, sin embargo es necesario instalar una base para que nuestra aplicación funcione.
Ejemplos de imágenes base pueden ser Alpine (sistema operativo liviano), Ubuntu o incluso imágenes que ya tienen instalado todo aquello que necesitas como, por ejemplo, Apache o MySQL.
Parámetros:- AS alias. Establece, para cada fase o etapa, un alias en ficheros Dockerfile multi-stage.
- WORKDIR ruta. Permite cambiar el directorio de trabajo para, por ejemplo, copiar ficheros más tarde.
- COPY origen destino. Copiar archivos o carpetas desde origen (máquina anfitrión o servidor) a destino (contenedor). Se pueden utilizar asteriscos en los nombres de ficheros.
Parámetros:- –chown=my-app-user para establecer el usuario con el que se realizará la copia y quien será el propietario en el contenedor de las carpetas y archivos copiados.
- –from=alias para copiar ficheros de un stage a otros en ficheros Dockerfile multi-stage.

Ejemplo comandos Dockerfile from copy y workdir - ADD origen destino. Igual que copy pero permite como argumento una url como, por ejemplo, “http://myWeb/files” e incluso ficheros .zip que descomprime. No recomendado porque, al tener más funcionalidad que COPY, es más pesado y hace que la creación de la imagen tarde más.
- RUN comando. Ejecutar comandos (Linux o Windows) a través de Dockerfile.
- ARG Variable=Valor. Permite definir argumentos para utilizarlos durante la construcción de la imagen, no después.
- ENV Variable=Valor. Establecer variables de entorno que serán utilizadas durante la ejecución de la aplicación en un contenedor.
La diferencia entre ARG y ENV es que ARG son variables utilizadas durante la creación de una imagen y ENV son variables utilizadas durante la ejecución de la aplicación en el contenedor. Podéis encontrar una buena explicación sobre ARG vs ENV en el enlace anterior. - EXPOSE puerto. Puertos de acceso, cuidado, es solo a nivel informativo, esto no permite el acceso al contenedor Docker, lo que realmente permite el acceso es
docker run -p XX:YYo su equivalente en el fichero docker-compose.yml. - USER my-user. Usuario con el que se ejecutará el contenedor o, mejor dicho, usuario con el que se ejecutarán las instrucciones que vengan a continuación. Recomendado cambiarlo a uno que no sea root.
Solo se aplica a todos los comandos que sean RUN, CMD o ENTRYPOINT y que estén a continuación de la línea USER.
Como consecuencia de lo anterior, para el comando COPY, debemos indicar el usuario propietario de manera explícita tal y como vimos anteriormente:COPY --chown=my-app-user ./ /usr/local/apache2/htdocs/ - CMD [“comando1”, “comando2”]. Ejecutar comandos, la diferencia con RUN es que RUN se ejecuta mientras se crea la imagen y CMD cuando se inicia el contenedor.
- ENTRYPOINT [“comando1”, “comando2”]. Es exactamente igual al anterior, la diferencia radica en que si queremos reemplazar el comando en
docker run imagen echo hola, con CMD podemos hacerlo tal cual está puesto pero, con ENTRYPOINT, debemos agregar –entrypoint, es decir,docker run imagen --entrypoint echo hola.

Comandos para docker-compose.yml
Tal y como vimos en la teoría, docker-compose.yml se utiliza para que podamos construir y ejecutar un conjunto de contenedores con toda la configuración necesaria. Para la creación de imágenes, si fuese necesario, utiliza los Dockerfile de cada uno de los contenedores.
A continuación veremos los comandos más importantes y utilizados en docker-compose.yml:
- docker compose [PARÁMETROS], ejecuta el fichero docker-compose.yml del directorio actual.
Parámetros:- up, es el parámetro que realmente levanta todos los contenedores construyendo, si fuese necesario, las imágenes de los ficheros Dockerfile.
- -d, modo detach, para no mostrar los logs al levantar los contenedores.
- -d, modo detach, para no mostrar los logs al levantar los contenedores.
- build, indica a Docker que cree las imágenes desde el principio sin utilizar ninguna previamente creada, útil para depurar errores. No levanta contenedores, sólo crea imágenes.
- –no-cache para no utilizar la caché al crear imágenes, útil para depurar errores y recrear imágenes.
- create, similar a up, la diferencia entre up vs create en compose es que
createsolo crea contenedores, no los inicia automáticamente. - down, detiene y elimina los contenedores y redes que se hayan creado con el fichero docker-compose.yml.
- logs, para ver los logs de los contenedores creados una vez se han iniciado.
- -f para seguir los logs conforme se van generando.
- -t para ver los timestamp de cada uno de ellos.
- ps, para listar los contenedores utilizados por docker compose.

Ejemplo de docker compose up 
Ejemplo docker compose up y down 
Ejemplo docker compose ps para listar contenedores - up, es el parámetro que realmente levanta todos los contenedores construyendo, si fuese necesario, las imágenes de los ficheros Dockerfile.
docker-compose.yml líneas más importantes y resumen
En el apartado anterior hablamos sobre comandos, ahora le toca el turno a las partes más importantes del fichero docker-compose.yml:
- services, para indicar las partes que componen nuestro proyecto. Cada service tendrá su propio nombre como, por ejemplo, API, APP y DB.
Importante, el nombre se puede utilizar para permitir la comunicación entre ellos sin necesidad de ip.
Parámetros de services:- image, imagen externa que utilizará el contenedor, debe estar hospedada en algún sistema para subir imágenes.
- build, imagen interna, dónde se encuentra el Dockerfile que utilizaremos para construir la imagen.
- ports, sirve para mapear puertos locales del contenedor con externos de la máquina anfitrión, formato XX:YY donde XX es el puerto de la máquina anfitrión e YY es el puerto del contenedor.
- environment, para establecer el valor de variables de entorno o configuración que serán utilizadas mientras el contenedor se ejecuta.
Forma 1, “Variable:valor”.
Forma 2, – “VariablePadre__VariableHijo=Valor”, utilizada para establecer variables de entorno con hijos en docker-compose.yml.
Dentro de los valores podemos utilizar el nombre de otro service en vez de una ip. - volumes permite que un contenedor utilice como almacenamiento persistente un volúmen que crearemos más adelante, fuera de la sección service.
Formato “nombre-volumen:ruta-carpeta-contenedor”. - networks, para asignarle una o varias redes al contenedor, tantos hijos como redes queramos añadir.
- depends_on seguido de un listado de nombres de servicio indica los servicios de los que depende el contenedor actual. Nos permite definir el orden de ejecución y las dependencias.
Por defecto Docker solo verifica que el contenedor del que depende se esté ejecutando, nada más.
Si queremos indicarle que verifique que el contenedor del que depende se esté ejecutando correctamente deberemos utilizar la opcióncondition: service_healthy. - healthcheck, indica, para un contenedor X, cuando su estado es “service_healthy”.
Para ejecutar un determinado test de salud con la terminal utilizaremos como subapartado el comandotest: ["CMD-SHELL", comando]y, opcionalmente, las instruccionesinterval, retries, start period y timeout.
Si un contenedor Y depende del contenedor X y tiene la líneacondition: service_healthydentro deldepends_on, el contenedor Y no se iniciará hasta que se cumpla elhealthcheckdel contenedor X.

docker-compose yml services build vs image 
Ejemplo variables configuracion y puertos en docker-compose yml 
docker-compose yml ejemplo volumenes y redes 
docker-compose yml ejemplo depends_on y healthcheck - volumes, sección para crear volúmenes, solo hace falta que tenga tantos hijos como volúmenes queramos crear. Después será necesario, tal y como hemos visto, asignarlo a cada servicio a través de la instrucción
volumes. - networks, permite definir un listado de redes a crear. Después las asignaremos a cada servicio simplemente con el apartado
networksdentro de cada uno de ellos.
Además hay que indicar el driver de la red, el cual puede ser bridge, host, overlay y none entre otros.
Ejemplo de redes en fichero docker-compose yml
Otros comandos útiles de Docker
Llegamos al último apartado donde veremos comandos que, si bien no tienen nada que ver con la creación de imágenes, ejecución de contenedores o ejecución de ficheros, a lo largo de este curso de Docker han sido comandos útiles:
- docker version, para conocer la versión instalada, también sirve para comprobar que la instalación es correcta y ver información sobre la herramienta.
- docker comando –help, permite obtener ayuda sobre un comando determinado como, por ejemplo,
docker start --helpnos proporciona un resumen con la funcionalidad del comando start junto con los argumentos que podemos utilizar. - docker volume create MyVolume, crea el volumen con el nombre “MyVolume” para la persistencia de datos entre contenedores, necesario asignarlo con el comando
docker create -v MyVolume:/home. - docker volume inspect MyVolume, para ver información sobre un determinado volumen.
- docker system prune -a, sirve para eliminar todos los contenedores, imágenes y caché que tengamos en Docker, ¡utilízalo con cuidado!.
- docker login para iniciar sesión en Docker Hub y subir imágenes a nuestro repositorio.
- docker network para ver información sobre las redes.
- ls permite listar todas las redes locales creadas.
- docker inspect (id|nombre), permite ver información en formato json de objetos de Docker como, por ejemplo, contenedores e imágenes.

Ejemplo comando docker inspect en contenedor - service docker start, para iniciar el servicio de Docker en entornos Linux.

























