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:

TareaNginx TradicionalNginx Proxy Manager
Añadir proxy hostEditar /etc/nginx/sites-available/, crear symlink, nginx -t, nginx -s reloadFormulario en UI, click «Save»
Certificado SSLcertbot certonly --nginx -d domain.com, editar config, test, reloadClick «Request SSL», esperar 30 seg, listo
Renovar certificadoCron job + script + esperanzaAutomático cada 60 días
Ver logstail -f /var/log/nginx/access.logUI con búsqueda y filtros
Backup configCopiar manualmente todos los .confExport JSON en UI

Casos de uso perfectos:

  1. Homelabs con 5-50 servicios (Portainer, Nextcloud, Home Assistant, n8n, Jellyfin)
  2. No quieres ser experto en Nginx (curva de aprendizaje reducida 90%)
  3. SSL automático es crítico (Let’s Encrypt con renovación sin intervención)
  4. Múltiples subdominios (portainer.home.lan, n8n.home.lan, grafana.home.lan)
  5. 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ísticaNPMTraefikCaddy
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 ParaPrincipiantes, UI loversDevOps, auto-scalingMinimalistas

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

  1. Cambiar credenciales admin (obligatorio)
  2. Deshabilitar Dark Mode (opcional, según preferencia)
  3. 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.lan a IP del servidor NPM
  • (Para SSL público) Dominio real apuntando a tu IP pública

Paso 1: Añadir Proxy Host

  1. En NPM UI, ir a Hosts → Proxy Hosts
  2. Click Add Proxy Host
  3. 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)
  1. Click Save

Resultado: Portainer accesible en http://portainer.home.lan (HTTP por ahora)

Paso 2: Añadir SSL Automático

  1. Editar el proxy host recién creado
  2. 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: ☑
  1. 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

  1. Dominio en Cloudflare (o otro DNS provider soportado)
  2. API Token de Cloudflare con permisos:

– Zone: Read

– DNS: Edit

Paso 1: Crear API Token en Cloudflare

  1. Login en Cloudflare → My Profile → API Tokens
  2. Create Token → «Edit zone DNS» template
  3. Zone Resources: Include → Specific zone → tudominio.com
  4. Continue → Create Token
  5. Copiar token (solo se muestra una vez)

Paso 2: Configurar en NPM

  1. NPM UI → SSL Certificates → Add SSL Certificate
  2. Tipo: Let’s Encrypt + DNS Challenge
  3. 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)
  1. 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

  1. NPM UI → Access Lists → Add Access List
  2. 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)
  1. Save

Paso 2: Asignar a Proxy Host

  1. Editar proxy host de n8n
  2. Details tab:
Access List: Admin Users (select)
  1. 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

  1. NPM UI → Streams → Add Stream
  2. 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.comnew-domain.com

Configuración

  1. NPM UI → Hosts → Redirection Hosts → Add
  2. 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/posthttps://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:

  1. /data/database.sqlite – Toda la configuración
  2. /letsencrypt/ – Certificados SSL
  3. 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:

  1. Crear proxy host principal: app.com → Frontend
  2. 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):

  1. Proxy Hosts → Click en host → Access Log tab
  2. Ver requests en tiempo real con:

– IP origen

– URL solicitada

– Status code

– User agent

– Timestamp

Error Logs:

  1. Ver errores de Nginx específicos del host
  2. Ú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):

  1. Documentar config actual de Traefik:

– Listar todos los servicios con labels

– Anotar dominios, puertos, middlewares

  1. Setup NPM con Docker Compose
  1. Recrear proxy hosts en NPM:

– Por cada servicio Traefik, crear proxy host equivalente

– Configurar SSL certificates (wildcard recomendado)

  1. Verificar funcionamiento antes de apagar Traefik
  1. 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:

  1. NPM primario (activo)
  2. NPM secundario (standby)
  3. Script que sincroniza database.sqlite del primario al secundario
  4. 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)

  1. Servidor origen: Settings → Backup → Download Backup
  2. Servidor destino: Settings → Restore → Upload backup JSON
  3. 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:

  1. Instala NPM con el Docker Compose de este tutorial
  2. Configura tu primer proxy host (Portainer es ideal para empezar)
  3. Obtén certificado wildcard de Cloudflare para todos tus subdominios
  4. Protege el admin panel (solo localhost o VPN)
  5. Automatiza backups con cron job diario
  6. 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/

Por ziru

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

El Diario IA
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.