Objetivos de aprendizaje
Después de leer este artículo podrás:
- Entender qué resuelve Docker Compose y cómo funciona
- Leer y escribir un compose.yaml con una app y una base de datos
- Saber cuándo basta Compose y cuándo necesitas otra herramienta
Casi toda aplicación real tiene más de una pieza: un servidor web, una base de datos, quizá una caché o una cola. Levantar cada una con un docker run largo, recordando puertos, redes y volúmenes, se convierte en una lista de comandos que nadie repite sin equivocarse. Docker Compose existe para cambiar esa lista por un archivo.
Describes lo que necesita la aplicación en YAML, versionas el archivo junto con el código y cualquier persona del equipo levanta el mismo entorno con un comando.
¿Qué hace Docker Compose en la práctica?#
Compose lee un archivo que declara los componentes de la aplicación y crea todo lo necesario para que funcionen juntos. Según la documentación oficial, el archivo tiene estos elementos de nivel superior:
- services: los componentes de la aplicación. Cada servicio ejecuta uno o más contenedores creados a partir de la misma imagen y configuración.
- networks: las redes que permiten que los servicios se comuniquen entre sí.
- volumes: almacenamiento persistente, que sobrevive a la eliminación del contenedor.
- configs y secrets: configuración y datos sensibles montados en los contenedores como archivos.
- name: el nombre del proyecto, que agrupa los recursos y aísla deploys distintos.
No necesitas usarlos todos. La mayoría de los archivos solo tiene services y volumes.
¿Cómo es un archivo compose.yaml?#
El ejemplo de abajo levanta una aplicación Node.js que habla con un PostgreSQL. El código de la aplicación está en la carpeta actual, con un Dockerfile.
services:
web:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://app:${DB_PASSWORD}@db:5432/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:18
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: app
volumes:
- db-data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
retries: 5
start_period: 30s
timeout: 10s
volumes:
db-data:Cómo leer este archivo:
build: .construye la imagen a partir delDockerfilede la carpeta.image: postgres:18usa una imagen ya hecha.ports: "3000:3000"publica el puerto 3000 del contenedor en el puerto 3000 de tu máquina.- Dentro de la red que crea Compose, un servicio llega a otro por su nombre. Por eso la URL usa
dbcomo host, nolocalhost. ${DB_PASSWORD}se lee del entorno o de un archivo.enven la misma carpeta, para que la contraseña no quede escrita en el YAML. Consulta qué es un archivo .env.- El volumen
db-dataconserva los datos de la base aunque el contenedor se vuelva a crear. $$en elhealthcheckescapa el signo de dólar, para que la variable se resuelva dentro del contenedor y no en Compose.
El archivo no necesita el campo version: al principio. Está obsoleto: es solo informativo y genera una advertencia si lo usas.
¿Qué comandos usas en el día a día?#
Con el archivo en la carpeta del proyecto, el ciclo básico es este:
docker compose up -d # crea redes y volúmenes y levanta los servicios en segundo plano
docker compose ps # muestra el estado de cada servicio
docker compose logs -f web # sigue los logs del servicio web
docker compose down # detiene y elimina los contenedores y la reddown conserva los volúmenes. Para borrar también los datos, usa docker compose down -v, con cuidado. El comando es docker compose (con espacio), un subcomando de Docker. La forma antigua docker-compose (con guion) todavía aparece en tutoriales viejos, y los nombres de archivo docker-compose.yml siguen aceptándose.
Si cambias el código y quieres reconstruir la imagen, ejecuta docker compose up -d --build. Como Compose guarda la configuración de cada contenedor, los servicios que no cambiaron se reutilizan.
¿depends_on espera a que la base de datos esté lista?#
Por defecto, no. depends_on solo garantiza el orden: Compose espera a que el contenedor de la base de datos esté en ejecución, no a que esté listo para aceptar conexiones. Un PostgreSQL puede tardar unos segundos en arrancar, y la aplicación que se levanta antes suele fallar con un error de conexión.
La solución es declarar un healthcheck en la base de datos y usar condition: service_healthy en depends_on, como en el ejemplo de arriba. Así Compose retiene el servicio web hasta que pase la prueba de la base de datos. Aun así, una buena aplicación intenta reconectarse sola, porque la base de datos puede caerse más tarde.
¿Para qué sirve Docker Compose?#
La documentación oficial destaca tres usos:
- Entorno de desarrollo: la base de datos, la caché, la cola y las APIs de las que depende el proyecto se levantan con un comando, iguales para todo el equipo.
- Pruebas automatizadas: el pipeline de CI crea un entorno aislado, ejecuta la suite y lo destruye todo al final.
- Deploy en un solo servidor: Compose puede desplegar en un host o en un host Docker remoto, con ajustes propios de producción.
Para diferenciar entornos, puedes combinar varios archivos (por ejemplo, uno base y otro de producción) o usar variables, que permiten que una misma configuración sirva para personas y entornos distintos.
¿Cuándo no basta Compose?#
Compose trabaja con un solo host. No reparte contenedores entre varios servidores, no mueve una carga a otra máquina si el servidor cae y no ajusta el número de réplicas según la demanda. Si necesitas eso, el camino es un orquestador de clúster, como Kubernetes, que también es bastante más complejo de operar.
Compose describe contenedores, no la seguridad del servidor. Puertos publicados, contraseñas en texto plano en el YAML e imágenes sin versión fija (latest) son problemas habituales. Fija la versión de las imágenes, mantén los secretos fuera del repositorio y publica solo los puertos que deban ser accesibles desde fuera.
¿Qué términos se suelen confundir con Compose?#
- Dockerfile: la receta para construir una imagen. Compose la usa en
build, pero no la reemplaza. Para escribir una, consulta cómo dockerizar una aplicación. - Docker: el motor que ejecuta los contenedores. Consulta qué es Docker.
- Imagen y contenedor: la imagen es la plantilla inmutable, el contenedor es una instancia de ella en ejecución.
- Kubernetes y Swarm: orquestadores de clúster, para varios hosts.
Preguntas frecuentes
¿Docker Compose es lo mismo que Docker?
No. Docker ejecuta contenedores individuales. Compose es una capa sobre Docker que describe varios contenedores, redes y volúmenes en un archivo y los administra juntos.
¿Cómo se llama el archivo de Docker Compose?
El nombre preferido es compose.yaml (o compose.yml). Por compatibilidad, docker-compose.yaml y docker-compose.yml también funcionan. Si existen los dos estilos, Compose usa compose.yaml.
¿Necesito el campo version en compose.yaml?
No. El campo version de nivel superior está obsoleto, es solo informativo y genera una advertencia si lo usas. Compose valida el archivo con el esquema más reciente.
¿Puedo usar Docker Compose en producción?
Sí, en un solo servidor. La documentación oficial contempla desplegar en un host único o en un host Docker remoto. Para varios servidores, los equipos suelen recurrir a otro orquestador.
Más en Deploy
Ver los 33 artículos- Qué son las variables de entornoLas variables de entorno son pares clave-valor que el sistema operativo entrega a un proceso al iniciar. Aprende a leerlas en Node.js y Python sin exponer tokens.
- Qué es un deploy o despliegueUn deploy o despliegue lleva una versión de tu código a un servidor, la prepara y la pone en marcha. Conoce las etapas, los métodos y cómo hacer rollback.
- ¿Cuánta RAM y CPU necesita mi aplicación?Dimensiona RAM y CPU midiendo el pico real de la aplicación y sumando un margen del 30%. Mira cómo medir en Node.js, Python y Java y qué hacer cuando falte.
- Deploy automático con GitHub ActionsEl deploy automático con GitHub Actions envía tu código al servidor en cada push. Mira el workflow paso a paso, los secrets, las pruebas y los errores comunes.