Page cover

Dockerfiles

Vamos a probar Docker con un ejemplo con php y dockerfiles con mariaDB.

Un Dockerfile es un archivo de texto que contiene una serie de instrucciones para construir una imagen de Docker. Estas instrucciones describen cómo configurar un entorno desde cero (o a partir de una imagen base) para ejecutar una aplicación específica. Es la base para automatizar la creación de imágenes Docker.

Conceptos clave

  • Imagen de Docker: Una imagen es una plantilla que contiene todo lo necesario para ejecutar una aplicación: sistema operativo, dependencias, librerías, y la propia aplicación.

  • Contenedor de Docker: Es una instancia ejecutable de una imagen, funcionando de manera aislada.

El Dockerfile es donde defines cómo se crea la imagen, paso a paso.

Estructura de un dockerfile

Cómo funciona un Dockerfile

Cuando ejecutas un comando como docker build, Docker:

  1. Lee el Dockerfile línea por línea.

  2. Construye una imagen Docker siguiendo las instrucciones del archivo.

  3. Crea una capa en la imagen por cada instrucción del Dockerfile:

    • Estas capas se almacenan en caché para optimizar futuras construcciones.

    • Si el contenido de una capa no cambia, se reutiliza en lugar de reconstruirse.

Finalmente, obtienes una imagen que puedes usar para lanzar contenedores.


Estructura básica de un Dockerfile

Un Dockerfile tiene una serie de instrucciones clave que definen cómo construir la imagen. Aquí está un desglose de las más comunes:

1. Especificar una imagen base

La imagen base es el punto de partida para tu imagen. Por ejemplo:

FROM python:3.10-slim

Esto indica que usarás la imagen oficial de Python 3.10 en su versión minimalista como base.

2. Agregar metadatos (opcional)

Puedes agregar información sobre la imagen usando etiquetas como:

LABEL maintainer="tu_email@example.com"
LABEL version="1.0"
LABEL description="Esta imagen ejecuta una aplicación Flask."

3. Copiar archivos al contenedor

Para copiar archivos desde tu máquina al contenedor:

COPY app/ /app/

Esto copia el contenido de la carpeta app/ en tu máquina al directorio /app/ dentro de la imagen.

4. Ejecutar comandos durante la construcción

Puedes instalar dependencias, descargar archivos o configurar el sistema operativo usando RUN:

RUN apt-get update && apt-get install -y libpq-dev
RUN pip install flask mysql-connector-python

Cada comando crea una nueva capa en la imagen.

5. Configurar el directorio de trabajo

El comando WORKDIR establece el directorio en el que se ejecutarán los comandos posteriores:

WORKDIR /app

6. Definir variables de entorno

Puedes configurar variables de entorno dentro del contenedor:

ENV FLASK_ENV=development

7. Exponer puertos

Indica qué puertos estarán disponibles para conexiones externas:

EXPOSE 5000

8. Definir el comando de inicio

Usa CMD para definir el comando que se ejecutará cuando se inicie el contenedor:

CMD ["flask", "run", "--host=0.0.0.0"]

O usa ENTRYPOINT si quieres que ciertos comandos sean fijos, permitiendo añadir parámetros adicionales al ejecutar el contenedor:

dockerfileCopiar códigoENTRYPOINT ["python"]
CMD ["app.py"]

A continuación tienes todos los argumentos que puede admitir un dockerfile:

#1. Imagen de base
FROM <base_image>:<tag>
#Ejemplo: FROM Ubuntu:20.04

#2. Metadatos
LABEL <key>=<value> ...
#Ejemplo: LABEL mantenimiento="you@ejemplo.com"

# 3. Instalar dependencias
RUN <command> && <command>
# Ejemplo: RUN apt-get update && apt-get install -y curl

# 4. Establecer el directorio de trabajo
WORKDIR /path/to/workdir
# Ejemplo: WORKDIR /app

# 5. Copiar archivos al contenedor:
COPY <src> <dest>
# Ejemplo: COPY . /app
# OR
ADD <src> <dest>
# Ejemplo: ADD https://ejemplo.com/file.tar.gz /app/

# 6. Establecer las variables de entorno
ENV <key>=<value>
# Ejemplo: ENV NODE_ENV=produccion

# 7. Abrir puertos
EXPOSE <port>
# Ejemplo: EXPOSE 8080

# 8. Especificar comando por defecto:
CMD ["executable", "param1", "param2"]
# Ejemplo: CMD ["npm", "start"]
# OR
ENTRYPOINT ["executable", "param1", "param2"] 
#Ejemplo: ENTRYPOINT ["python", "app.py"]

# 9. Añadir volúmenes:
VOLUME ["/path/to/dir"]
# Ejemplo: VOLUME ["/data"]

# 10. Definir argumentos por defecto:
ARG <name>[=<default value>] 
# Ejemplo: ARG VERSION=1.0.0

# 11. Revisión del rendimiento del sistema
HEALTHCHECK [OPTIONS] CMD <command>
# Ejemplo: HEALTHCHECK --interval=30s --timeout=10s \
# CMD curl -f http://localhost/health || exit 1

