Configuració completa d’un Proxy Invers NGINX amb Docker per a Home Assistant (amb DuckDNS i SSL)
🧭 Objectiu
L’objectiu d’aquest projecte és desplegar un entorn segur i eficient que permeti l’accés remot a Home Assistant utilitzant un proxy invers basat en NGINX, gestionat a través de contenidors Docker, en una Raspberry Pi 5 amb Ubuntu Server. Per tal d’assegurar una connexió xifrada i de confiança, s’empren certificats SSL gratuïts obtinguts mitjançant Let’s Encrypt i validats automàticament amb Certbot. Un sistema per controlar el teu sistema de domòtica de Vilassar de mar, Vilassar de dalt, Preia de Mar, Premia de dalt, Cabrera, Argentona, Masnou, Alella.
El sistema també incorpora la integració amb DuckDNS per mantenir actualitzada l’adreça IP dinàmica del dispositiu, de manera que el servei sigui accessible externament a través d’un subdomini personalitzat (elteudomini.duckdns.org), independentment dels canvis d’IP del proveïdor d’internet.
Aquest document proporciona una guia completa i estructurada per configurar tots els components necessaris, incloent:
• Redirecció de ports al router,
• Configuració d’NGINX com a proxy invers (amb versió temporal i definitiva),
• Automatització de la generació i renovació de certificats SSL,
• Integració de DuckDNS per a la gestió dinàmica del DNS,
• I configuració de Home Assistant per acceptar peticions de proxy de manera segura.
Aquesta infraestructura garanteix un accés remot estable, segur, i fàcilment mantenible al teu entorn domòtic, sense necessitat d’utilitzar serveis de tercers de pagament, i tot gestionat des de la pròpia Raspberry Pi.
🔁 Pas previ important: redirecció de ports al router, compta duckdns.org, accès a la raspberry mitjançant ssh.
- Port 80 (HTTP) redirigit a
192.168.1.11:80 #la ip de la teva raspberry
- Port 443 (HTTPS) redirigit a
192.168.1.11:443 #la ip de la teva raspberry
- Compta dusckdns.org amb el teu domini creat
- Accès SSH a la raspberry.
IMPORTANT : en els exemples de codi a copiar de debò a negreta, el que has de substituir per les teves dades.
1. Estructura de carpetes i fitxers necessaris
Crear la següent carpeta i fitxers dins de la teva ruta/docker
sudo mkdir nginx-proxy
cd nginx-proxy
sudo mkdir html logs
sudo mkdir config
cd config
sudo mkdir conf.d
cd ../
vi docker-compose.yml
2. Contingut del Fitxer docker-compose.yml
vi docker-compose.yml
services:
services:
nginx:
image: nginx:latest
container_name: nginx-proxy
volumes:
- ./config/nginx.conf:/etc/nginx/nginx.conf
- ./config/conf.d:/etc/nginx/conf.d
- ./etc/letsencrypt:/etc/letsencrypt:rw
- ./config/html:/usr/share/nginx/html
- ./config/certbot:/var/www/certbot
ports:
- "80:80"
- "443:443"
restart: always
duckdns:
image: linuxserver/duckdns
container_name: duckdns
environment:
- DUCKDNS_TOKEN=elteutocken
- DUCKDNS_DOMAIN=elteudomini.duckdns.org
volumes:
- ./config/duckdns:/config
restart: always
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./etc/letsencrypt:/etc/letsencrypt:rw
- ./config/certbot:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
restart: always
3. Fitxer nginx.conf
sudo vi /latevaruta/docker/nginx-proxy/config/nginx.conf
events {}
# nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/conf.d/*.conf;
4. Contingut del Fitxer default.conf
desactivat SSL
sudo /latevaruta/docker/nginx-proxy/config/conf.d/default.nginx
events {}
server {
listen 80;
server_name syrck.duckdns.org;
root /usr/share/nginx/html;
index index.html;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# location / {
# return 301 https://$host$request_uri;
# }
}
#server {
#listen 443 ssl;
#server_name elteudomini.duckdns.org;
#ssl_certificate /etc/letsencrypt/live/elteudomini.duckdns.org/fullchain.pem;
#ssl_certificate_key /etc/letsencrypt/live/elteudomini.duckdns.org/privkey.pem;
### Proxy invers a Home Assistant
#location / {
#proxy_pass http://192.168.0.11:8123; # IP contenidor de Home Assistant
#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;
### Configuració per a WebSockets
#proxy_http_version 1.1;
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection 'upgrade';
#}
#}
5. Home Assistant: afegim al Home assutant les trusted_proxies
Afegir al fitxer configuration.yaml el següent:
sudo vi latevarutadocker/homeassitant/config/configuration.yaml
http:
use_x_forwarded_for: true
trusted_proxies:
- 172.18.0.0/16
- 192.168.0.11 # aquí la ip de la teva raspberry
6. Generació del certificat SSL (una vegada)
Un cop tenim tots els fitxers fets, arranquem els contenidors
/latevaruta/docker/nginx-proxy/docker compose -d
un cop iniciat modifiquem els permisos de les següents carpetes
sudo chown -R www-data:www-data /latevaruta/docker/nginx-proxy/config
sudo chown -R www-data:www-data /latevaruta/docker/nginx-proxy/config
i Verifiquem el correcte funcionament dels contenidor
/latevaruta/docker/nginx-proxy/docker ps
/latevaruta/docker/nginx-proxy/docker logs nginx-proxy
/latevaruta/docker/nginx-proxy/docker logs -f certbot
/latevaruta/docker/nginx-proxy/docker logs duckdns
Fem un reinci dels contenidors
/latevaruta/docker/nginx-proxy/docker compose down
/latevaruta/docker/nginx-proxy/docker compose up -d
Si tot ha anat bé podem fer un curl per veure si respon correctament amb duckdns y les carpetes per generar els certificats
curl http://syrck.duckdns.org/.well-known/acme-challenge/
executem docker exec -it certbot certbot certonly -d elteunomdedomini.duckdns.org –agree-tos –no-eff-email –email elte@mail
Si ens genera els certificats correctcament, acavem de configurar correcttament default.conf per poder treballar amb SSL.
Desde sudo /latevaruta/docker/nginx-proxy/config/conf.d/default.nginx. Treu el # de totes les línies que nomès tinguin un. Les que tenen ### son descripcions, ho les treguis.
events {}
server {
listen 80;
server_name syrck.duckdns.org;
root /usr/share/nginx/html;
index index.html;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name elteudomini.duckdns.org;
ssl_certificate /etc/letsencrypt/live/elteudomini.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/elteudomini.duckdns.org/privkey.pem;
### Proxy invers a Home Assistant
location / {
proxy_pass http://192.168.0.11:8123; # IP contenidor de Home Assistant
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;
### Configuració per a WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
}
}
docker compose restart nginx
* Recorda, una vegada generat el certificado SSL, substituir el codi del teu ngingx.conf amb la configuració SSL, i reiniciar el contenidor nginx des de la carpeta /docker/nginx-proxy ejecuta docker compose up -d
7. Script de renovació
vi /latevaruta//docker/nginx-proxy/renew_cert.sh
#!/bin/bash
cd /latevaruta/docker/nginx-proxy
docker compose run --rm certbot renew
docker compose exec nginx-proxy nginx -s reload
8. Cron per renovació diària
Executa des de la terminal ssh crontab -e i enganxa la següent línea
20 4 * * * /latevaruta/docker/nginx-proxy/renew_cert.sh >> /latevaruta/docker/nginx-proxy/renew.log
2>&1
Aquest codi ens automatitzarà la renovació del certificat SSL cada dia a les 4hores i 20 minuts.
✅ Estat final:
- Accés segur a Home Assistant: https://elteudomini.duckdns.org
- Certificat SSL vàlid i funcionant
- Renovació automàtica configurada
- DuckDNS gestionant IP dinàmica
💪 Tot 100% Dockeritzat i autogestionat.