Para construir una imagen podemos emplear un archivo llamado «Dockerfile». Antes de continuar me gustaría establecer las diferencias entre «Dockerfile» y «Docker compose»
- Dockerfile — > Lo empleamos para construir una imagen docker.
- Docker compose — > Archivo empleado para «lanzar» varios contenedores con unas características determinadas. Ademas, este Docker compose puede utilizar un Dockerfile (build).
Después de aclarar este concepto (que a veces no se explica adecuadamente) hablaremos de construir (build) una imagen.
Un “dockerfile” es un archivo de texto donde se establecen una serie de comandos (similares a pseudo Linux) que hace que el cliente docker (el docker que corre en nuestra máquina) los ejecute para crear una imagen. Obviamente las imágenes se basan en otras imágenes (como ya se ha explicado) como puede ser una imagen de Python, Ubuntu (como en nuestro ejemplo) o cualquier otra. Estas imágenes “base” tienen las funcionalidades necesarias para luego “añadirle” otras en nuestra imagen “customizada” gracias a «Dockerfile». El proceso desde el «Dockerfile» hasta la ejecución de un contenedor es el de la siguiente imagen.

Vamos a crear un “dockerfile” muy simple con base una maquina Ubuntu 16.04 a la que añadiremos algunas “especias” a nuestro gusto. El archivo quedaría así:
#Mi primer Dockerfile
FROM ubuntu:16.04
RUN apt-get update
RUN apt-get install -y apache2
RUN echo «Bienvenido Maxtor!» > /var/www/html/index.html
EXPOSE 80
La explicación del código es casi obvia, creamos una imagen de Ubuntu 16.04 al que le forzamos a actualizarse, que luego se instale el servidor apache (“-y” significa que a todas las preguntas responda con un «yes»), que en la página web de un mensaje de bienvenida (siempre recogida en index.html) y que estará disponible (por defecto) en el puerto 80 del futuro contenedor qe lancemos de esa imagen.
Así, para construir nuestra imagen (obviamente la maquina de Ubuntu se obtiene de Docker Hub) ejecutamos el siguiente comando docker build -t ubuntutest .
Hay que tener claro que “-t” se refiere a “tag” (para poner el nombre a la imagen) y que el “.” final es necesario para decirle que busque el “Dockerfile” para crear la imagen en el propio directorio donde estamos. En las siguientes imágenes vemos como se ha creado la imagen siguiendo los pasos descritos.



Ahora lanzaremos un contenedor de nuestra imagen creada con la instrucción docker run -d –rm -p 8080:80 ubuntutest /usr/sbin/apache2ctl -D FOREGROUND. En este caso hemos lanzado el contenedor forzando a que arranque el servidor apache en background, ya que un docker necesita ejecutar en primer plano el proceso principal “Ubuntu” y en background el resto, SINO NO FUNCIONARA!.
La siguientes imágenes muestran los pasos seguidos.


Finalmente, alguien podria preguntarse por qué no hemos establecido en el «Dockerfile» que cuando se cree la imagen se lance en «background» el servicio apache. Pues bien, esto si se puede realizar añadidenod al final de nuestro archivo «Dockerfile» CMD [«apachectl», «-D», «FOREGROUND»].
La instrucción «CMD» tiene la siguiente sintaxis CMD [«executable»,»param1″,»param2″]. EN nuestro caso que ejecute apache en modo «detached» y «foreground». No obstante a lo anterior, si en un Dockerfile establecemos (por ejemplo) CMD [«apachectl», «-D», «FOREGROUND»] tendremos las siguientes características:
- Para lanzar un contenedor de la imagen creada solo necesitaríamos la instrucción docker run -d –rm -p 8080:80 ubuntutest
- Siempre que lancemos un contenedor usando esa imagen tendremos el servidor apache ejecutándose en segundo plano en ese contenedor e igual NO nos interesa ese comportamiento y preferiríamos levantarlo explícitamente en la sentencia «run» (en el caso de que no queramos). Esto es algo a valorar a la hora de crear la imagen.
Deja una respuesta