
Una aplicación real raramente es un solo proceso. Necesitas la aplicación, una base de datos, quizás un caché, un proxy inverso. Levantarlos por separado con docker run, pasarles las variables correctas, conectarlos en la misma red… se convierte en algo tedioso de repetir. Docker Compose resuelve esto con un solo archivo de configuración y un solo comando.
Qué es Docker Compose
Docker Compose es una herramienta que permite definir y ejecutar aplicaciones multi-contenedor. Describes todos los servicios, redes y volúmenes en un archivo docker-compose.yml y los arrancas con docker compose up. Compose gestiona el ciclo de vida completo: crear, arrancar, parar y eliminar todos los recursos de la aplicación.
Estructura del docker-compose.yml

services:
web:
build: .
ports:
- "80:3000"
depends_on:
- db
environment:
DB_HOST: db
DB_PORT: 5432
restart: unless-stopped
db:
image: postgres:15
environment:
POSTGRES_DB: miapp
POSTGRES_PASSWORD: secreto
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
volumes:
pgdata:
Cada clave de services define un contenedor. Los servicios se comunican entre sí usando el nombre del servicio como hostname: el servicio web accede a la base de datos en db:5432, no en localhost. Compose crea automáticamente una red interna que conecta todos los servicios del mismo archivo.
depends_on indica que un servicio debe arrancar antes que otro. Ojo: solo espera a que el contenedor esté en pie, no a que el proceso dentro esté listo. Para esperar a que PostgreSQL esté listo para aceptar conexiones necesitas un healthcheck o un script de espera.
Volúmenes: datos que persisten
Sin volúmenes, cuando paras y eliminas un contenedor pierdes todos sus datos. Un volumen desacopla el almacenamiento del ciclo de vida del contenedor.
volumes:
pgdata: # volumen gestionado por Docker
# O un bind mount (carpeta del host)
volumes:
- ./data:/var/lib/postgresql/data # host:contenedor
Los volúmenes gestionados por Docker viven en /var/lib/docker/volumes/. Los bind mounts montan una carpeta del host directamente, lo que facilita el desarrollo porque los cambios en el código son visibles inmediatamente.
Variables de entorno y secretos
services:
api:
image: mi-api
env_file:
- .env # carga variables desde un archivo .env
environment:
NODE_ENV: production
DB_HOST: db # sobreescribe lo que haya en .env
Comandos del día a día

docker compose up -d # arranca en background
docker compose up --build # reconstruye imágenes y arranca
docker compose down # para y elimina contenedores y redes
docker compose down -v # también elimina volúmenes
docker compose logs -f api # logs en tiempo real del servicio api
docker compose exec db psql # abre psql dentro del contenedor db
docker compose ps # estado de todos los servicios
docker compose restart web # reinicia solo el servicio web
Cuando el proyecto crece y el número de réplicas, redes y configuraciones se multiplica, Compose empieza a quedarse corto. El siguiente escalón son los orquestadores como Kubernetes, pero para la gran mayoría de proyectos, Compose es todo lo que necesitas. Lo que sí conecta directamente con Compose es el CI/CD: automatizar la construcción, prueba y despliegue de estos contenedores cada vez que haces un push al repositorio.