Crear Imagen y Contenedor Docker Nivel Genin

Comienza construyendo una imagen Docker bien papita de implementar en un contenedor, conoce elementos básicos para seguir el camino hacia la dockerización. Por esta vez, no es necesario que cuentes con código de aplicación para publicar 😎. Lo que buscas para entender mejor la construcción de imágenes y contenedores de Docker desde cero, aquí lo puedes encontrar. ¡De veras!

La Imagen, materia prima del contenedor

El contenedor Docker al final es la instancia de una imagen Docker; cuando la imagen pasa de sólo ocupar espacio de almacenamiento, y comienza a consumir memoria RAM, procesamiento, red, o sea cuando la pones a chambear papá.

Comentamos en un post, que existe un repositorio público de imágenes base Docker. Las imágenes base tienen archivos que tus aplicaciones pueden necesitar para su ejecución, pero principalmente traen los archivos mínimos del sistema operativo para que el contenedor viva. Y hay de dos sopas, o tus imágenes ejecutarán Linux o Windows, y depende del sistema operativo de la máquina Host; dicha máquina es aquella que trae el motor de Docker.

Entonces, comienzas desde una imagen base a la que posteriormente vas a agregar los archivos que necesites para lograr ejecutar algo.

Vamos al Ejemplo

Espero que ya tengas tu laboratorio listo para tirar comandos, si aún no lo tienes y trabajas con Windows 10, puedes darte una vuelta por nuestro post.

¿Qué haremos? 

  • Utilizar Nginx y crear un contenedor y usarlo desde el navegador

Comencemos

Como vamos a utilizar a Nginx, vamos a requerir de los archivos para ejecutarlo en Docker, y de hecho ya existe una imagen Docker con Nginx que podemos utilizar.

Verificamos qué imágenes tenemos actualmente, en nuestro caso no hay imágenes:

C:\Users\mix_i>docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE

C:\Users\mix_i>

Ahora, vamos a usar el siguiente comando

docker run -it --rm -d -p 8080:80 --name web nginx

El comando run hace que Docker  genere un contenedor, lo demás son opciones para ajustar el comportamiento:

  • -it: este es un método para utilizar dos operadores de forma conjunta, y normalmente siempre se usan así cuando se quiere un modo interactivo con el contenedor
  • – – rm: se usa para que el contenedor se elimine cuando el proceso que se haya ejecutado en el contenedor termine. Útil para procesos o aplicaciones que se requiere realicen tareas de corta duración y que al finalizar su ejecución se liberen los recursos de forma automática
  • -d: inicia el contenedor en segundo plano (proceso separado)
  • -p: aquí mapeamos los puertos de nuestro Host con los puertos dentro del contenedor, el protocolo por default es TCP. En este ejemplo, estamos indicando que el puerto 8080 de la máquina Host queremos mapearlo con el puerto 80 del contenedor🧐, así que cuando enviemos peticiones a nuestra máquina Host por el puerto 8080, éstas llegarán al puerto 80 del contenedor
  • – – name: es para asignarle un nombre a nuestro contenedor, y este ejemplo quisimos ponerle de nombre “web”
  • nginx: este no es un comando u opción, lo que pasa es que al final del comando run, se debe especificar el nombre de la imagen a utilizar, y la imagen que deseamos es del web server nginx

El resultado de ejecutar el comando run es el siguiente:

docker run -it --rm -d -p 8080:80 --name web nginx
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
a330b6cecb98: Already exists
e0ad2c0621bc: Pull complete
9e56c3e0e6b7: Pull complete
09f31c94adc6: Pull complete
32b26e9cdb83: Pull complete
20ab512bbb07: Pull complete
Digest: sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e
Status: Downloaded newer image for nginx:latest
68dcf0f3ba7d2dd9fa4367c0fe660c579b0fd2e680c6f619d7933faea6019b05

Debido a que necesitamos contar con una imagen en nuestra máquina Host para crear el contenedor, se observa que al no encontrar una imagen con nombre “nginx” de forma local, automáticamente intentará descargar una del repositorio Docker Hub. Después de la descarga, se crea el contenedor a partir de la imagen.

Podemos revisar las imágenes que tenemos, y comprobar que ahora sí obtenemos información, a diferencia de cuando ejecutamos el comando anteriormente

C:\Users\mix_i>docker images
REPOSITORY   TAG       IMAGE ID       CREATED      SIZE
nginx        latest    ad4c705f24d3   2 days ago   133MB

Por otro lado, podemos listar los contenedores activos, lo que esperamos es ver 1 contenedor activo, para ello, utilizamos el comando “ps”

C:\Users\mix_i>docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
68dcf0f3ba7d   nginx     "/docker-entrypoint.…"   8 minutes ago   Up 8 minutes   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web

