Nginx Proxy Manager: Reverse Proxy con UI Visual y SSL Automático (Guía Completa 2025)
Introducción
Gestionar múltiples servicios web en tu homelab puede convertirse rápidamente en un caos de puertos, certificados SSL vencidos y archivos de configuración de Nginx imposibles de mantener. ¿Y si pudieras configurar todo con clicks en una interfaz visual, sin tocar la terminal?
Nginx Proxy Manager (NPM) es exactamente eso: una UI web moderna que convierte la complejidad de Nginx en formularios simples. SSL automático con Let’s Encrypt, Access Lists para autenticación, logs visuales, backups con un click… todo sin escribir una sola línea de configuración .conf.
En esta guía exhaustiva aprenderás a instalar, configurar y dominar Nginx Proxy Manager para transformar tu homelab en una infraestructura profesional con HTTPS en todos tus servicios.
Lo que dominarás al terminar:
- Instalar Nginx Proxy Manager con Docker Compose en 10 minutos
- Configurar proxy hosts con SSL automático de Let’s Encrypt
- Crear certificados wildcard para múltiples subdominios
- Proteger servicios con Access Lists (autenticación)
- Integrar con Cloudflare, DuckDNS y otros DNS providers
- Comparar NPM vs Traefik vs Caddy (¿cuál elegir?)
- Troubleshoot errores 502, 504 y problemas de certificados
- Aplicar mejores prácticas de seguridad para producción
Ya seas principiante en homelabs o sysadmin experimentado, NPM simplificará drásticamente tu gestión de servicios web.
—¿Qué es Nginx Proxy Manager?
El Reverse Proxy con la UI Más Amigable
Nginx Proxy Manager es una interfaz de gestión web que envuelve Nginx (el servidor web más popular del mundo) en una UI visual intuitiva. Piensa en ello como «Nginx sin el dolor de cabeza».
Componentes principales:
- Nginx Core: Motor de reverse proxy (probado en batalla, usado por 33% de todos los sitios web)
- Node.js Backend: API REST para gestionar configuraciones
- SQLite Database: Almacena proxy hosts, certificados, usuarios
- Certbot Integration: Cliente Let’s Encrypt para SSL automático
- React Frontend: UI web moderna y responsive
Filosofía «Zero Touch»: Nunca necesitas editar archivos de configuración de Nginx. Todo se hace con formularios en la UI web.
¿Por Qué Nginx Proxy Manager para tu Homelab?
Ventajas sobre Nginx tradicional:
| Tarea | Nginx Tradicional | Nginx Proxy Manager |
|---|---|---|
| Añadir proxy host | Editar /etc/nginx/sites-available/, crear symlink, nginx -t, nginx -s reload | Formulario en UI, click «Save» |
| Certificado SSL | certbot certonly --nginx -d domain.com, editar config, test, reload | Click «Request SSL», esperar 30 seg, listo |
| Renovar certificado | Cron job + script + esperanza | Automático cada 60 días |
| Ver logs | tail -f /var/log/nginx/access.log | UI con búsqueda y filtros |
| Backup config | Copiar manualmente todos los .conf | Export JSON en UI |
Casos de uso perfectos:
- Homelabs con 5-50 servicios (Portainer, Nextcloud, Home Assistant, n8n, Jellyfin)
- No quieres ser experto en Nginx (curva de aprendizaje reducida 90%)
- SSL automático es crítico (Let’s Encrypt con renovación sin intervención)
- Múltiples subdominios (
portainer.home.lan,n8n.home.lan,grafana.home.lan) - Necesitas autenticación simple (Access Lists con usuario/password)
NO uses NPM si:
- Necesitas configuraciones extremadamente avanzadas de Nginx (Lua scripts, rate limiting complejo)
- Tienes >100 servicios (Traefik auto-discovery es más eficiente)
- Quieres automation con labels Docker (Traefik es superior)
Comparativa: Nginx Proxy Manager vs Traefik vs Caddy
Antes de instalar, es crucial elegir el reverse proxy correcto. Aquí está la comparativa definitiva:
| Característica | NPM | Traefik | Caddy |
|---|---|---|---|
| UI de Gestión | ✅ Web UI completa | ⚠️ Dashboard read-only | ❌ No (config file) |
| Auto-discovery | ❌ Manual | ✅ Docker labels | ❌ Manual |
| Curva Aprendizaje | ⭐⭐ Muy fácil | ⭐⭐⭐ Media | ⭐⭐ Fácil |
| SSL Automático | ✅ Let’s Encrypt | ✅ Let’s Encrypt | ✅ Let’s Encrypt |
| Wildcard Certs | ✅ Wizard DNS | ✅ Config YAML | ✅ Config file |
| Performance | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
| RAM Usage | ~200 MB | ~50-100 MB | ~30-50 MB |
| Access Control | ✅ Access Lists | ⚠️ Middlewares | ⚠️ Básico |
| Backup/Restore | ✅ Export/Import UI | ❌ Manual | ❌ Manual |
| Logs Visualization | ✅ En UI con filtros | ❌ Terminal | ❌ Terminal |
| Community | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Ideal Para | Principiantes, UI lovers | DevOps, auto-scaling | Minimalistas |
Decisión por Caso de Uso
Elige Nginx Proxy Manager si:
- ✅ Prefieres UI visual sobre archivos de configuración
- ✅ Gestionas servicios manualmente (no necesitas auto-discovery)
- ✅ Quieres máxima simplicidad para SSL
- ✅ 5-50 servicios en tu homelab
Elige Traefik si:
- ✅ Tienes muchos contenedores Docker que cambian frecuentemente
- ✅ Necesitas auto-discovery con labels
- ✅ Requieres load balancing avanzado
- ✅ Trabajas en ambiente cloud-native/Kubernetes
Elige Caddy si:
- ✅ Quieres minimalismo extremo (un solo binario)
- ✅ Config file simple es suficiente (Caddyfile)
- ✅ No necesitas UI
- ✅ Prioridad absoluta: bajo consumo RAM
Recomendación: Para homelabs domésticos, NPM ofrece el mejor balance entre potencia y facilidad de uso.
—Instalación de Nginx Proxy Manager con Docker
Requisitos Previos
- ✅ Docker instalado (
docker --version) - ✅ Docker Compose instalado (
docker-compose --version) - ✅ Puertos 80, 443, 81 disponibles
- ✅ (Opcional) Dominio apuntando a tu IP pública
Paso 1: Crear Estructura de Directorios
# Crear carpeta para NPM
mkdir -p ~/nginx-proxy-manager
cd ~/nginx-proxy-manager
Paso 2: Docker Compose Completo
Crea docker-compose.yml:
version: '3.8'
services:
nginx-proxy-manager:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80' # HTTP
- '443:443' # HTTPS
- '81:81' # Admin Web UI
environment:
DB_SQLITE_FILE: "/data/database.sqlite"
DISABLE_IPV6: 'true' # Opcional: deshabilitar IPv6
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy_network
healthcheck:
test: ["CMD", "/bin/check-health"]
interval: 10s
timeout: 3s
networks:
proxy_network:
driver: bridge
Configuración de seguridad (Producción):
ports:
- '80:80'
- '443:443'
- '127.0.0.1:81:81' # Solo accesible desde localhost
Paso 3: Iniciar Nginx Proxy Manager
# Levantar servicios
docker-compose up -d
# Verificar está corriendo
docker ps | grep nginx-proxy-manager
# Ver logs
docker logs nginx-proxy-manager -f
Paso 4: Acceso Inicial
URL: http://localhost:81 (o http://IP-SERVIDOR:81)
Credenciales por defecto:
- Email:
admin@example.com - Password:
changeme
IMPORTANTE: ⚠️ El sistema te forzará a cambiar email y password en el primer login.
Paso 5: Configuración Inicial Recomendada
- Cambiar credenciales admin (obligatorio)
- Deshabilitar Dark Mode (opcional, según preferencia)
- Configurar Default Site (página mostrada si no hay proxy host match)
Configurar tu Primer Proxy Host con SSL
Vamos a exponer Portainer con HTTPS automático paso a paso.
Escenario: Portainer en portainer.home.lan
Prerrequisitos:
- Portainer corriendo en Docker (puerto 9000)
- DNS local apuntando
portainer.home.lana IP del servidor NPM - (Para SSL público) Dominio real apuntando a tu IP pública
Paso 1: Añadir Proxy Host
- En NPM UI, ir a Hosts → Proxy Hosts
- Click Add Proxy Host
- Tab Details:
Domain Names:
portainer.home.lan
Scheme: http (el backend es HTTP, NPM añade HTTPS)
Forward Hostname / IP:
portainer (nombre del contenedor Docker)
O: 192.168.1.100 (IP directa)
Forward Port:
9000
Cache Assets: ☐ (desactivado para apps dinámicas)
Block Common Exploits: ☑ (activado por seguridad)
Websockets Support: ☑ (activado - Portainer lo necesita)
Access List: - None - (por ahora)
- Click Save
Resultado: Portainer accesible en http://portainer.home.lan (HTTP por ahora)
Paso 2: Añadir SSL Automático
- Editar el proxy host recién creado
- Tab SSL:
SSL Certificate: Request a new SSL Certificate
Force SSL: ☑ (redirect HTTP → HTTPS)
HTTP/2 Support: ☑
HSTS Enabled: ☑ (seguridad adicional)
HSTS Subdomains: ☐ (solo si aplica)
Email Address for Let's Encrypt: tu@email.com
I Agree to the Let's Encrypt Terms of Service: ☑
- Click Save
NPM automáticamente:
- ✅ Solicita certificado a Let’s Encrypt
- ✅ Configura Nginx para HTTPS
- ✅ Programa renovación automática (cada 60 días)
- ✅ Habilita redirección HTTP → HTTPS
Resultado: https://portainer.home.lan con certificado válido (si el dominio es público).
Para dominios locales (.home.lan, .local): Necesitarás certificado custom o usar IP + HTTP (Let’s Encrypt requiere validación pública).
—Certificados Wildcard con Cloudflare
Los certificados wildcard te permiten cubrir todos los subdominios con un solo certificado: .tudominio.com
Ventajas de Wildcard
- ✅ Un certificado para infinitos subdominios
- ✅ No necesitas puerto 80 abierto públicamente (usa DNS challenge)
- ✅ Puedes obtener certs para servicios internos
- ✅ Menos requests a Let’s Encrypt (límites rate)
Requisitos
- Dominio en Cloudflare (o otro DNS provider soportado)
- API Token de Cloudflare con permisos:
– Zone: Read
– DNS: Edit
Paso 1: Crear API Token en Cloudflare
- Login en Cloudflare → My Profile → API Tokens
- Create Token → «Edit zone DNS» template
- Zone Resources: Include → Specific zone → tudominio.com
- Continue → Create Token
- Copiar token (solo se muestra una vez)
Paso 2: Configurar en NPM
- NPM UI → SSL Certificates → Add SSL Certificate
- Tipo: Let’s Encrypt + DNS Challenge
- Configuración:
Domain Names:
*.tudominio.com
tudominio.com (incluir root también)
Email: tu@email.com
I Agree to the Let's Encrypt Terms of Service: ☑
DNS Provider: Cloudflare
Credentials File Content:
dns_cloudflare_api_token = <TU_TOKEN_CLOUDFLARE>
Propagation Seconds: 120 (tiempo para DNS propagation)
- Click Save
NPM automáticamente:
- Crea registro TXT temporal en Cloudflare
- Valida con Let’s Encrypt
- Obtiene certificado wildcard
- Limpia registros TXT
Tiempo total: ~2-3 minutos
Paso 3: Usar Certificado Wildcard
Al crear proxy hosts, selecciona el wildcard certificate:
SSL Certificate: (select) *.tudominio.com
Ahora puedes crear servicio1.tudominio.com, servicio2.tudominio.com, etc. todos usando el mismo certificado.
Access Lists: Proteger Servicios con Autenticación
Access Lists permiten añadir autenticación HTTP Basic a cualquier servicio sin configurar auth en cada aplicación individual.
Caso de Uso: Proteger n8n
Escenario: n8n tiene workflows sensibles y quieres capa extra de seguridad.
Paso 1: Crear Access List
- NPM UI → Access Lists → Add Access List
- Configuración:
Name: Admin Users
Authorization:
☑ Satisfy Any
Username: admin
Password: <password-seguro>
(Click "Add" para añadir más usuarios)
Pass Auth to Host: ☑ (opcional - pasa headers X-Forwarded-User)
- Save
Paso 2: Asignar a Proxy Host
- Editar proxy host de n8n
- Details tab:
Access List: Admin Users (select)
- Save
Resultado: Al acceder a https://n8n.tudominio.com, el navegador solicita usuario/password ANTES de llegar a n8n.
Access Lists Avanzados
Permitir IPs específicas:
Allow IPs:
192.168.1.0/24 (red local)
100.64.0.0/10 (Tailscale)
Deny IPs:
0.0.0.0/0 (bloquear todo lo demás)
Ejemplo: Acceso solo desde VPN:
Allow: 10.8.0.0/24 (OpenVPN)
Allow: 100.64.0.0/10 (Tailscale)
Deny: 0.0.0.0/0
—
Integración con Servicios Populares
Portainer (Docker GUI)
Domain: portainer.tudominio.com
Forward Hostname: portainer (contenedor Docker)
Forward Port: 9000
☑ Block Common Exploits
☑ Websockets Support (CRÍTICO para Portainer)
Home Assistant
Domain: ha.tudominio.com
Forward Hostname: homeassistant
Forward Port: 8123
☑ Websockets Support
☐ Block Common Exploits (desactivar - causa problemas con HA)
Custom Nginx Configuration:
client_max_body_size 50M;
proxy_buffering off;
Nextcloud
Domain: cloud.tudominio.com
Forward Hostname: nextcloud
Forward Port: 80
Custom Config (CRÍTICO):
client_max_body_size 10G;
client_body_timeout 300s;
location = /.well-known/carddav {
return 301 $scheme://$host/remote.php/dav;
}
location = /.well-known/caldav {
return 301 $scheme://$host/remote.php/dav;
}
n8n (Automation Platform)
Domain: n8n.tudominio.com
Forward Hostname: n8n
Forward Port: 5678
☑ Websockets Support
Custom Config:
client_max_body_size 50M;
proxy_read_timeout 300s;
Jellyfin / Plex (Media Streaming)
Domain: jellyfin.tudominio.com
Forward Hostname: jellyfin
Forward Port: 8096
Custom Config (optimizado para streaming):
proxy_buffering off;
proxy_request_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Timeouts largos para streaming
proxy_read_timeout 3600s;
proxy_connect_timeout 3600s;
send_timeout 3600s;
—
Streams: TCP/UDP Proxying
NPM no solo hace HTTP/HTTPS, también puede proxear conexiones TCP/UDP raw.
Caso de Uso: Exponer Base de Datos PostgreSQL
ADVERTENCIA: ⚠️ Nunca expongas bases de datos a internet sin VPN. Este ejemplo es para acceso interno.
Configuración Stream
- NPM UI → Streams → Add Stream
- Configuración:
Incoming Port: 5432
Forwarding Host: postgres (contenedor Docker)
Forwarding Port: 5432
TCP Forwarding: ☑
UDP Forwarding: ☐
Docker Compose necesita mapear puerto:
services:
nginx-proxy-manager:
ports:
- '80:80'
- '443:443'
- '81:81'
- '5432:5432' # Stream PostgreSQL
Uso: Conectar a PostgreSQL en servidor-npm:5432 proxy automáticamente a backend.
Otros Casos Stream
- MySQL: Puerto 3306
- SSH: Puerto 22 (para jump host)
- SMTP: Puerto 25, 587
- Redis: Puerto 6379
- Minecraft Server: Puerto 25565
Redirection Hosts: Redirects Simples
Caso de uso: Redirigir old-domain.com → new-domain.com
Configuración
- NPM UI → Hosts → Redirection Hosts → Add
- Configuración:
Domain Names: old-domain.com, www.old-domain.com
Scheme: https
Forward Domain/IP: new-domain.com
Redirection Code:
○ 301 Permanent (SEO-friendly, recomendado)
○ 302 Temporary
Preserve Path: ☑ (mantener /path en redirect)
Resultado: https://old-domain.com/blog/post → https://new-domain.com/blog/post
Optimización y Mejores Prácticas
1. Seguridad del Admin Panel
Problema: Puerto 81 expuesto = vulnerabilidad crítica
Soluciones recomendadas:
Opción A: Solo localhost (Mejor para homelab local)
ports:
- '127.0.0.1:81:81' # Solo accesible desde localhost
Acceso remoto vía SSH tunnel:
ssh -L 8181:localhost:81 user@servidor-homelab
# Abrir http://localhost:8181 en navegador
Opción B: VPN obligatoria (Tailscale)
# No mapear puerto 81 públicamente
# Acceder vía Tailscale internal IP: http://100.x.x.x:81
Opción C: Access List en proxy host de admin UI
Crear proxy host para npm-admin.tudominio.com que apunte a nginx-proxy-manager:81 con Access List restrictiva.
2. Backup Automatizado
Qué respaldar:
/data/database.sqlite– Toda la configuración/letsencrypt/– Certificados SSL- Export desde UI (JSON)
Script de backup:
#!/bin/bash
# backup-npm.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backups/npm"
# Crear backup del contenedor
docker exec nginx-proxy-manager cp /data/database.sqlite /data/backup-$DATE.sqlite
# Copiar archivos al host
docker cp nginx-proxy-manager:/data/backup-$DATE.sqlite $BACKUP_DIR/
tar czf $BACKUP_DIR/npm-full-backup-$DATE.tar.gz data/ letsencrypt/
# Subir a cloud (ejemplo: rclone)
rclone copy $BACKUP_DIR/ gdrive:backups/npm/
# Retener solo últimos 30 días
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
echo "✅ Backup completado: npm-full-backup-$DATE.tar.gz"
Cron para ejecutar diariamente:
# crontab -e
0 3 * * * /usr/local/bin/backup-npm.sh
3. Performance Tuning
Cacheo de assets estáticos:
# En Custom Nginx Configuration de proxy host:
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, no-transform, immutable";
access_log off;
}
Compression (Gzip):
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml;
Rate Limiting (prevenir abuse):
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_req zone=api_limit burst=20 nodelay;
4. Custom Error Pages
Página 503 de mantenimiento personalizada:
error_page 503 /maintenance.html;
location = /maintenance.html {
root /data/nginx/custom;
internal;
}
Crear /data/nginx/custom/maintenance.html:
<!DOCTYPE html>
<html>
<head>
<title>Mantenimiento</title>
</head>
<body>
<h1>🔧 Servicio en Mantenimiento</h1>
<p>Volveremos pronto. Gracias por tu paciencia.</p>
</body>
</html>
—
Troubleshooting: Soluciones a Errores Comunes
Error 1: «502 Bad Gateway»
Síntomas: Navegador muestra «502 Bad Gateway» al acceder al servicio.
Causas y soluciones:
Causa 1: Backend service caído
# Verificar backend está corriendo
docker ps | grep portainer
# Si está caído, levantarlo
docker start portainer
Causa 2: Hostname/IP incorrecto
# Test conectividad desde NPM a backend
docker exec nginx-proxy-manager curl http://portainer:9000
# Si falla, verificar:
# - Nombre correcto del contenedor
# - Ambos en misma red Docker
# - Puerto correcto
Causa 3: Network isolation
# Ver redes del contenedor backend
docker inspect portainer | grep NetworkMode
# Añadir backend a red de NPM
docker network connect proxy_network portainer
Error 2: «504 Gateway Timeout»
Síntomas: Request timeout después de 60 segundos.
Causa: Backend muy lento o operación pesada (uploads, procesamiento).
Solución – Aumentar timeouts:
# Custom Nginx Configuration del proxy host:
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
send_timeout 300s;
client_max_body_size 100M;
Error 3: «Challenge Failed» al solicitar SSL
Síntomas: Let’s Encrypt falla con error «Failed to verify challenge».
Causas y soluciones:
Causa 1: Puerto 80 no accesible públicamente
# Test de accesibilidad pública
curl -I http://tudominio.com
# Verificar firewall permite puerto 80
sudo ufw status | grep 80
sudo ufw allow 80/tcp
Causa 2: DNS no apunta a IP correcta
# Verificar DNS propagation
nslookup tudominio.com
dig tudominio.com
# Debe retornar tu IP pública
Causa 3: Cloudflare Proxy activado (naranja)
En Cloudflare DNS:
- Desactivar proxy (nube gris) durante validación
- O usar DNS Challenge en lugar de HTTP Challenge
Error 4: «Invalid Response» en Dashboard
Síntomas: NPM UI no carga, muestra errores.
Soluciones:
# 1. Verificar contenedor está healthy
docker ps | grep nginx-proxy-manager
# 2. Ver logs de errores
docker logs nginx-proxy-manager --tail 50
# 3. Reiniciar NPM
docker restart nginx-proxy-manager
# 4. Si persiste, regenerar database (PRECAUCIÓN: pierdes config)
docker-compose down
rm -rf data/database.sqlite
docker-compose up -d
# Login con credenciales default y reconfigurar
Error 5: Websockets No Funcionan
Síntomas: Apps en tiempo real (Portainer, Home Assistant, n8n) no actualizan.
Solución:
Proxy Host → Details tab:
☑ Websockets Support (activar)
Si persiste, añadir manualmente:
# Custom Config:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
—
Casos de Uso Avanzados
Stack Completo de Homelab
Servicios expuestos vía NPM:
portainer.home.lan → Portainer (9000)
n8n.home.lan → n8n Automation (5678)
grafana.home.lan → Grafana Dashboards (3000)
uptime.home.lan → Uptime Kuma (3001)
jellyfin.home.lan → Jellyfin Media (8096)
books.home.lan → Calibre Web (8083)
home.home.lan → Home Assistant (8123)
Docker Compose coordinado:
version: '3.8'
services:
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:latest
ports:
- '80:80'
- '443:443'
- '127.0.0.1:81:81'
volumes:
- ./npm/data:/data
- ./npm/letsencrypt:/etc/letsencrypt
networks:
- homelab_network
portainer:
image: portainer/portainer-ce
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- homelab_network
n8n:
image: n8nio/n8n
environment:
- WEBHOOK_URL=https://n8n.home.lan
volumes:
- n8n_data:/home/node/.n8n
networks:
- homelab_network
grafana:
image: grafana/grafana
volumes:
- grafana_data:/var/lib/grafana
networks:
- homelab_network
networks:
homelab_network:
driver: bridge
volumes:
n8n_data:
grafana_data:
Resultado: Todos los servicios accesibles por nombre memorable con HTTPS automático.
Custom Locations (Path-Based Routing)
Escenario: Múltiples servicios bajo mismo dominio.
app.com/ → Frontend React
app.com/api/ → Backend API
app.com/admin/ → Admin Panel
app.com/docs/ → Documentation
Configuración:
- Crear proxy host principal:
app.com→ Frontend - En ese proxy host, añadir Custom Locations:
Path: /api
Forward Hostname: backend-api
Forward Port: 8000
Path: /admin
Forward Hostname: admin-panel
Forward Port: 3000
Path: /docs
Forward Hostname: documentation
Forward Port: 8080
—
Monitoreo y Logs
Logs en UI
Access Logs (requests):
- Proxy Hosts → Click en host → Access Log tab
- Ver requests en tiempo real con:
– IP origen
– URL solicitada
– Status code
– User agent
– Timestamp
Error Logs:
- Ver errores de Nginx específicos del host
- Útil para debug de 502, 504, etc.
Logs desde CLI
# Logs generales de NPM
docker logs nginx-proxy-manager -f
# Logs de un proxy host específico
docker exec nginx-proxy-manager tail -f /data/logs/proxy-host-1_access.log
# Logs de error de Nginx
docker exec nginx-proxy-manager tail -f /data/logs/error.log
# Seguir todos los logs
docker exec nginx-proxy-manager tail -f /data/logs/*.log
Integración con Grafana Loki
Promtail para enviar logs a Loki:
# docker-compose.yml
services:
promtail:
image: grafana/promtail:latest
volumes:
- ./npm/data/logs:/var/log/npm:ro
- ./promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
—
Enlaces Relacionados
Para complementar tu homelab con herramientas de gestión Docker y monitoreo:
- [Portainer: Gestiona Docker con Interfaz Web (Guía Completa 2025)](https://www.eldiarioia.es/2025/10/16/portainer-gestiona-docker-con-interfaz-web/)
- [Dockge vs Portainer: ¿Cuál Elegir para Docker? (Comparativa 2025)](https://www.eldiarioia.es/2025/11/03/dockge-vs-portainer-docker-gui/)
- [Uptime Kuma: Monitoreo Self-Hosted Gratis (Guía 2025)](https://www.eldiarioia.es/2025/11/05/uptime-kuma-monitoreo-self-hosted-homelab/)
- [Tailscale para Homelab: VPN Mesh sin Abrir Puertos](https://www.eldiarioia.es/2025/10/25/tailscale-homelab-vpn-mesh/)
- [n8n Nodos: Guía Completa de Automatización 2025](https://www.eldiarioia.es/2025/06/24/nodos-n8n-automatizacion/)
- [Homelab con GPU 24GB+: Guía Completa Stack Profesional](https://www.eldiarioia.es/2025/10/25/homelab-gpu-24gb-guia-completa/)
- [El Stack arr: Prowlarr, Sonarr, Radarr (Tutorial 2025)](https://www.eldiarioia.es/2025/11/03/arr-stack-prowlarr-sonarr-radarr-tutorial/)
- [Freenom Alternativas 2025: Mejores Dominios Gratis](https://www.eldiarioia.es/2025/11/04/freenom-alternativas-dominios-gratis/)
Preguntas Frecuentes
¿Nginx Proxy Manager consume muchos recursos?
No excesivamente. NPM consume aproximadamente:
- RAM: 180-220 MB (incluye Nginx + Node.js + SQLite)
- CPU: 0.5-2% en reposo con 10-20 proxy hosts activos
- Disco: ~50 MB (binario) + certificados (~1-5 MB por cert)
Para homelabs típicos con 10-30 servicios, NPM corre perfectamente en:
- Raspberry Pi 4 (4GB RAM)
- Intel NUC básico
- VM con 1 vCPU + 1 GB RAM
Comparación:
- Traefik: ~50-100 MB (más ligero)
- Caddy: ~30-50 MB (más ligero aún)
- NPM trade-off: Mayor consumo RAM pero UI completa incluida
¿Puedo usar Nginx Proxy Manager sin Docker?
Técnicamente sí, pero NO recomendado. Existe instalación nativa en Ubuntu/Debian, pero:
- ❌ Mucho más compleja (dependencias Node.js, Python, etc.)
- ❌ Actualizaciones manuales
- ❌ Conflictos con otras apps Node.js
- ❌ No hay aislamiento de procesos
Recomendación: Usa Docker siempre. Es el método oficial y más estable.
¿Nginx Proxy Manager funciona con IPv6?
Sí, pero desactivado por defecto. Para habilitar IPv6:
environment:
DISABLE_IPV6: 'false'
Luego configurar dual-stack en proxy hosts:
Forward Hostname: backend (IPv4)
IPv6: ☑ Support IPv6
Nota: La mayoría de homelabs no necesitan IPv6. Déjalo desactivado salvo que tengas caso de uso específico.
¿Cómo migro de Traefik a Nginx Proxy Manager?
Proceso manual requerido (no hay migración automática):
- Documentar config actual de Traefik:
– Listar todos los servicios con labels
– Anotar dominios, puertos, middlewares
- Setup NPM con Docker Compose
- Recrear proxy hosts en NPM:
– Por cada servicio Traefik, crear proxy host equivalente
– Configurar SSL certificates (wildcard recomendado)
- Verificar funcionamiento antes de apagar Traefik
- Cambiar puertos (Traefik y NPM compiten por 80/443)
Tiempo estimado: ~1-2 horas para 20 servicios.
¿NPM soporta HTTP/3 (QUIC)?
No actualmente. NPM está basado en Nginx mainline que tiene soporte experimental HTTP/3, pero NPM no lo expone en la UI.
Si HTTP/3 es crítico, considera Caddy (soporte nativo) o esperar futuras versiones de NPM.
¿Puedo tener múltiples instancias de NPM para alta disponibilidad?
No directamente. NPM usa SQLite (single-file database) que no soporta concurrencia de múltiples procesos.
Workaround para HA:
- NPM primario (activo)
- NPM secundario (standby)
- Script que sincroniza
database.sqlitedel primario al secundario - En caso de fallo del primario, promover secundario manualmente
Alternativa: Usa Traefik si HA es requisito crítico (Traefik es stateless, escala horizontalmente fácil).
¿Cómo exporto/importo configuración entre servidores?
Método 1: Export/Import en UI (Recomendado)
- Servidor origen: Settings → Backup → Download Backup
- Servidor destino: Settings → Restore → Upload backup JSON
- All proxy hosts, streams, redirects, access lists recreados
Método 2: Copiar database.sqlite
# Servidor origen
docker cp nginx-proxy-manager:/data/database.sqlite ./backup.sqlite
# Servidor destino
docker cp ./backup.sqlite nginx-proxy-manager:/data/database.sqlite
docker restart nginx-proxy-manager
IMPORTANTE: Certificados SSL NO se incluyen en export JSON. Copiar carpeta letsencrypt/ manualmente o regenerar.
¿NPM puede hacer load balancing entre múltiples backends?
Sí, básico. En proxy host, puedes especificar múltiples Forward Hosts:
# Custom Config:
upstream backend {
server backend1:8080;
server backend2:8080;
server backend3:8080;
}
location / {
proxy_pass http://backend;
}
Limitaciones:
- No health checks automáticos (Nginx Plus feature)
- No sticky sessions en UI (requiere config manual)
- Round-robin básico
Si necesitas LB avanzado: Usa Traefik o HAProxy.
¿Puedo usar NPM para servicios no-HTTP (SSH, RDP, bases de datos)?
Sí, con Streams (TCP/UDP proxying).
Ejemplo: MySQL Database
Streams → Add Stream:
Incoming Port: 3306
Forwarding Host: mysql-server
Forwarding Port: 3306
TCP: ☑
Docker Compose necesita:
ports:
- '3306:3306' # Mapear puerto del stream
Soporta: PostgreSQL (5432), Redis (6379), SSH (22), RDP (3389), cualquier TCP/UDP.
¿Cómo actualizo Nginx Proxy Manager sin perder configuración?
# 1. Backup ANTES de actualizar (CRÍTICO)
docker exec nginx-proxy-manager cp /data/database.sqlite /data/backup-pre-update.sqlite
# 2. Pull imagen actualizada
docker pull jc21/nginx-proxy-manager:latest
# 3. Recrear contenedor
docker-compose up -d
# 4. Verificar funciona correctamente
docker logs nginx-proxy-manager
# 5. Si algo sale mal, rollback:
docker cp nginx-proxy-manager:/data/backup-pre-update.sqlite /data/database.sqlite
docker restart nginx-proxy-manager
Frecuencia de updates: Cada 2-3 meses. Revisar changelog en GitHub antes de actualizar.
¿NPM funciona detrás de Cloudflare?
Sí, perfectamente. Configuración recomendada:
En Cloudflare DNS:
- ☁️ Proxy activado (naranja) para servicios públicos
- ☁️ DNS only (gris) si usas NPM Access Lists (IP whitelisting no funciona con Cloudflare proxy)
En NPM, obtener IP real del visitante:
# Custom Config:
set_real_ip_from 173.245.48.0/20; # Cloudflare IP ranges
set_real_ip_from 103.21.244.0/22;
real_ip_header CF-Connecting-IP;
Ventaja: DDoS protection de Cloudflare + reverse proxy de NPM = doble capa de seguridad.
¿Cómo limito acceso por geolocalización?
NPM no tiene GeoIP built-in, pero puedes usar Cloudflare WAF rules O añadir módulo GeoIP a Nginx:
# Requiere compilar Nginx con módulo GeoIP (avanzado)
# Alternativa: Usar Cloudflare Firewall Rules (más fácil)
# Cloudflare Rule:
# If Country != Spain → Block
—
Conclusión
Nginx Proxy Manager democratiza el poder de Nginx, haciéndolo accesible para cualquier persona con un homelab. Lo que antes requería horas de lectura de documentación y edición de archivos .conf, ahora son formularios simples en una UI elegante.
Resumen de ventajas:
✅ SSL automático con Let’s Encrypt (renovación incluida)
✅ UI web completa (no necesitas saber sintaxis Nginx)
✅ Wildcard certificates con wizard para DNS providers
✅ Access Lists para autenticación centralizada
✅ Backup/Restore con un click
✅ Logs visuales con búsqueda y filtros
✅ Streams para TCP/UDP (SSH, bases de datos, etc.)
Próximos pasos recomendados:
- Instala NPM con el Docker Compose de este tutorial
- Configura tu primer proxy host (Portainer es ideal para empezar)
- Obtén certificado wildcard de Cloudflare para todos tus subdominios
- Protege el admin panel (solo localhost o VPN)
- Automatiza backups con cron job diario
- Explora Access Lists para servicios sensibles
Con Nginx Proxy Manager, tu homelab pasa de amateur a profesional en una tarde. La simplicidad no significa sacrificar potencia: debajo de la UI sigue siendo Nginx battle-tested, el mismo que usa Netflix, Cloudflare y millones de sitios de producción.
¿Listo para simplificar tu reverse proxy? 🚀
—Recursos Adicionales:
- Documentación Oficial: https://nginxproxymanager.com/guide/
- GitHub Repository: https://github.com/NginxProxyManager/nginx-proxy-manager
- Community Forum: https://github.com/NginxProxyManager/nginx-proxy-manager/discussions
- Docker Hub: https://hub.docker.com/r/jc21/nginx-proxy-manager
- Let’s Encrypt Docs: https://letsencrypt.org/docs/
