Desplegar NGINX, MariaDB y phpMyAdmin con Docker Compose

·5 min de lectura·

Docker Compose permite definir varios servicios relacionados en un único archivo. En esta guía montaremos NGINX para servir una página estática, MariaDB para almacenar datos y phpMyAdmin como interfaz de administración. Los servicios comparten una red privada de Compose; solo NGINX y phpMyAdmin publican puertos en el host, y phpMyAdmin queda limitado a la máquina local [1][2].

Nota: este ejemplo sirve para aprender y para un entorno local. Antes de exponerlo en Internet, añade HTTPS, autenticación y controles de acceso adecuados; no publiques phpMyAdmin directamente.

Estructura del proyecto

Crea una carpeta de trabajo con esta estructura:

web-stack/
├── compose.yaml
├── secrets/
│   ├── mariadb_root_password.txt
│   └── mariadb_app_password.txt
└── web/
    └── index.html

Escribe una contraseña única en cada archivo de secrets/. No uses los valores de ejemplo de este artículo ni subas estos archivos a un repositorio. Restringe el acceso en el host:

chmod 600 secrets/mariadb_root_password.txt secrets/mariadb_app_password.txt

Prepara una página de prueba en web/index.html:

<!doctype html>
<html lang="es">
  <meta charset="utf-8">
  <title>Servidor NGINX en Docker</title>
  <h1>NGINX está funcionando</h1>
</html>

Definir los servicios en Compose

Crea compose.yaml:

services:
  web:
    image: nginx:stable-alpine
    ports:
      - "8080:80"
    volumes:
      - ./web:/usr/share/nginx/html:ro
    restart: unless-stopped

  db:
    image: mariadb:lts
    environment:
      MARIADB_DATABASE: aplicacion
      MARIADB_USER: appuser
      MARIADB_PASSWORD_FILE: /run/secrets/mariadb_app_password
      MARIADB_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    secrets:
      - mariadb_app_password
      - mariadb_root_password
    volumes:
      - mariadb_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      start_period: 10s
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  phpmyadmin:
    image: phpmyadmin:5.2
    environment:
      PMA_HOST: db
    ports:
      - "127.0.0.1:8081:80"
    depends_on:
      db:
        condition: service_healthy
    restart: unless-stopped

secrets:
  mariadb_app_password:
    file: ./secrets/mariadb_app_password.txt
  mariadb_root_password:
    file: ./secrets/mariadb_root_password.txt

volumes:
  mariadb_data:

Compose crea una red para el proyecto, así que phpMyAdmin puede encontrar MariaDB usando el nombre de servicio db; no hace falta publicar el puerto de la base de datos en el host [1][3]. El volumen con nombre mariadb_data conserva los ficheros de la base aunque se reemplace el contenedor.

Las contraseñas se montan como secretos en los servicios que las necesitan. La imagen oficial de MariaDB admite las variables MARIADB_ROOT_PASSWORD_FILE y MARIADB_PASSWORD_FILE, que leen las claves desde esos archivos [4][5]. Los secretos de Compose basados en archivos se conceden explícitamente a cada servicio y se montan como archivos dentro del contenedor [2].

El puerto 8080 de NGINX se publica en las interfaces del host. El puerto 8081 de phpMyAdmin se enlaza a 127.0.0.1, por lo que solo es accesible desde el propio host. Docker advierte que publicar un puerto sin especificar una dirección normalmente lo hace accesible a través de las interfaces de red del host [6].

Validar y arrancar

Desde web-stack/, valida el YAML y luego inicia los servicios:

docker compose config --quiet
docker compose up -d
docker compose ps

Abre http://localhost:8080 para comprobar NGINX. Para administrar la base desde el mismo host, visita http://localhost:8081 e inicia sesión con el usuario appuser y la contraseña guardada en mariadb_app_password.txt. El usuario root queda reservado para tareas administrativas desde un entorno controlado.

Compose espera a que el healthcheck de MariaDB indique que el servicio está sano antes de crear phpMyAdmin, gracias a depends_on con condition: service_healthy [3]. El healthcheck healthcheck.sh forma parte de la imagen oficial de MariaDB [5].

Operación y persistencia

Consulta el estado y los registros con:

docker compose ps
docker compose logs --follow db
docker compose logs --follow phpmyadmin

Detén los contenedores sin eliminar el volumen de datos:

docker compose down

No añadas --volumes (-v) si quieres conservar la base: esa opción elimina los volúmenes declarados por Compose. La base se guarda en mariadb_data; haz copias de seguridad de forma independiente, pues un volumen no sustituye a un backup [7].

Las variables de inicialización de MariaDB, como el nombre de la base y las credenciales, se aplican al crear una base vacía. Si el volumen ya contiene una base, cambiar esas variables en Compose no modifica automáticamente las cuentas ni los datos existentes [4]. Para actualizar imágenes, revisa las notas de versión y fija una versión concreta adecuada a tu despliegue en lugar de depender de una etiqueta móvil.

En resumen

  • Compose define NGINX, MariaDB y phpMyAdmin como servicios separados.
  • La base de datos no publica un puerto en el host; phpMyAdmin la alcanza por la red privada de Compose.
  • Los archivos de secretos evitan escribir las contraseñas en el YAML, pero también deben protegerse y excluirse del control de versiones.
  • El volumen nombrado conserva los datos cuando se eliminan los contenedores, siempre que no se borre explícitamente.
  • phpMyAdmin queda disponible solo desde el host local en este ejemplo.

📚 Fuentes consultadas

  1. Networking in Compose — Docker Docs
  2. Manage secrets securely in Docker Compose — Docker Docs
  3. Control startup and shutdown order in Compose — Docker Docs
  4. MariaDB Server Docker Official Image Environment Variables — MariaDB Documentation
  5. Using Healthcheck — MariaDB Documentation
  6. Define services in Docker Compose — Docker Docs
  7. Volumes — Docker Docs

Imagen

Servicios web y base de datos con Docker Compose

¿Te ha resultado útil?

Compártelo con tu red de contactos profesionales.

Comentarios (0)

Sé el primero en comentar.