--- title: "Cómo usar Docker Compose en Ubuntu 24.04 con un ejemplo" description: "Despliega WordPress y MariaDB con Docker Compose usando volúmenes, redes, credenciales en .env y healthchecks, y aprende a operar y actualizar la pila." category: "Docker Kubernetes" language: es source: https://cubepath.com/es/docs/docker-kubernetes/docker-compose-guia-completa-con-ejemplos updated: 2026-09-25 --- # Cómo usar Docker Compose en Ubuntu 24.04 con un ejemplo Docker Compose permite describir en un único archivo YAML todos los contenedores de una aplicación, con sus redes, volúmenes y variables, y gestionarlos juntos con un solo comando. En este tutorial desplegarás en Ubuntu 24.04 un WordPress con su base de datos MariaDB usando Compose, guardarás las credenciales fuera del archivo principal, harás que WordPress espere a que la base de datos esté lista y aprenderás los comandos para operar, actualizar y eliminar la pila. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con al menos 1 GB de RAM. - Docker Engine y el plugin `docker-compose-plugin` instalados desde el repositorio oficial de Docker. - Un usuario no root con privilegios `sudo` y miembro del grupo `docker`. Comprueba que tienes Compose v2: ```bash docker compose version ``` ```output Docker Compose version v2.39.2 ``` El comando actual es `docker compose` (con espacio). El antiguo binario `docker-compose` escrito en Python está abandonado desde 2023; si tus scripts lo usan, cámbialos a la nueva sintaxis. ## Paso 1: Crear el directorio del proyecto Compose usa el nombre del directorio como **nombre del proyecto**, que sirve de prefijo para contenedores, redes y volúmenes. Crea uno para la pila: ```bash mkdir -p ~/wordpress && cd ~/wordpress ``` ## Paso 2: Guardar las credenciales en un archivo .env Compose lee automáticamente el archivo `.env` del directorio del proyecto y sustituye sus valores en `compose.yaml`. Así las contraseñas no quedan en el archivo que versionas. ```bash nano .env ``` ```ini MARIADB_ROOT_PASSWORD=your_root_password MARIADB_PASSWORD=your_db_password WP_PORT=8080 ``` Sustituye `your_root_password` y `your_db_password` por contraseñas largas y distintas; puedes generarlas con `openssl rand -base64 24`. Restringe los permisos del archivo: ```bash chmod 600 .env ``` > Importante: Si guardas el proyecto en Git, añade `.env` a `.gitignore`. ## Paso 3: Escribir el archivo compose.yaml El nombre recomendado del archivo es `compose.yaml` (también se aceptan `compose.yml` y el antiguo `docker-compose.yml`). Crea el archivo: ```bash nano compose.yaml ``` ```yaml services: db: image: mariadb:11.4 restart: unless-stopped environment: MARIADB_DATABASE: wordpress MARIADB_USER: wordpress MARIADB_PASSWORD: ${MARIADB_PASSWORD:?define MARIADB_PASSWORD en .env} MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:?define MARIADB_ROOT_PASSWORD en .env} volumes: - db_data:/var/lib/mysql networks: - backend healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s retries: 5 start_period: 30s wordpress: image: wordpress:php8.3-apache restart: unless-stopped depends_on: db: condition: service_healthy environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_NAME: wordpress WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: ${MARIADB_PASSWORD} ports: - "127.0.0.1:${WP_PORT:-8080}:80" volumes: - wp_data:/var/www/html networks: - backend volumes: db_data: wp_data: networks: backend: ``` Los bloques del archivo son: - **`services`**: cada entrada es un contenedor. `image` indica la imagen (con etiqueta fija), `restart` la política de reinicio, `environment` las variables y `volumes` los datos persistentes. - **`${VARIABLE}`**: se sustituye con el valor de `.env`. La forma `${VAR:?mensaje}` hace que Compose se niegue a arrancar si la variable no está definida, y `${VAR:-8080}` aplica un valor por defecto. - **`depends_on` con `condition: service_healthy`**: WordPress no arranca hasta que el healthcheck de MariaDB da positivo. Sin la condición, Compose solo esperaría a que el contenedor existiera, no a que la base de datos aceptara conexiones. - **`healthcheck`**: la imagen oficial de MariaDB incluye el script `healthcheck.sh`, que comprueba la conexión y que InnoDB está inicializado. - **`networks`**: los servicios de la misma red se localizan por su nombre. Por eso `WORDPRESS_DB_HOST` es simplemente `db`. - **`volumes`** (nivel superior): declara volúmenes con nombre que sobreviven a la eliminación de los contenedores. Ya no hace falta la clave `version:` al principio del archivo. Compose la ignora y muestra un aviso de que está obsoleta. El puerto se publica solo en `127.0.0.1`, porque los puertos que publica Docker no pasan por UFW. Para exponer el sitio lo correcto es poner delante un proxy inverso con HTTPS (Nginx o Caddy) que reenvíe a `127.0.0.1:8080`. Antes de arrancar, valida el archivo y comprueba cómo quedan las variables sustituidas: ```bash docker compose config ``` Si hay un error de sintaxis YAML o falta una variable obligatoria, Compose lo indica aquí con la línea exacta. Ten en cuenta que la salida muestra las contraseñas en claro. ## Paso 4: Arrancar la pila Descarga las imágenes, crea la red y los volúmenes y arranca los contenedores en segundo plano: ```bash docker compose up -d ``` ```output [+] Running 5/5 Network wordpress_backend Created Volume "wordpress_db_data" Created Volume "wordpress_wp_data" Created Container wordpress-db-1 Healthy Container wordpress-wordpress-1 Started ``` Observa que el contenedor de WordPress arranca después de que `db` pase a `Healthy`. Consulta el estado de los servicios: ```bash docker compose ps ``` ```output NAME IMAGE SERVICE STATUS PORTS wordpress-db-1 mariadb:11.4 db Up 40 seconds (healthy) 3306/tcp wordpress-wordpress-1 wordpress:php8.3-apache wordpress Up 12 seconds 127.0.0.1:8080->80/tcp ``` Comprueba que WordPress responde y redirige al asistente de instalación: ```bash curl -I http://127.0.0.1:8080 ``` ```output HTTP/1.1 302 Found Location: http://127.0.0.1:8080/wp-admin/install.php ``` Para completar la instalación desde tu navegador sin exponer el puerto, abre un túnel SSH desde tu equipo con `ssh -L 8080:127.0.0.1:8080 your_user@your_server_ip` y visita `http://localhost:8080`. ## Paso 5: Operar los servicios Todos los comandos de Compose se ejecutan desde el directorio del proyecto y aceptan el nombre de un servicio para actuar solo sobre él. Ver los logs de un servicio y seguirlos en tiempo real: ```bash docker compose logs -f --tail 50 wordpress ``` Ejecutar un comando dentro de un servicio en marcha, por ejemplo una consola de MariaDB (te pedirá la contraseña de `wordpress`): ```bash docker compose exec db mariadb -u wordpress -p wordpress ``` Comprueba que las tablas existen una vez completada la instalación web: ```sql SHOW TABLES; ``` Escribe `exit` para salir. Otros comandos habituales: | Comando | Efecto | |---------|--------| | `docker compose stop` | Detiene los contenedores sin eliminarlos | | `docker compose start` | Arranca los contenedores detenidos | | `docker compose restart wordpress` | Reinicia un servicio | | `docker compose top` | Procesos en ejecución de cada servicio | | `docker compose down` | Detiene y elimina contenedores y redes. Los volúmenes se conservan | ## Paso 6: Cambiar la configuración y actualizar imágenes Compose compara el estado actual con `compose.yaml` y solo recrea lo que ha cambiado. Por ejemplo, para limitar la memoria de la base de datos, añade la clave `mem_limit` al servicio `db`: ```bash nano compose.yaml ``` ```yaml db: image: mariadb:11.4 restart: unless-stopped mem_limit: 512m ``` Aplica el cambio: ```bash docker compose up -d ``` ```output Container wordpress-db-1 Recreated Container wordpress-wordpress-1 Running ``` Solo se recrea `db`; los datos siguen en el volumen `wordpress_db_data`. Para actualizar a las últimas versiones publicadas de las etiquetas que usas, descarga las imágenes y recrea los contenedores que hayan cambiado: ```bash docker compose pull docker compose up -d ``` Después elimina las imágenes antiguas que ya no usa ningún contenedor: ```bash docker image prune ``` > Consejo: Haz una copia de la base de datos antes de actualizar, por ejemplo con `docker compose exec -T db sh -c 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --all-databases' > backup.sql`. Cambiar de versión mayor de MariaDB (por ejemplo, de 10.11 a 11.4) requiere revisar las notas de actualización de la imagen. ## Paso 7: Separar la configuración de desarrollo Si existe un archivo `compose.override.yaml` junto a `compose.yaml`, Compose lo combina automáticamente. Es útil para ajustes que solo quieres en tu máquina local, por ejemplo montar un tema de WordPress en desarrollo: ```bash nano compose.override.yaml ``` ```yaml services: wordpress: volumes: - ./mi-tema:/var/www/html/wp-content/themes/mi-tema environment: WORDPRESS_DEBUG: "1" ``` En el servidor de producción no copies el archivo de override, o indica explícitamente qué archivos usar con `-f`: ```bash docker compose -f compose.yaml up -d ``` ## Paso 8: Detener y eliminar la pila Para eliminar contenedores y redes conservando los datos: ```bash docker compose down ``` Si vuelves a ejecutar `docker compose up -d`, WordPress arrancará con todo su contenido. Para borrarlo todo, volúmenes incluidos: ```bash docker compose down -v ``` > Advertencia: `down -v` elimina de forma permanente la base de datos y los archivos de WordPress. ## Solución de problemas **`required variable MARIADB_PASSWORD is missing a value`.** Falta el archivo `.env` o la variable en él. Compose busca `.env` en el directorio del proyecto, que por defecto es el directorio donde está `compose.yaml`. **`dependency failed to start: container wordpress-db-1 is unhealthy`.** MariaDB no ha arrancado bien. Revisa `docker compose logs db`. Si cambiaste las contraseñas de `.env` después del primer arranque, ten en cuenta que MariaDB solo las aplica al inicializar un volumen vacío. **WordPress muestra `Error establishing a database connection`.** Comprueba que `WORDPRESS_DB_PASSWORD` y `MARIADB_PASSWORD` coinciden y que ambos servicios están en la misma red con `docker compose config`. ## Conclusión Has desplegado una aplicación de dos servicios con Docker Compose, con credenciales en `.env`, volúmenes persistentes, una red interna y un arranque ordenado mediante healthchecks, y conoces los comandos para operarla y actualizarla. Como siguientes pasos, pon un proxy inverso con HTTPS delante de WordPress, programa copias de seguridad de los volúmenes y convierte tus propias aplicaciones en servicios de Compose a partir de su Dockerfile.