# 12. Establecer usuario:
USER <username_or_uid>
# Ejemplo: USER node

#13. Stop Signal
STOPSIGNAL <signal>
# Ejemplo: STOPSIGNAL SIGTERM

# 14. Comando de la shell
RUN <command>
# Ejemplo: RUN echo "Hello World"

# 15. Ejecutar desde comando:
RUN ["executable", "param1", "param2"]
# Ejemplo: RUN ["python", "app.py"]

#16. Especificar el tipo de shell:
SHELL ["executable", "param1"]
#Ejemplo: SHELL ["/bin/bash", "-c"]

Ejemplo) Dockerfile con MariaDB

Para evitar que el comando que se escribe en el Para mitigar estos errores, se puede crear un archivo llamado Dockerfile con la configuración que queramos tener en el contenedor:

Vamos a revisar como funciona Dockerfile creando un contenedor de MySQL.

  1. Creamos el archivo dockerfile en una carpeta recién creada que queramos como la que hemos creado en la guía de volúmenes donde tenemos creado el volumen llamado "wordpress-db":

sudo nano Dockerfile

Dentro de este archivo escribiremos:

## MySQL 8
## Imagen base
FROM mariadb:latest
FROM mysql:latest

## Variables de entorno. Configuración inicial de MySQL 8
ENV MYSQL_ROOT_PASSWORD=1234
ENV MYSQL_DATABASE=wpalex
ENV MYSQL_USER=alex
ENV MYSQL_PASSWORD=P@ssw0rd
## Puerto donde se expondrá el Servidor de Bases de Datos
EXPOSE 3306
## Directorio del Contenedor que necesita persistencia
VOLUME /var/lib/docker/volumes/wordpress-db/_data

## MySQL 8 - Usando MySQL como base
FROM mysql:latest

## Variables de entorno - Configuración inicial de MySQL
ENV MYSQL_ROOT_PASSWORD=1234
ENV MYSQL_DATABASE=wpalex
ENV MYSQL_USER=alex
ENV MYSQL_PASSWORD=P@ssw0rd

## Puerto donde se expondrá el Servidor de Bases de Datos
EXPOSE 3306

## Directorio del Contenedor que necesita persistencia
VOLUME /var/lib/mysql

Donde:

  • FROM: Le indica la imagen que se va a usar en el contenedor, en este caso MySQL oficial en última versión

  • ENV: Hace referencia a variables de entorno del contenedor que se configurarán al iniciarse.

  • EXPOSE: Indica el puerto en el que será visible, en este caso el de por defecto de mysql. Este es importante para conectar luego las apps cliente.

  • VOLUME: Se crea una zona fuera del contenedor para almacenar el contenido de la ruta escrita. Esto se hace para almacenar los datos (de mysql en este caso) incluso si se borra o para el contenedor. Tienes la explicación de donde ha salido de la guía.

A continuación tienes algunos parámetros más comunes de un fichero dockerfile:

Parámetro
Ejemplo
Descripción

FROM

FROM mysql

Indica la imagen base desde la que se construye.

ENV

ENV HOME=/home/app

Añade una variable de entorno. Las variables de entorno las puedes encontrar en las páginas respectivas del Docker hub.

WORKDIR

WORKDIR /home/app

Indica el directorio de trabajo para los siguientes comandos.

COPY

COPY *.txt /doc/

Copia archivos desde el anfitrión al contenedor

VOLUME

VOLUME /myvol1

Crea un punto de montaje accesible por otros contenedores.

RUN

RUN npm install

Ejecuta un comando en el contenedor.

EXPOSE

EXPOSE 3000

Abre un puerto para ese contenedor.

ARG

ARG NAME

Indicamos el argumento que deseamos para nuestra imagen. Con esto le decimos: esperará un argumento personalizado al momento de crear la imagen.

  1. Ahora toca construir el contenedor en si según los parámetros definidos, para ello ejecutamos:

docker build -t alexdb:latest .

Al final del proceso obtendremos un codigo que será el ID de la imagen de docker o puedes listar las imágenes como hemos visto antes.

Al ejecutar la imagen en un contenedor se puede verificar la versión de MySQL y, como tenemos los datos de conexión, entrar a verificar las bases de datos creadas por defecto. Ejecute el comando sustituyendo [IMAGE ID] por el valor que tiene su imagen:

docker run -d [IMAGE ID] 

Esto lanzará el docker en segundo plano.

  1. Para hacer la conexión a la base de datos tendrá que ejecutar lo siguiente:

docker exec -it [CONTAINER ID] sh

Tras acceder al shell del contenedor, ya puedes hacer pequeñas comprobaciones:

mysql --version
mysql -u root -p

El segundo comando te permitirá acceder mediante el usuario root al CLI de mysql teniendo que poner la contraseña antes descrita. Si se realiza correctamente la conexión, se mostrará una información de bienvenida.

  1. Para comprobar las bases de datos que están creadas, incluida la configurada en el Dockerfile, se puedes escribir:

show databases;

Referencia:

Última actualización