Docker Compose es una herramienta que permite definir y gestionar contenedores. Es muy utilizado en aplicaciones multicontenedor.
Docker Compose utiliza un archivo YAML que define los servicios que componen la aplicación, sus redes, volúmenes, y otras configuraciones de manera sencilla y eficiente. Y luego con un solo comando podremos iniciar todos los servicios.
Docker Compose se compone por servicios que no son mas que contenedores. En las versiones recientes de Docker, se incluye Compose V2.
Docker Compose se basa en la definición de los contenedores en un archivo YAML (compose.yaml). Este archivo describe cada servicio necesario, las imágenes que se usarán, las redes para la comunicación interna, los volúmenes para la persistencia de datos, y otras configuraciones específicas.
Componentes clave de Docker compose:
El fomato YAML usa la sangría o identación para su estructura, por eso es importante que seamos consistentes con dicha identación. Es decir, si usamos espacios o tabulación.
En Docker compose, el archivo compose puede tener alguno de los siguientes nombres.
Nombres estándares de compose
compose.yaml/ymldocker-compose.yaml/ymlSi el archivo compose tiene otro nombre, hay que indicarselo a la CLI con --file
service: Especifica el nombre del servicio, un servicio es un contenedor. Para cada servicio, podemos especificar, entre otras configuraciones:image: Especifica qué imagen Docker se va a utilizar para crear el contenedor. Puede ser una imagen local o descargada de Docker Hub.ports: Mapea puertos del contenedor a puertos del host, permitiendo el acceso externo al contenedor desde el sistema anfitrión.
P_HOST:P_CONTAINERexpose: Indica los puertos abiertos dentro del contenedor sin hacerlos accesibles fuera del host. Serán accesibles desde la misma red interna.environment: Permite pasar variables de entorno al contenedor.restart Define la política de reinicio del contenedor en caso de fallo o salida. Puede tener valores como:no: No reiniciaralways: Reinicia siempreon-failure: reiniciar si solo fallaunless-stopped: Reiniciar a menos que el contenedor sea detenido manualmente.La CLI de Docker nos ayuda a interactuar con compose mediante el comando docker compose.
Comandos básicos:
docker compose up: Inicia todos los servicios definidos en el archivo compose.docker compose down: Detiene y elimina los servicios que están corriendo según el archivo compose.docker compose logs: Nos muestra los ouputs de los contenedores. Útil para hacer debug.docker compose ps: Lista los servicios junto a su estado actual.Unas de las mejores caracteristicas de docker y compose, es que se pueden deployar aplicaciones rápidamente. Empezaremos por un servidor web Nginx. Copiamos el siguiente texto a un archivo llamado compose.yaml en una carpeta nueva.
services:
web:
image: nginx:alpine-slim
ports:
- "80:80"
Luego ejecutamos en la misma carpeta:
docker compose up
Abrimos http://localhost y analizamos. Salimos con Control+C.
Por defecto, Compose crea una nueva red tipo bridge derivada de su project name. Si no se especifica, el project-name se deriva de la carpeta que contiene el archivo compose.
Vamos a modificar el compose para que no solo muestre la página de bienvenida de Nginx, sino para que sirva una web propia. Creamos una carpeta nueva llamada web.
Luego, descargamos el siguiente archivo funny-eyes. Descomprimimos el ZIP y renombramos la carpeta funny-eyes-master a html.
web/
├─ html/
│ ├─ js/
│ ├─ css/
│ ├─ index.html
├─ compose.yaml
Una vez que tengamos la estructura de directorios indicados, creamos un archivo compose.yaml con el siguiente contenido:
services:
web:
image: nginx:alpine-slim
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html:ro # bind mount (read only)
Luego ejecutamos:
docker compose up -d
El -d adicional indica que se ejecutará como "daemon".
Cuando ejecutamos el compose en modo daemon (-d) para detener podemos hacer lo siguiente:
docker compose stop # Detiene los contenedores
docker compose down # Detiene y elimina contenedores y redes
docker stop [CONTAINER_ID | NAME] # Usando docker CLI (sin compose)
Es importante remarcar que el ámbito del compose es por directorio/carpeta.
Es decir, si ejecutamos un docker compose stop para detener contenedores que levantamos pero estamos ubicados en otra carpeta, la CLI buscará un archivo compose dentro del directorio actual. Si no lo encuentra dará un mensaje no configuration file provided: not found
Por lo tanto, podremos tener tantos composes como queramos pero siempre respetando por carpetas o bien, podemos en la misma carpeta tener varios composes, pero tendremos que hacer explícito (con -f o --file) a qué archivo nos estamos refiriendo.
docker compose --file otro-compose.yml up -d
Gestionar diversos conenedores utilizando la Docker CLI requiere de varios pasos que tienen que ejecutarse uno tras otro y es propenso a errores.
Una de las cualidades de Docker Compose es la fácil gestión de aplicaciones multi-contenedor. Muchas veces las aplicaciones se componen de varios contenedores. Naturalmente, esos contenedores deberán poder comunicarse entre sí.
Ejemplo básico de un archivo compose.yaml multicontainer. Simplemente declaramos otro servicio.
version: '3' # Obsoleta en Compose V2
services:
web: # Nombre del servicio
image: nginx:latest
ports: # Publish ports
- "80:80"
database: # Nombre del servicio
image: mysql:5.7
environment: # Variables de entorno
MYSQL_ROOT_PASSWORD: example
En este ejemplo, se definen dos servicios: web, que usa la imagen de Nginx, y database, que utiliza MySQL. Con el comando docker compose up se iniciarán automáticamente ambos contenedores.
Vamos a comprobar que es muy sencillo tener aplicaciones mas complejas deployadas en segundos. En este ejemplo levantaremos un Wordpress.
WordPress es un sistema de gestión de contenido (CMS) de código abierto que permite crear y administrar sitios web y blogs de manera fácil, sin necesidad de saber programar. Es altamente personalizable mediante temas y plugins, lo que lo hace ideal para sitios web de todo tipo, desde blogs personales hasta tiendas en línea.
Para eso descargaremos el compose-wp.yaml
Luego nos ubicamos en una carpeta nueva y ejecutamos:
docker compose --file compose-wp.yaml up -d
Abriremos http://localhost
Analicemos el archivo compose.
Docker Compose NO reemplaza Dockerfile. Ya que tienen propósitos diferentes: Mientras que Dockerfile nos ayuda a personalizar nuestras imágenes, Compose es una herramienta para definir la relación entre cada servicio (contenedores) del arhivo Compose.
Para indicar que nuestra imágen se construye a partir de un Dockerfile, la instrucción image se reemplaza por build.
Funciones de build:
services:
app:
build:
context: ./app
dockerfile: Dockerfile.custom
ports:
- "8080:8080"
Para buildear imágenes de Dockerfile ha sido explicado mas en detalle en otra clase. Sin embargo en Docker Compose tenemos dos opciones:
docker buildPara la segunda opción simplemente basta con agregar un parámetro mas a docker compose
docker compose --build # Solo buildea las imágenes
docker compose up -d --build # Buildea y ejecuta los servicios