Crear Imagen y Contenedor Docker Nivel Chūnin

Continúa tu camino a la Dockerizacion, al utilizar un Dockerfile para agilizar la construcción de imágenes Docker; aprende a agregar archivos a tu imagen Docker, consolidando así lo que necesitas para ejecutar tu código en un Contenedor ¡De veras!

Retomemos el camino

En un post anterior, utilizamos una imagen base para crear un contenedor, sin utilizar archivos de aplicación adicionales; la imagen fue de un Webserver (Nginx) que pudimos echar a andar y probar desde un explorador web.

Directo al Dockerfile

Las imágenes base de Docker traen una versión mínima de S.O. y un entorno para que las aplicaciones se ejecuten, y justo aquí nos preguntamos ¿Cómo le ponemos nuestra aplicación a la imagen base? Para ello, necesitas modificar la imagen base, agregando tus archivos, estableciendo puntos de entrada a tu aplicación, parámetros. Entonces, aquí recurrimos a un archivo llamado Dockerfile, a secas, es decir, sin extensión de archivo en particular (esto es lo default); en él, se define cómo consolidar en una sóla imágen nuestros archivos de aplicación, la imagen base y demás parámetros que servirán para su posterior ejecución en un contenedor.

En un Dockerfile vamos a escribir los comandos necesarios para formar una imagen final, típicamente lo que se indica en el archivo es lo siguiente:

  1. Imagen base a utilizar
  2. Copiar archivos a la imagen, indicando origen y destino
  3. Indicar algún comando o punto de entrada a ejecutar cuando la imagen se implemente en un contenedor

En la práctica puede haber más pasos, se abordarán en futuros post ya que merecen su propio espacio.

Para el Ejemplo: Los insumos

El objetivo es mostrar cómo consolidar nuestro código en una imagen base, así que usaremos un código HTML de una página muy sencilla, después crearemos la imagen final, y por último la usaremos en un contenedor.
Por favor, descarga los archivos index.html y Dockerfile del siguiente link, se descargará un archivo Zip; antes de extraer archivos, quita el bloqueo del archivo Zip, para ello ve a sus propiedades y haz clic en el checkbox y después clic en aceptar:

Sugiero extraer los archivos en una ruta sin tantas carpetas superiores, para usar rutas cortas durante el desarrollo de nuestro ejercicio.

¡Vamos a usar el Dockerfile!

Primero, en nuestra ventana de terminal, establecemos la carpeta donde dejamos los archivos. En Windows esto es:

cd "C:\ParentFolder\IndexSimplePage"

A lo anterior llamemoslo establecer contexto de construcción o directorio de trabajo.

Ahora ejecuta la siguiente línea

docker image build -t imynginx:1.0 .

El código anterior lo que hace es construir la imagen, asignarle un nombre y etiqueta, también se especifica la ruta de trabajo donde irá a buscar (por default) un archivo llamado Dockerfile. Como salida, puede arrojar algo similar a lo siguiente:

[+] Building 0.4s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                               0.0s
 => => transferring dockerfile: 467B                                                                               0.0s
 => [internal] load .dockerignore                                                                                  0.0s
 => => transferring context: 2B                                                                                    0.0s
 => [internal] load metadata for docker.io/library/nginx:latest                                                    0.0s
 => [1/2] FROM docker.io/library/nginx                                                                             0.2s
 => [internal] load build context                                                                                  0.0s
 => => transferring context: 32B                                                                                   0.0s
 => [2/2] COPY index.html /usr/share/nginx/html                                                                    0.0s
 => exporting to image                                                                                             0.1s
 => => exporting layers                                                                                            0.0s
 => => writing image sha256:b52d80791ef7566b27f2ae62c9dd16fcea18e05ffb9ad86038de9646e52c4909                       0.0s
 => => naming to docker.io/library/imynginx:1.0

Esto me resultó así ya que previamente había descargado la imagen de Nginx, y ésta ya se encontraba en mi repositorio local de imágenes Docker. En posteriores post ahondaremos más acerca de dicho repositorio, y la posibilidad de tener un repositorio no local (registry).

Observa que al comando build le indicamos al final un punto, así es como le decimos que utilice todos los archivos de la ruta (path) donde estamos posicionados ¿Y dónde estamos? Recuerda que usamos previamente el comando cd, por tanto, ahí es donde establecimos el contexto de construcción, para fines de este post, ahí es donde se tomará el archivo Dockerfile. 

De momento, ten en cuenta que el contexto de construcción (build context) es el lugar donde el proceso que realiza el comando build toma como referencia para la construcción de la imagen, si hay alguna instrucción dentro de tu Dockerfile que manipule archivos, éstos van a buscarse a partir de dicho contexto.

Continuando con el ejemplo, es hora de utilizar el comando para mostrar las imágenes Docker que tenemos:

docker images
REPOSITORY           TAG       IMAGE ID       CREATED         SIZE
imynginx             1.0       e926220e96c6   8 minutes ago   141MB

Corroboramos que tenemos nuestra imagen con el nombre y etiqueta que colocamos. ¡Es momento de darle vida en un contenedor 😃!

Ejecuta la siguiente línea:

docker run --name cmynginx -p 80:80 -d imynginx:1.0

La salida del comando anterior será el id del contenedor (algo como 00c13c6a11a3e3c99dca…).

Para comprobar nuestros resultados, abre tu navegador y ve a la URL http://localhost:80

Debe ver una página como a continuación:

Ajá, pero 🎵con el Dockerfile ¿Qué cosa sucede?🎵

Veamos qué hace cada línea. Básicamente son tres instrucciones las que usamos en este sencishito post:

La primer instrucción es para indicar la imagen base a utilizar

FROM nginx

Con la siguiente línea copiamos un archivo, index.html (nuestro código), a una ruta cuyo último directorio se llama “html”, que ya existe dentro de la imagen base y es una ruta especial que utiliza el Webserver Nginx

COPY index.html /usr/share/nginx/html

La última línea es la siguiente, y sirve para establecer un proceso y parámetros que se ejecutarán cuando la imagen se implemente en un contenedor

CMD ["nginx", "-g", "daemon off;"]

Sólo puede haber una instrucción CMD en un archivo Dockerfile, si hubiera más de una, sólo la última se ejecutará o tendrá efecto.

Las demás líneas de código en el archivo Dockerfile de nuestro ejemplo son comentarios, para ponerlos utilice el carácter # (hash tag, gatito 😸).

Algunos comentarios

Hasta aquí ya sabes cómo poder agilizar el proceso de construcción de una imagen Docker, utilizando un Dockerfile. Utilizamos un archivo HTML muy sencillo para representar el código de tu aplicación y se lo pusimos a una imagen base Docker, resultando en una imagen final que se implementó en un contenedor.

Por supuesto que una aplicación, Web por ejemplo, contiene más que sólo un archivo, como librerías o paquetes, scripts, carpeta de contenido multimedia, etc. Y no sólo eso, para obtener los archivos de publicación, se debe compilar el aplicativo previamente, que si bien es algo que ya hacías antes de utilizar Docker, tal vez con ayuda de algún IDE, SDK o herramienta de compilación, ¿Qué sentirías al saber que la compilación, publicación de tu aplicación puede ocurrir durante la construcción de una imagen Docker? OMG! 😱🤪🙀 Esto último lo veremos en el siguiente post, y verás que la Dockerización trae consigo mucha automatización, que es clave en el famosísimo DevOps.

¡行くよ!

Deja un comentario

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