Creación de imágenes para Docker

imagenes dockerLa creación de imágenes para Docker puede tener diversas razones, ya sea porque no puede encontrar un componente o un servicio que desea usar como parte de su aplicación en Docker. También es posible que se la aplicación que se está desarrollando se tiene que acoplar para facilitar el envío y la implementación. Hasta ahora hemos utilizado Docker con imagenes ya creadas, como se vio en la Práctica con el comando run de Docker. Ahora vamos a crear una aplicación web simple con el Framekork de Python Flask.

Para la creación de imágenes para Docker primero debemos comprender para qué estamos dockerizando o para qué aplicación estamos creando una imagen y cómo se crea la aplicación. Comience por pensar qué podría hacer si desea implementar la aplicación manualmente. Anotamos los pasos necesarios en el orden correcto y creamos una imagen para una aplicación web simple. Si tuviera que configurarlo manualmente sería estos pasos:

  1. Comenzaría con un sistema operativo como un ubuntu
  2. Luego actualizaría los repositorios de origen utilizando el comando apt. 
  3. En tercer lugar instale las dependencias usando el comando apt
  4. Luego instale las dependencias de Python usando el comando pip
  5. Copie el código fuente de mi aplicación en una ubicación como /opt
  6. Finalmente ejecute el servidor web usando el comando “flask”.

 

Creación del archivo para la imagen de Docker

Ahora que se tienen las instrucciones, vamos a crear un archivo acoplable con estos pasos. Aquí hay una descripción general rápida del proceso de creación de su propia imagen:

Primero hay que crear un archivo docker llamado “Dockerfile” y escribir las instrucciones para configurar la aplicación en él, como instalar dependencias, donde copiar el código fuente desde y hacia y cuál es el punto de entrada de la aplicación, etc:

FROM Ubuntu
RUN apt-get update
RUN apt-get install python
RUN pip install flask
RUN pip install flask-mysql
COPY . /opt/source-code
ENTRYPOINT FLASK_APP=/opt/source-code/app.py flask run

Una vez hecho, hay que construir la imagen usando el comando “docker build” y especificar el archivo docker como entrada, así como un nombre de etiqueta para la imagen: “docker build Dockerfile -t <Imagen>”

Esto creará una imagen local. Para que esté disponible en el registro público de Docker Hub, hay que ejecutar el comando “docker push <imagen>” y especificar el nombre de la imagen que acaba de crear. 

Estructura del archivo Dockerfile

El archivo Docker es un archivo de texto escrito en un formato específico que Docker puede entender. Está en formato de instrucciones y argumentos. Todo a la izquierda en MAYÚSCULAS es una instrucción. Cada uno de estos le indica a Docker que realice una acción específica mientras crea la imagen. Todo a la derecha es un argumento para esas instrucciones. La primera línea define en qué sistema operativo base se debe enfocar el contenedor. Cada imagen de Docker debe basarse en otra imagen. Un sistema operativo u otra imagen que se creó antes basada en un sistema operativo. 

Es importante tener en cuenta que todos los archivos Docker deben comenzar con una instrucción FROM, la instrucción de ejecución le indica a Docker que ejecute un comando particular en esas imágenes base. Entonces, en este punto, Docker ejecuta los comandos de actualización de apt-get para obtener los paquetes actualizados e instala las dependencias requeridas en la imagen, luego la instrucción de copia copia los archivos del sistema local en la imagen de Docker. En este caso, el código fuente de nuestra aplicación está en la carpeta actual y lo copiaré en la ubicación /opt/source-code dentro de la imagen de Docker. Y finalmente, el punto de entrada nos permite especificar un comando que se ejecutará cuando la imagen se ejecute como un contenedor. 

Cuando Docker construye las imágenes, las construye en una arquitectura en capas. Cada línea de instrucción crea una nueva capa en la imagen con solo los cambios de la capa anterior. Como cada capa solo almacena los cambios de la capa anterior, también se refleja en el tamaño. 

Tamaño de las imágenes creadas

Si nos fijamos en la imagen base de Ubuntu, tiene un tamaño de alrededor de 120mb. Los paquetes apt que instalo son alrededor de 300mb y las capas restantes son pequeñas. Puede ver esta información si ejecuta el comando “docker history <imagen>” seguido del nombre de la imagen. Cuando ejecuta el comando “docker build” se pueden ver los diversos pasos involucrados y el resultado de cada tarea. Todas las compilaciones de capas se almacenan en caché, por lo que la arquitectura en capas lo ayuda a reiniciar la compilación de Docker desde ese paso en particular en caso de que falle o si agrega nuevos pasos en el proceso de compilación, no tendría que comenzar de nuevo.

Docker almacena en caché todas las capas construidas, por lo que, en caso de que falle un paso en particular, puede solucionar el problema y volver a ejecutar “docker build”. Se reutilizarán las capas anteriores de la memoria caché y continuará para construir las capas restantes. Lo mismo es cierto si tuviera que agregar pasos adicionales en el archivo acoplable. De esta manera, reconstruir su imagen es más rápido y no tiene que esperar a que un acoplador reconstruya la imagen completa cada vez. Esto es útil especialmente cuando actualiza el código fuente de su aplicación, ya que puede cambiar con más frecuencia solo las capas por encima de las capas actualizadas que deben reconstruirse.

Acabamos de ver una serie de productos en contenedores, como herramientas de  desarrollo de bases de datos, sistemas operativos, etc. Pero eso no es todo. La creación de imágenes para Docker puede contener casi todas las aplicaciones en contenedores, incluso las más simples, como navegadores o utilidades como aplicaciones curl como Spotify Skype, etc.