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
| .
├── 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
| 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
| 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