Anteriormente vimos las diferentes formas de crear imágenes de Docker. En este post entraremos en detalle sobre las instrucciones que podemos utilizar en un Dockerfile.


Que es un Dockerfile

Un Dockerfile es simplemente un fichero de texto que nos permite definir las instrucciones a seguir por Docker para construir una imagen personalizada.

Cuando ejecutamos docker build desde el terminal, lo que estamos haciendo es construir una imagen de Docker ejecutando las instrucciones indicadas en el Dockerfile de forma secuencial.


Comandos de un Dockerfile

Un fichero Dockerfile está compuesto por una serie de instrucciones en mayúsculas que indican la tarea que tiene que ejecutar el comando constructor de la imagen.

Hay que tener en cuenta que Docker trata las líneas que comiencen con # como comentarios. Si el caracter # aparece en cualquier otra parte de la línea (intrucción), Docker lo tratará como un argumento.

Si quieres profundizar en las opciones y posibilidades de cada una de las instrucciones, puedes consultar el tutorial oficial sobre Dockerfile. A continuación, explico las que creo que son más interesantes:

1. FROM

Especifica la imagen base sobre la que vamos a partir.

2. MAINTAINER

Información sobre el creador de la imagen

3. ENV

Esta instrucción permite crear variables de entorno que serán interpretadas por Dockerfile. De esta forma podemos hacer cosas como:

# Dockerfile
FROM ubuntu:14.04
ENV root /carpeta_prueba
ADD $root

, y esto lo que hará es declarar una variable de entorno root cuyo valor será carpeta_prueba y la añadirá al sistema de ficheros del contenedor.

Las variables se pueden escribir como $nombre_var o como ${nombre_var}.

3. ADD

ADD <origen>... <destino>

Esta instrucción copia ficheros, directorios o ficheros remotos desde y los añade al sistema de ficheros del contenedor en el path .

El parámetro <origen> acepta caracteres comodín (tipo ?, *…) que se cumplirán (o no) en base a las reglas impuestas por filepath.Match.

En caso de que el origen sea un fichero comprimido, lo descomprime en el destino de la misma forma que lo haríamos con tar -x.

Hay unas cuantas reglas a tener en cuenta. Es muy recomendable echarles un ojo ya que explican las diferentes casuísticas que se pueden dar.

Un tema básico es que <origen> debe estar dentro del contexto de contrucción de la imagen, es decir, donde está el Dockerfile.

4. COPY

La instrucción COPY es parecida a ADD si trabajamos con carpetas y ficheros pero no permite trabajar con ficheros remotos, ni descomprimer ficheros comprimidos, etc… En definitiva, es una versión básica del ADD.

También permite caracteres comodín y estos son los aspectos que hay que tener en cuenta.

5. RUN

Permite ejecutar una instrucción en el contenedor, luego aplica/persiste los cambios en el contenedor y continua la siguiente instrucción del Dockerfile.

Resulta muy útil, por ejemplo, para instalar librerías como mysql, git, etc… en el contenedor mediante el gestor de paquetes apt-get.

6. CMD

La instrucción CMD es muy similar al comando RUN con la ligera diferencia que no se ejecuta cuando se corre el comando build sino cuando instanciamos o arrancamos el contenedor.

Sólo puede existir una única instrucción CDM por cada Dockerfile y puede ser útil para ejecutar servicios que ya esten instalados o para correr archivos ejecutables espeficicando su ubicacion.

7. WORKDIR

Permite especificarle a Docker en que directorio va a ejecutar una instrucción CMD, RUM o ENTRYPOINT, como por ejemplo:

WORKDIR /var/www
RUN pwd

, donde esto devolvería /var/www.

8. EXPOSE

Esta instrucción permite exponer puertos, permitiéndonos exponer un contenedor con el mundo exterior (internet, nuestro host, etc…).

Por ejemplo, podemos exponer los puertos 22 (para SSH), 80 (para HTTP), 3306 (MySQL), etc…

9. VOLUME

Esta instrucción permite establecer puntos de montaje para que cuando usemos el contenedor podamos tener acceso externo (desde nuestro host) a un determinado directorio del contenedor.

Por ejemplo, al indicar la instrucción VOLUME ["/var/www"] estaremos creando un punto de montaje en el directorio especificado permitiendo compartir dicho directorio con otros contenedores o con la máquina anfitrión.