Docker Compose para principiantes: tu primer proyecto
- docker
- docker-compose
- infraestructura
- contenedores
- principiantes
Qué problema resuelve Docker Compose
Si alguna vez has intentado instalar WordPress en un servidor, sabes que necesitas configurar un servidor web, PHP, una base de datos, crear usuarios, ajustar permisos y rezar para que todo funcione junto. Si algo falla, empiezas de cero. Y si quieres replicar esa instalación en otro servidor, repites todo el proceso manualmente.
Docker Compose resuelve esto. Defines en un solo archivo qué servicios necesitas (web, base de datos, proxy), cómo se conectan entre sí y con qué configuración. Un solo comando levanta todo. Otro comando lo para. Si quieres mover la instalación a otro servidor, copias el archivo y repites el mismo comando. Para entender por qué uso este enfoque en producción, lee por qué uso Docker y Traefik en todos mis proyectos.
Es la diferencia entre montar un mueble de IKEA con instrucciones (Docker Compose) y montarlo de memoria (instalación manual). El resultado es el mismo, pero uno es reproducible y el otro depende de que no se te olvide ningún paso.
Los conceptos básicos
Antes de tocar un archivo, necesitas entender tres ideas.
Contenedores
Un contenedor es una caja aislada que contiene una aplicación y todo lo que necesita para funcionar. Un contenedor de MySQL tiene MySQL y sus dependencias. Un contenedor de WordPress tiene WordPress, PHP y un servidor web. Cada contenedor es independiente y no interfiere con los demás.
Imágenes
Una imagen es la plantilla a partir de la cual se crean contenedores. Es como un molde: la imagen de WordPress es el molde, y cada contenedor que creas a partir de ella es una copia funcional. Las imágenes se descargan de Docker Hub, un repositorio público con miles de imágenes listas para usar.
Volúmenes
Los contenedores son efímeros por diseño. Si paras un contenedor y lo eliminas, sus datos desaparecen. Los volúmenes son el mecanismo para que los datos persistan fuera del contenedor. La base de datos de tu WordPress se guarda en un volumen, así que aunque destruyas el contenedor de MySQL, los datos siguen ahí.
Si quieres profundizar en las opciones de persistencia, tengo un artículo sobre volúmenes Docker vs bind mounts donde explico cuándo usar cada opción.
Anatomía de un docker-compose.yml
El archivo docker-compose.yml es donde describes tu infraestructura. Su estructura es sencilla:
version: "3.8"
services:
nombre-del-servicio:
image: imagen-a-usar
ports:
- "puerto-host:puerto-contenedor"
volumes:
- datos:/ruta/en/contenedor
environment:
- VARIABLE=valor
volumes:
datos:
Cada bloque bajo services es un contenedor. Defines qué imagen usa, qué puertos expone, dónde guarda los datos y qué variables de entorno necesita. La sección volumes al final declara los volúmenes nombrados que usan los servicios.
Ejemplo real: WordPress + MySQL + Traefik
Vamos a montar un WordPress completo con base de datos y proxy inverso. Este es un setup que uso en producción con clientes.
version: "3.8"
services:
traefik:
image: traefik:v2.11
command:
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
db:
image: mysql:8.0
volumes:
- db_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: wordpress
MYSQL_USER: ${DB_USER}
MYSQL_PASSWORD: ${DB_PASSWORD}
restart: unless-stopped
wordpress:
image: wordpress:6-apache
volumes:
- wp_data:/var/www/html
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: ${DB_USER}
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD}
WORDPRESS_DB_NAME: wordpress
labels:
- "traefik.http.routers.wp.rule=Host(`tudominio.com`)"
depends_on:
- db
restart: unless-stopped
volumes:
db_data:
wp_data:
Fíjate en varios detalles importantes:
- Traefik actúa como proxy inverso. Recibe el tráfico en el puerto 80 y lo enruta al contenedor correcto según el dominio. Si quieres añadir SSL, en el artículo sobre certificados SSL con Let’s Encrypt y Traefik explico cómo hacerlo.
- Las variables como
${DB_PASSWORD}se leen de un archivo.envque veremos a continuación. depends_onindica que WordPress necesita que la base de datos esté levantada primero.restart: unless-stoppedhace que los contenedores se reinicien automáticamente si el servidor se reinicia.
Variables de entorno y el archivo .env
Nunca pongas contraseñas directamente en el docker-compose.yml. Usa un archivo .env en la misma carpeta:
DB_ROOT_PASSWORD=una-contraseña-segura-aqui
DB_USER=wordpress_user
DB_PASSWORD=otra-contraseña-segura
Docker Compose lee automáticamente el archivo .env y sustituye las variables. Este archivo nunca debe subirse a un repositorio de código. Añádelo a tu .gitignore.
Comandos esenciales
Con el archivo docker-compose.yml y el .env en la misma carpeta, estos son los comandos que vas a usar constantemente:
Levantar todo
docker compose up -d
El flag -d ejecuta los contenedores en segundo plano. Sin él, verías los logs en la terminal y al cerrarla se pararían los contenedores.
Ver qué está corriendo
docker compose ps
Muestra el estado de cada servicio: si está corriendo, en qué puerto escucha y cuánto tiempo lleva activo.
Ver logs
docker compose logs -f wordpress
Muestra los logs del servicio wordpress en tiempo real. Esencial para depurar problemas. Sin especificar servicio, muestra los logs de todos.
Parar todo
docker compose down
Para y elimina los contenedores, pero los volúmenes (y por tanto los datos) se mantienen. Si quieres eliminar también los volúmenes, añade el flag -v, pero ten cuidado porque perderás los datos.
Reconstruir tras cambios
docker compose up -d --build
Si has modificado la configuración o actualizado imágenes, este comando recrea los contenedores que hayan cambiado.
Errores típicos de principiantes
Olvidar el archivo .env
Si las variables no están definidas, Docker Compose las sustituye por cadenas vacías. Tu base de datos se crea sin contraseña o con usuario vacío, y luego WordPress no puede conectar. Revisa siempre que el .env existe y tiene todos los valores.
No usar volúmenes
Si no defines volúmenes para los datos, la primera vez que hagas docker compose down y up perderás toda la información. La base de datos, los archivos subidos, la configuración, todo.
Puertos en conflicto
Si ya tienes algo escuchando en el puerto 80 (un Apache o Nginx instalado directamente en el servidor), Docker no podrá usar ese puerto. Comprueba que los puertos están libres antes de levantar los servicios.
Siguientes pasos
Una vez que tienes tu primer proyecto con Docker Compose funcionando, el siguiente nivel es:
- Añadir SSL con Let’s Encrypt para que tu web funcione con HTTPS.
- Configurar backups automáticos de los volúmenes. En mi guía de backups automáticos con rsync explico cómo hacerlo para toda la infraestructura.
- Añadir más servicios: un servidor de correo, una herramienta de analítica, un panel de administración.
- Montar un entorno de desarrollo local idéntico al de producción.
Docker Compose es la base sobre la que construyo toda la infraestructura de mis clientes. Si todavía estás decidiendo si necesitas un servidor propio, revisa la comparativa entre hosting compartido y VPS para entender cuándo da el salto. Una vez tengas el VPS, empezar con Docker Compose es la decisión más acertada que puedes tomar.
Si quieres que te ayude a montar tu infraestructura con Docker o necesitas migrar tu web actual a un entorno más profesional, escríbeme. También puedes ver mi servicio de gestión técnica donde me encargo de todo esto para que tú te centres en tu negocio.
Técnico freelance especializado en desarrollo a medida, automatizaciones con IA y gestión técnica para negocios en España. Más sobre mí →
¿Necesitas que alguien se ocupe de tu web?
Me encargo de que tu web funcione, esté segura y actualizada. Backups, actualizaciones y soporte directo. Planes desde 49 €/mes.