Configuración completa de un Proxy Inverso NGINX con Docker para Home Assistant (con DuckDNS y SSL)
🧭 Objetivo
El objetivo de este proyecto es desplegar un entorno seguro y eficiente que permita el acceso remoto a Home Assistant utilizando un proxy inverso basado en NGINX, gestionado a través de contenedores Docker, en una Raspberry Pi 5 con Ubuntu Server. Para garantizar una conexión cifrada y fiable, se emplean certificados SSL gratuitos obtenidos mediante Let’s Encrypt y validados automáticamente con Certbot. Un sistema para controlar tu sistema de domótica de Vilassar de mar, Vilassar de dalt, Preia de Mar, Premia de dalt, Cabrera, Argentona, Masnou, Alella.
El sistema también incorpora la integración con DuckDNS para mantener actualizada la dirección IP dinámica del dispositivo, de modo que el servicio sea accesible externamente a través de un subdominio personalizado (syrck.duckdns.org), independientemente de los cambios de IP del proveedor de internet.
Este documento proporciona una guía completa y estructurada para configurar todos los componentes necesarios, incluyendo:
• Redirección de puertos en el router,
• Configuración de NGINX como proxy inverso (versión temporal y definitiva),
• Automatización de la generación y renovación de certificados SSL,
• Integración de DuckDNS para la gestión dinámica del DNS,
• Y configuración de Home Assistant para aceptar peticiones proxy de forma segura.
Esta infraestructura garantiza un acceso remoto estable, seguro y fácilmente mantenible a tu entorno domótico, sin necesidad de utilizar servicios de terceros de pago, todo gestionado desde la propia Raspberry Pi.
🔁 Paso previo importante: redirección de puertos en el router, cuenta en duckdns.org y acceso SSH a la Raspberry Pi.
- Puerto 80 (HTTP) redirigido a
192.168.1.11:80 #la IP de tu Raspberry
- Puerto 443 (HTTPS) redirigido a
192.168.1.11:443 #la IP de tu Raspberry
- Cuenta en duckdns.org con tu dominio creado
- Acceso SSH a la Raspberry
IMPORTANTE : en los ejemplos de código a copiar veras en negrita, lo que debes sustituir por tus datos.
1. Estructura de carpetas
Crea la siguiente carpeta y archivos dentro de tu ruta/docker:
mkdir nginx-proxy
cd nginx-proxy
mkdir certs html logs
vi docker-compose.yml
vi nginx.conf
2. Contenido del archivo docker-compose.yml
services:
nginx:
image: nginx:latest
container_name: nginx-proxy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certs:/etc/nginx/certs:ro
- ./html:/usr/share/nginx/html
- ./logs:/var/log/nginx
duckdns:
image: linuxserver/duckdns
container_name: duckdns
restart: unless-stopped
environment:
- SUBDOMAINS=tudominio
- TOKEN=TU_TOKEN_DUCKDNS
- TZ=Europe/Madrid
volumes:
- ./duckdns/config:/config
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./certs:/etc/letsencrypt
- ./html:/var/www/certbot
entrypoint: /bin/sh -c
command: >
"certbot certonly --webroot --webroot-path=/var/www/certbot
--email tu_email@correo.com --agree-tos --no-eff-email
-d tudominio.duckdns.org"
3. Archivo nginx.conf
temporal (sin SSL)
events {}
http {
server {
listen 80;
server_name tudominio.duckdns.org;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
return 200 'NGINX temporal funcionando para validación Certbot';
add_header Content-Type text/plain;
}
}
}
4. Archivo nginx.conf
definitivo con SSL
events {}
http {
server {
listen 80;
server_name tudominio.duckdns.org;
location /.well-known/acme-challenge/ {
root /usr/share/nginx/html;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name tudominio.duckdns.org;
ssl_certificate /etc/nginx/certs/live/tudominio.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/live/tudominio.duckdns.org/privkey.pem;
location / {
proxy_pass http://192.168.1.11:8123; # aquí la IP de tu Raspberry
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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;
}
}
}
5. Home Assistant: trusted_proxies
Añadir en el archivo configuration.yaml
lo siguiente:
vi docker/homeassitant/config/configuration.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.18.0.0/16
- 192.168.1.11 # aquí la IP de tu Raspberry
6. Generación del certificado SSL(una sola vez)
docker compose up -d nginx
docker compose run --rm certbot
mv nginx.conf.ssl nginx.conf
docker compose restart nginx
* Recuerda, una vez generado el certificado SSL, sustituir el código de tu ngingx.conf con la configuración SSLy reiniciar el contenedor de nging des de la carpeta /docker/nginx-proxy docker compose restart nginx-proxy
7. Crear Script de renovación del certificado SSL
#!/bin/bash
cd turuta/docker/nginx-proxy
docker compose run --rm certbot renew
docker compose exec nginx-proxy nginx -s reload
8. Cron para renovación diaria
Ejecuta desde la terminal SSH crontab -e
y pega la siguiente línea:
20 4 * * * /tu_ruta/docker/nginx-proxy/renew_cert.sh >> /tu_ruta/docker/nginx-proxy/renew.log
2>&1
Este código automatizará la renovación del certificado SSL cada día a las 4:20 de la madrugada.
✅ Estado final:
- Acceso seguro a Home Assistant:
https://tudominio.duckdns.org
- Certificado SSL válido y funcionando
- Renovación automática del certificado SSL configurada
- DuckDNS gestionando IP dinámica
💪 Todo 100% Dockerizado y autogestionado.