Como se observa, la salida default del comando es a modo de tabla, donde vemos la imagen que utiliza el contenedor, cuánto tiempo tiene que se creó la instancia, el estatus actual, y el mapeo de los puertos. Finalmente, en la columna Name, vemos el nombre que asignamos al contenedor. Un dato importante a tener en cuenta es el ID del contenedor, lo usaremos cuando ejecutemos un comando Docker que lo requiera; dicho dato siempre es distinto entre contenedores, y cambia si el contenedor se elimina y se vuelve a crear, en realidad es una cadena más larga de lo que se ve.

Para probar el contenedor, en una ventana de navegador vamos a la URL: http://localhost:8080

Lo que ocurre es que las peticiones llegan a la máquina Host por el puerto 8080, y son enviadas dentro del contenedor a su puerto 80. Esto es por el mapeo que realizamos en el comando “run”, ¿Porqué el contenedor usa el puerto 80? pues por ser el default en el que Nginx escucha peticiones, aunque esto se puede cambiar; si has utilizado Internet Information Services, siglas IIS (el aya yay), te parecerá familiar. 

Aunque también, las peticiones llegan al contenedor porque la máquina Host tiene varias redes (networks) configuradas por default, una de ellas, llamada “bridge” es la red a la que por default un contenedor se conecta cuando lo creas, a no ser que indiques otra cosa. Para que veas este hecho, y siguiendo nuestro ejemplo, ejecuta lo siguiente:

docker network disconnect bridge web

Y ahora vuelve a ejecutar la URL http://localhost:8080 (puede que sea necesario que borres caché de tu navegador), entonces deberás de ver un error de que no puedes acceder a la URL. Para volver a conectar el contenedor a la red, ejecuta lo siguiente:

docker network connect bridge web

Vuelve a probar para corroborar que funciona como al principio 😰
Por último, ¿Recuerdas la opción – – rm que usamos al crear el contenedor?, pues para probar que nuestro contenedor se elimina de forma automática, lo que haremos es detener el contenedor con este comando

docker stop 68dcf0

¿68dcf0? Recuerda que en líneas anteriores, el ID de nuestro contenedor fue “68dcf0f3ba7d”, usamos el dato para referirnos a un contenedor en particular dentro de un comando de Docker, y puedes escribir el ID completo, o algunos primeros caracteres, que no coincidan con los primeros caracteres de otro contenedor al que no quieres afectar.

Revisamos los contenedores activos y no activos con el comando “ps” y opción “-a” (para mostrar contenedores sin importar su estatus) de la siguiente manera

docker ps -a

Cómo puedes ver, no hay resultados, eso quiere decir que después de detenerse el contenedor, éste se eliminó 😦

Puedes volver a ejecutar el comando “run” con las mismas opciones, pero quitando la opcion “- – rm” para volver a crear el contenedor, pero esta vez si detenemos el contenedor no se eliminará

docker run -it -d -p 8080:80 --name web nginx
cc72ef6a3a3ce306080c56853f2a782b92c7cb3522b7ab3968141498f2f6297a

Debido a que ya contábamos con la imagen “nginx”, no fue necesario descargarla, entonces la salida del comando muestra el ID del contenedor que se generó, observa que ya no es el mismo de antes 🤨. 

Revisamos nuevamente los contenedores activos:

docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS                                   NAMES
cc72ef6a3a3c   nginx     "/docker-entrypoint.…"   11 seconds ago   Up 10 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web

Ahora detenemos el contenedor

docker stop cc72ef

Después ejecutamos el comando “ps” con la opción “-a” para ver todos los contenedores independiente de su estatus:

CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS                     PORTS     NAMES
cc72ef6a3a3c   nginx     "/docker-entrypoint.…"   7 minutes ago   Exited (0) 6 seconds ago             web

Como puedes ver, ahora el contenedor no se eliminó, y si intentas probar la URL, verás que no funcionará ya que el contenedor está detenido. Para eliminar manualmente el contenedor, ejecutamos el comando “rm” así

docker rm cc72ef
cc72ef

La salida del comando “rm” es el id del contenedor que se eliminó, si todo fue bien.

Hasta aquí hemos utilizado comandos de uso general para imagen y contenedor, utilizamos una imagen Nginx que podamos echar a andar muy fácilmente para ejemplificar. 

Aunque llegues a sentir cierto gusto por tirar comandos a diestra y siniestra para crear tus contenedores, llegará el día donde necesites agilizar esos procesos, para ello conocerás Dockerfile en un siguiente post… y tu vida cambiará 😎 ¡De veras!

2 comentarios en “Crear Imagen y Contenedor Docker Nivel Genin”

  1. Pingback: Crear Imagen y Contenedor Docker Nivel Chūnin – CodecX

  2. Pingback: Crear Imagen y Contenedor Docker Nivel Jōnin – CodecX

Deja un comentario

Tu dirección de correo electrónico no será publicada.