Guía rápida de Docker Compose - Comandos más útiles con ejemplos
Por cierto, docker-compose es diferente de docker compose...
Aquí tienes un cheatsheet de Docker Compose con ejemplos anotados para ayudarte a dominar los archivos y comandos de Compose rápidamente.
Referencia del archivo Compose: docker-compose.yml
Estructura básica:
version: '3' # Versión del formato del archivo de Compose
services:
web:
image: nginx:latest
ports:
- "8080:80" # Puerto del host 8080: Puerto del contenedor 80
db:
image: postgres
environment: # Variables de entorno
POSTGRES_PASSWORD: example
volumes:
- db_data:/var/lib/postgresql/data
networks: # Red personalizada
appnet:
driver: bridge
volumes: # Volumen con nombre
db_data:
- services: Cada contenedor en tu aplicación de múltiples contenedores. En el ejemplo anterior tenemos dos servicios:
web
ydb
. - networks & volumes: Define redes aisladas y almacenamiento persistente - aquí tenemos la red
appnet
y el volumendb_data
.
Ejemplos
Servicio único con mapeo de puertos
services:
app:
build: .
ports:
- "8000:80" # Puerto del host 8000: Puerto del contenedor 80
Expone la aplicación en el puerto 8000 del host y construye desde el Dockerfile en el directorio actual.
Multi-servicio con volumen compartido y red personalizada
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- type: bind
source: ./app
target: /app
networks:
- mynet
db:
image: postgres
volumes:
- db_data:/var/lib/postgresql/data
networks:
- mynet
networks:
mynet:
volumes:
db_data:
Web y DB en la misma red; DB utiliza un volumen con nombre persistente - db_data
.
Usando contexto de construcción y ruta del Dockerfile
Puedes construir una imagen de Docker según demanda desde el Dockerfile especificado en docker-compose.yml.
services:
app:
build:
context: .
dockerfile: docker/MyDockerfile
Compartir datos entre servicios
services:
web:
image: nginx
volumes:
- shared_data:/usr/share/nginx/html
worker:
image: myworker
volumes:
- shared_data:/usr/src/app/data
volumes:
shared_data:
Ambos servicios acceden al mismo volumen (para archivos estáticos o intercambio de datos) - shared_data
.
Opciones avanzadas del archivo Compose
- environment: Establece variables de entorno para los contenedores.
- depends_on: Controla el orden de inicio de los servicios.
- deploy.replicas: Escala el servicio en modo Swarm.
Ejemplo:
services:
web:
image: nginx
deploy:
replicas: 3
depends_on:
- db
Inicia 3 instancias de web; solo controla el orden de inicio (no la disponibilidad).
Comandos esenciales de Docker Compose
Comando | Descripción | Uso de ejemplo |
---|---|---|
docker-compose up |
Crea y inicia contenedores | docker-compose up |
docker-compose up -d |
Ejecutar en segundo plano | docker-compose up -d |
docker-compose exec |
Ejecutar un comando en un contenedor en ejecución | docker-compose exec web bash |
docker-compose build |
Construir/reconstruir imágenes | docker-compose build |
docker-compose down |
Detener y eliminar contenedores, redes, volúmenes e imágenes | docker-compose down |
docker-compose logs -f |
Ver y seguir los registros | docker-compose logs -f |
docker-compose ps |
Listar contenedores en ejecución | docker-compose ps |
docker-compose run |
Ejecutar comandos de una sola vez (ignora el comando en el archivo Compose) | docker-compose run web python manage.py migrate |
docker-compose stop |
Detener contenedores en ejecución (se pueden reiniciar con start ) |
docker-compose stop |
docker-compose restart |
Reiniciar servicios | docker-compose restart web |
docker-compose pull |
Descargar imágenes de servicio | docker-compose pull |
docker-compose rm |
Eliminar contenedores detenidos de servicios | docker-compose rm web |
docker-compose config |
Validar y ver el archivo Compose | docker-compose config |
docker-compose up --scale web=3 |
Iniciar múltiples instancias de un servicio | docker-compose up --scale web=3 |
Patrones comunes de Compose
-
Bases de datos con datos persistentes
services: mysql: image: mysql environment: MYSQL_ROOT_PASSWORD: password volumes: - mysql_data:/var/lib/mysql volumes: mysql_data:
Los datos de la base de datos persisten en el volumen
mysql_data
incluso tras reiniciar los contenedores. -
Montaje de código para desarrollo
services: app: build: . volumes: - .:/app
Editar código en el host en vivo, reflejado automáticamente en el contenedor.
Banderas útiles
-d
: Modo de detención (ejecutar en segundo plano).--build
: Forzar la reconstrucción de imágenes antes de iniciar.--force-recreate
: Reconstruir contenedores incluso si no han cambiado.--remove-orphans
: Eliminar contenedores no definidos en el archivo Compose.
Definir y personalizar servicios
Puedes definir y personalizar servicios, redes y volúmenes en Docker Compose aprovechando el archivo docker-compose.yml
, que centraliza todas las necesidades de configuración y orquestación de tu aplicación.
- Servicios se definen bajo la clave
services
. - Cada servicio representa una configuración de contenedor, donde puedes establecer:
- Image: Seleccionar una imagen de Docker Hub u otro registro.
- Ports: Mapear puertos del contenedor a puertos del host.
- Variables de entorno: Pasar valores de configuración.
- Volúmenes: Persistir datos o compartir archivos/carpetas con el host u otros servicios.
- Redes: Controlar qué redes puede acceder el servicio.
Ejemplo:
services:
web:
image: nginx:latest
ports:
- "8080:80" # Puerto del host 8080: Puerto del contenedor 80
environment:
- NGINX_HOST=localhost
volumes:
- web_data:/usr/share/nginx/html
networks:
- frontend
db:
image: postgres:13
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
volumes:
- db_data:/var/lib/postgresql/data
networks:
- backend
- Aquí, el servicio
web
utiliza la imagen nginx, establece una variable de entorno, adjunta un volumen, abre el puerto 80 como 8080 en el host y se conecta a la redfrontend
. El serviciodb
hace algo similar para PostgreSQL.
Personalizar redes
- Redes controlan qué servicios pueden comunicarse. Compose crea una red por defecto, pero puedes definir más, especificar controladores personalizados, establecer opciones y determinar qué servicio se une a qué red para un aislamiento fino.
- Define redes en el nivel superior bajo
networks
, y lista qué redes debe adjuntar un servicio con la clavenetworks
a nivel de servicio.
Ejemplo:
networks:
frontend:
driver: bridge
backend:
driver: bridge
driver_opts:
com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
- Adjunta redes a servicios:
services:
app:
networks:
- frontend
- backend
db:
networks:
- backend
- Esta configuración permite que el servicio
app
acceda a usuarios en las redesfrontend
ybackend
, mientras quedb
solo es accesible dentro de labackend
.
Personalizar volúmenes
- Volúmenes se definen bajo la clave
volumes
en el nivel superior. Móntalos en contenedores usando la clavevolumes
bajo un servicio. - Los volúmenes pueden tener nombres, usar controladores personalizados y compartirse entre múltiples servicios para persistencia de datos y compartir datos.
Ejemplo:
volumes:
web_data: # Volumen con nombre para contenido web
db_data: # Volumen con nombre para base de datos
services:
web:
volumes:
- web_data:/usr/share/nginx/html
db:
volumes:
- db_data:/var/lib/postgresql/data
- En este ejemplo,
web_data
se persiste y está disponible para cualquier contenedor que lo monte.db_data
asegura que los datos de la base de datos nunca se pierdan al recrear el contenedor. - Puedes definir montajes de tipo bind con opciones de controlador personalizado para casos avanzados:
volumes:
db_data:
driver: local
driver_opts:
type: none
device: /data/db_data
o: bind
- Esta configuración establece un montaje de tipo bind desde la ruta del host
/data/db_data
dentro del contenedor.
Resumen de buenas prácticas:
- Usa el nombre del servicio como nombre de host DNS para la comunicación entre servicios.
- Adjunta servicios a múltiples redes según sea necesario para controlar el acceso.
- Usa volúmenes con nombre para almacenamiento persistente y compartir datos.
- Define todo usando YAML, lo que permite el control de versiones y scripts de despliegue fáciles.
Archivos Compose múltiples
Para organizar configuraciones complejas de múltiples servicios en Docker Compose, puedes usar archivos Compose múltiples y archivos de sobrescritura, permitiendo configuraciones modulares, específicas del entorno y escalables. Aquí te explico cómo funciona:
- Estructura de archivos base y de sobrescritura
- Crea un archivo base (
compose.yaml
odocker-compose.yml
) que contenga todas las definiciones de servicios comunes y por defecto. - Agrega archivos de sobrescritura específicos del entorno (por ejemplo,
docker-compose.override.yml
,docker-compose.dev.yml
,docker-compose.prod.yml
).
Ejemplo de estructura de archivos:
/proyecto
|-- docker-compose.yml # Configuración base
|-- docker-compose.override.yml # Sobrescrituras locales/dev (aplicadas automáticamente)
|-- docker-compose.prod.yml # Sobrescrituras de producción
|-- docker-compose.test.yml # Sobrescrituras de prueba (si es necesario)
La configuración base define servicios principales, mientras que cada sobrescritura personaliza ajustes para un entorno o caso específico.
- Cómo funcionan los archivos de sobrescritura
- Fusión: Cuando ejecutas
docker compose up
, Docker Compose fusiona el archivo base con cualquier archivo de sobrescritura en orden; los archivos posteriores sobrescriben, extienden o añaden ajustes a los archivos anteriores. - Sobrescritura de campos: Si un servicio o campo se define en múltiples archivos, el valor del último archivo especificado se usa. Los campos nuevos se añaden.
Ejemplo de fusión:
docker-compose.yml
:services: web: image: myapp ports: - "8000:80"
docker-compose.override.yml
:services: web: environment: - DEBUG=true
- Resultado: El servicio
web
usa tanto la imagen y el puerto base como la variable de entorno sobrescritaDEBUG
.
- Uso de comandos para múltiples archivos
- Comportamiento por defecto: Si está presente, Docker Compose carga automáticamente
docker-compose.override.yml
junto condocker-compose.yml
al ejecutar cualquier comando. - Especificar archivos manualmente: Usa banderas
-f
para controlar qué archivos se fusionan y en qué orden:docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
- Esto ignora el sobrescritura por defecto y usa ajustes específicos de producción.
- Estrategias prácticas de organización
- Separación por entorno: Usa un sobrescritura por entorno: dev, test, prod, etc.
- Microservicios y equipos: Separa la configuración en archivos distintos para diferentes servicios o equipos, y combínalos según sea necesario.
- Conmutadores de características: Archivos adicionales pueden introducir o eliminar servicios o configuraciones opcionales para necesidades temporales (por ejemplo, un
compose.debug.yml
para registro adicional).
- Ventajas
- Claridad: Mantiene archivos individuales pequeños y enfocados.
- Escalabilidad: Añade fácilmente nuevos servicios, entornos o ajustes.
- Mantenibilidad: Solo cambia o revisa las secciones relevantes para un despliegue específico.
- Ejemplo: Cambiar entornos
Desarrollo:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
Producción:
docker compose -f docker.docker-compose.yml -f docker-compose.prod.yml up -d
Cada entorno obtiene solo la configuración necesaria para él, con toda la configuración compartida en el archivo base.
Organizar configuraciones complejas de Compose con múltiples archivos - y aprovechar el sistema de sobrescritura/fusión - asegura modularidad, personalización específica del entorno y escalabilidad fácil para aplicaciones Docker con múltiples servicios.