Saltar a contenido

Instalación de Nginx con Docker Compose en un VPS con Debian/Ubuntu

Historial de cambios

Versión Fecha Comentario Autor
1.0 03/02/2025 Primera edición. Marco Teórico y Cheat Sheet. Jes

Introducción

Docker Compose es una herramienta que simplifica la orquestación de contenedores, permitiendo definir y gestionar servicios multi-contenedor mediante un archivo YAML. Combinado con Nginx —un servidor web y proxy inverso eficiente—, ofrece una solución robusta para desplegar aplicaciones web de forma reproducible y aislada. Este artículo explica cómo implementar Nginx en un VPS con Debian/Ubuntu usando Docker Compose, incluyendo ejemplos prácticos y configuraciones avanzadas.

1. Marco Teórico

1. Docker Compose:

Permite definir servicios, redes y volúmenes en un archivo docker-compose.yml, facilitando la gestión de aplicaciones en contenedores. Sus ventajas incluyen:

  • Reproducible: Configuración declarativa del entorno.
  • Aislamiento: Servicios independientes con recursos dedicados.
  • Portabilidad: Funciona en cualquier sistema con Docker instalado.

2. Imagen Oficial de Nginx:

Disponible en Docker Hub, incluye:

  • Soporte para contenido estático (HTML, CSS, JS).
  • Personalización de configuración mediante montajes de volúmenes.
  • Sustitución de variables de entorno en tiempo de ejecución (vía envsubst).

1.3 Casos de Uso Comunes:

  • Hosting de contenido estático.
  • Proxy inverso para aplicaciones.
  • Balanceo de carga.

2. Estructura del Proyecto

1
2
3
4
5
6
7
.
├── nginx/                    # Configuración central de Nginx + Certbot
│   ├── docker-compose.yml    # Define Nginx + Certbot (red y volúmenes compartidos)
│   └── conf.d/               # Carpeta para configs manuales (opcional)
└── odoo/                     # Proyecto Odoo (ejemplo)
    ├── docker-compose.yml    # Define Odoo + PostgreSQL
    └── nginx.conf           # Config específica para Odoo (proxy_pass, SSL, etc.)

3. Configuración Base (Solo una vez)

3.1. Crear red y volúmenes compartidos

1
2
3
4
docker network create nginx_net  # Red para conectar todos los servicios
docker volume create shared_confs  # Volumen para configs de Nginx
docker volume create certbot_www  # Volumen para desafíos ACME (Certbot)
docker volume create certbot_conf  # Volumen para certificados SSL

3.2. nginx/docker-compose.yml

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - shared_confs:/etc/nginx/conf.d  # Configs centralizadas
      - certbot_www:/var/www/certbot   # Certbot challenges
      - certbot_conf:/etc/letsencrypt  # Certificados SSL
    networks:
      - nginx_net
    restart: unless-stopped

  certbot:
    image: certbot/certbot
    volumes:
      - certbot_www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    networks:
      - nginx_net
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    depends_on:
      - nginx
    restart: unless-stopped

volumes:
  shared_confs:
    external: true  # Usa el volumen creado manualmente
  certbot_www:
    external: true
  certbot_conf:
    external: true

networks:
  nginx_net:
    external: true  # Usa la red creada manualmente

3.3. Iniciar Nginx + Certbot

cd nginx
docker compose up -d

4. Agregar un Proyecto (Ejemplo: Odoo)

4.1 Archivos de configuración

Archivo odoo.tudominio.com.conf.

server {
    listen 443 ssl http2;
    server_name odoo.tudominio.com;

    # Certificados SSL (generados por Certbot)
    ssl_certificate /etc/letsencrypt/live/odoo.tudominio.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/odoo.tudominio.com/privkey.pem;

    # Configuración SSL recomendada
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # Proxy a Odoo
    location / {
        proxy_pass http://web_aledev:8069;  # Nombre del servicio en Docker
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket (para chat en vivo)
    location /websocket {
        proxy_pass http://web_aledev:8072;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# Redirección HTTP → HTTPS
server {
    listen 80;
    server_name odoo.tudominio.com;
    return 301 https://$host$request_uri;
}

Archivo docker-compose.odoo.yaml.

services:
  web_aledev:
    image: odoo:16
    depends_on:
      - db_aledev
    ports:
      - "8069:8069"  # Odoo HTTP
      - "8072:8072"  # Longpolling (WebSocket)
    volumes:
      - odoo-data:/var/lib/odoo
    environment:
      - HOST=db_aledev  # Conexión a PostgreSQL
    networks:
      - nginx_net  # Misma red que Nginx

  db_aledev:
    image: postgres:15
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=odoo
      - POSTGRES_PASSWORD=odoo
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - nginx_net

  config_loader:
    image: alpine
    command: sh -c "cp /config/odoo.conf /etc/nginx/conf.d/"
    volumes:
      - ./nginx.conf:/config/odoo.conf
      - shared_confs:/etc/nginx/conf.d
    networks:
      - nginx_net

volumes:
  odoo-data:
  postgres-data:

networks:
  nginx_net:
    external: true  # Usa la red compartida

4.2 Generar Certificado SSL para Odoo

1
2
3
4
5
 docker compose -f docker-compose.yml run --rm --entrypoint "" certbot sh -c "certbot certonly --webroot -w /var/www/certbot -d dominio.com --email usuario@dominio.com  --agree-tos --no-eff-email --dry-run --http-01-port 80"
 ```

 ```bash
docker compose -f docker-compose.yml run --rm --entrypoint "" certbot sh -c "certbot certonly --webroot -w /var/www/certbot -d dominio.com --email usuario@dominio.com --agree-tos --no-eff-email --http-01-port 80"

4.3 Iniciar Odoo

cd odoo
docker compose up -d

5. Comandos Clave para Mantenimiento

Comando Descripción
docker exec nginx nginx -t Verificar sintaxis de Nginx
docker exec nginx nginx -s reload Recargar configuración sin downtime
docker compose -f nginx/docker-compose.yml run --rm certbot renew Renovar certificados manualmente
docker volume ls Listar volúmenes
docker network inspect nginx_net Verificar conectividad entre servicios

6. Solución de Problemas Comunes

6.1. Error: network nginx_net declared as external, but not found

docker network create nginx_net

6.2. Certbot no genera certificados

Verifica que:
- El dominio apunta al servidor correcto.
- Los puertos 80 y 443 están abiertos en el firewall.

6.3. Odoo no se conecta a PostgreSQL

Ejecuta:

docker exec -it odoo_web_aledev_1 ping db_aledev

Si falla, revisa que ambos servicios estén en la misma red (nginx_net).

Nota Final: Esta estructura permite escalar a N proyectos sin modificar la configuración base de Nginx. Cada proyecto vive en su propia carpeta con su propio docker-compose.yml, conectándose a través de la red compartida.

7. Usos

8. Bibliografía