En el tema anterior vimos lo básico para trabajar con Docker. En este tema, veremos aspectos más avanzados como la creación de imágenes, la gestión de las redes en Docker y una forma más sencilla de crear varios contenedores conectados entre sí.
Hay veces que nos interesa crear imágenes si ninguna de las hay cumple todos nuestros requisitos. Este proceso se divide en dos partes:
Para gestionar la configuración de una imagen de Docker, necesitamos crear un archivo especial llamado Dockerfile.
Un Dockerfile es un archivo de texto que contiene un conjunto de instrucciones para construir una imagen de Docker de manera automática. Cada instrucción en un Dockerfile ejecuta un comando en el sistema operativo base, y su resultado forma parte de la imagen final. Esto permite definir, de forma declarativa, todos los pasos necesarios para que un contenedor se configure y ejecute de la manera deseada, incluyendo la instalación de paquetes, la copia de archivos, la exposición de puertos y la definición del comando de inicio.
Un Dockerfile generalmente sigue la siguiente estructura:
1. FROM 2. LABEL 3. RUN 4. COPY / ADD 5. WORKDIR 6. ENV 7. EXPOSE 8. CMD / ENTRYPOINT
FROM ubuntu:20.04
LABEL maintainer="tu_nombre@example.com" version="1.0"
RUN apt-get update && apt-get install -y nginx
COPY . /app
WORKDIR /app
ENV NODE_ENV=production
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
Así, un ejemplo completo de un Dockerfile podría ser:
# Usamos una imagen base de Ubuntu FROM ubuntu:20.04 # Instalamos paquetes necesarios RUN apt-get update && apt-get install -y \ curl \ vim # Establecemos el directorio de trabajo WORKDIR /app # Copiamos los archivos de nuestra aplicación al contenedor COPY . . # Exponemos el puerto que usará la aplicación EXPOSE 8080 # Definimos el comando que se ejecutará al iniciar el contenedor CMD ["bash"]
Una vez que tenemos el Dockerfile con la configuración deseada, el siguiente paso es construir la imagen a partir de ese archivo. Para ello, se utiliza el comando docker build. Este comando procesa el Dockerfile y genera una imagen que luego puede ser utilizada para crear contenedores.
La sintaxis básica del comando es la siguiente:
docker build -t nombre_imagen:tag ruta_dockerfile
Donde:
Por ejemplo, si estamos en el mismo directorio donde tenemos nuestro Dockerfile, podríamos crear una imagen de la siguiente forma:
docker build -t mi_aplicacion:1.0 .
Docker incluye un sistema de redes que permite a los contenedores comunicarse entre sí y con el mundo exterior. Las principales ordenes para trabajar con redes de Docker son:
Comando | Descripción |
---|---|
docker network create | Crea una red |
docker network rm | Elimina una red |
docker network ls | Lista las redes existentes |
docker network connect | Conecta un contenedor a una red |
docker network disconnect | Desconecta un contenedor de una red |
docker network inspect | Muestra los detalles de una red |
Por defecto, Docker crea varias redes cuando se instala, y los contenedores nuevos se conectan automáticamente a una de estas redes según sea necesario.
Además, podmos crear nuestras propias redes para organizar los contenedores según las necesidades de nuestra aplicación. Esto se realiza con el comando docker network create:
docker network create mi_red
Esto crea una nueva red llamada mi_red, que será una red de tipo bridge por defecto. Los contenedores conectados a esta red pueden comunicarse entre ellos por nombre, usando el nombre del contenedor como si fuera un hostname.
Si queremos cambiar el tipo de red, podemos usar el parámetro –driver indicando el tipo de red:
docker network create --driver tipo_red mi_red
Los tipos de redes más comunes son:
Una vez que has creado una red, puedes añadir contenedores a esta red, tanto en el momento de su creación como después.
Para añadir un contenedor a una red en el momento de su creación utilizamos la opción –network con el comando docker run:
docker run -d --name mi_contenedor --network mi_red nginx
Este comando crea un contenedor llamado mi_contenedor basado en la imagen nginx y lo conecta a la red mi_red.
Para añadir un contenedor existente a una red usamos el comando docker network connect:
docker network connect mi_red mi_contenedor
Esto conecta el contenedor mi_contenedor a la red mi_red.
Para eliminar un contenedor de una red utiliza el comando docker network disconnect:
docker network disconnect mi_red mi_contenedor
Esto desconecta el contenedor mi_contenedor de la red mi_red.
Para eliminar una red, usamos el comando docker rm:
docker rm mi_contenedor
Para eliminar una red, primero debes desconectar todos los contenedores asociados a esa red o detener y eliminar los contenedores. También se puede utilizar el parámetro -f para forzar la eliminación de la red, desconectando automáticamente todos los contenedores que estén asociados a ella.
Para obtener información detallada sobre una red, como los contenedores conectados a ella, puedes utilizar el comando docker network inspect:
docker network inspect mi_red
Este comando muestra detalles como la configuración de la red, los contenedores que la utilizan, sus direcciones IP dentro de la red, y más:
[ { "Name": "kea_dhcp-net", "Id": "6cdc6ee7b4bc543dfb877d587579285dcc57bedc6289460b4f9bbb6b5b510956", "Created": "2024-07-24T11:46:09.349440923+02:00", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "172.18.2.0/24", "Gateway": "172.18.2.1" } ] }, "Internal": false, "Attachable": true, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "806bb109a752a2dcfd7f81fc531e516728a1f002a2c6e3890e25a6fbca7c56c3": { "Name": "dhcp-mysql", "EndpointID": "e2e2ceaccc99b91a84466808297e23fbeaac1c9d20134e34161d544fef9af03a", "MacAddress": "02:42:ac:12:02:03", "IPv4Address": "172.18.2.3/24", "IPv6Address": "" }, "80f038e5572004df1d566ec650be56a342f0e8e9e094f2b0d84d36c384981327": { "Name": "dhcp-kea-server", "EndpointID": "2fc6bbf08db6b5d29b8ffc9e4a788926ec54e255f661de7b026037cdb7df75d4", "MacAddress": "02:42:ac:12:02:02", "IPv4Address": "172.18.2.2/24", "IPv6Address": "" } }, "Options": {}, "Labels": { "com.docker.compose.network": "dhcp-net", "com.docker.compose.project": "kea", "com.docker.compose.version": "1.25.0" } } ]
Docker Compose es una herramienta que permite definir y gestionar aplicaciones multicontenedor en Docker. Utiliza archivos de configuración en formato YAML para describir los servicios, redes y volúmenes que conforman una aplicación. Con un solo comando, puedes crear y arrancar todos los servicios definidos en el archivo, facilitando la orquestación de aplicaciones complejas.
Para instalarlo, basta seguir las instrucciones de su página oficial
Un archivo docker-compose.yml define la configuración de una aplicación multicontenedor. Aquí se presentan las secciones principales:
name: myapp services: web: image: nginx:alpine ports: - "8080:80" volumes: - ./html:/usr/share/nginx/html networks: - mi_red db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: ejemplo MYSQL_DATABASE: mi_basededatos volumes: - db_data:/var/lib/mysql networks: - mi_red networks: mi_red: volumes: db_data:
Comando | Descripción |
---|---|
docker compose up | Inicia los servicios definidos en el archivo docker-compose.yml. Si los contenedores no existen, los crea; si ya existen, los inicia. Si se agrega el parámetro -d ejecutará los servicios en segundo plano (detached mode) |
docker compose down | Detiene y elimina los contenedores, redes y volúmenes (si se utiliza el párametro -v) creados por docker-compose up |
docker compose start | Inicia los contenedores que ya han sido creados por docker-compose up, pero que están detenidos. A diferencia de up, no crea nuevos contenedores |
docker compose stop | Detiene los contenedores en ejecución, pero no los elimina. Los contenedores pueden reiniciarse con docker-compose start |
docker compose ps | Muestra el estado actual de los contenedores gestionados por Docker Compose, indicando si están en ejecución, detenidos, etc. |
Ejercicio 1
<html> <body> <h2>Hello World!</h2> </body> </html>
Ejercicio 2
PMA_ARBITRARY=1 UPLOAD_LIMIT=64
Ejercicio 3