🚀 Nginx Proxy Manager: Tu Reverse Proxy con SSL Automático en 10 Minutos
¿Tienes varios servicios corriendo en Docker (WordPress, Nextcloud, Jellyfin, Home Assistant…) y quieres acceder a todos con nombres bonitos y HTTPS sin volverte loco editando archivos de configuración de Nginx? Nginx Proxy Manager es la solución que estabas buscando.
Es una interfaz web súper sencilla que te permite gestionar proxy hosts, obtener certificados SSL gratis de Let’s Encrypt automáticamente, y proteger tus servicios con listas de acceso. Todo sin tocar ni una línea de configuración de Nginx a mano.
📋 ¿Qué es Nginx Proxy Manager y por qué lo necesitas?
Nginx Proxy Manager (NPM) es un contenedor Docker que envuelve Nginx con una interfaz web moderna y fácil de usar. Te permite:
- Crear proxy hosts: Redirige tráfico de un dominio (ej: blog.miservidor.com) a un contenedor interno (ej: WordPress en puerto 8080)
- SSL gratis y automático: Obtén certificados Let’s Encrypt con un clic, renovación automática incluida
- Wildcard certificates: Un solo certificado para todos tus subdominios (*.miservidor.com)
- Listas de acceso: Protege servicios con autenticación HTTP o restricciones por IP
- Streams TCP/UDP: Proxy para servicios no-HTTP como bases de datos o servidores de juegos
Ventaja principal: No necesitas ser experto en Nginx. Si sabes hacer clic, puedes configurarlo.
🔧 Requisitos previos
Antes de empezar necesitas:
- Docker y Docker Compose instalados en tu servidor (Linux, Raspberry Pi, Synology…)
- Puertos 80, 81 y 443 libres:
- Puerto 80: HTTP (redirecciones a HTTPS)
- Puerto 81: Interfaz de administración de NPM
- Puerto 443: HTTPS (tráfico SSL)
- Un dominio propio (puedes usar uno gratis de DuckDNS, No-IP, Cloudflare, etc.)
- Puertos 80 y 443 abiertos en tu router si quieres acceso desde internet (port forwarding a tu servidor)
Nota: Si solo quieres usar NPM en tu red local con certificados auto-firmados, no necesitas abrir puertos ni dominio público.
⚡ Instalación en 3 pasos
Paso 1: Crear estructura de directorios
mkdir -p ~/nginx-proxy-manager/{data,letsencrypt}
cd ~/nginx-proxy-manager
Paso 2: Crear docker-compose.yml
Crea el archivo con tu editor favorito:
nano docker-compose.yml
Y pega esta configuración básica:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80' # HTTP
- '81:81' # Interfaz admin
- '443:443' # HTTPS
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
environment:
# Opcional: cambiar zona horaria
- TZ=Europe/Madrid
Paso 3: Levantar el contenedor
docker compose up -d
Espera unos 30 segundos mientras se genera la entropía de las claves. Luego abre tu navegador:
http://IP_DE_TU_SERVIDOR:81
Login inicial:
- Email:
admin@example.com - Password:
changeme
🔒 Inmediatamente después del primer login te pedirá cambiar email y contraseña. Hazlo YA.
🎯 Configuración con base de datos MariaDB (producción)
Para entornos de producción o si gestionas muchos proxy hosts, es mejor usar una base de datos externa en lugar de SQLite:
version: '3.8'
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: nginx-proxy-manager
restart: unless-stopped
ports:
- '80:80'
- '81:81'
- '443:443'
environment:
DB_MYSQL_HOST: "db"
DB_MYSQL_PORT: 3306
DB_MYSQL_USER: "npm"
DB_MYSQL_PASSWORD: "npm_password_super_segura"
DB_MYSQL_NAME: "npm"
TZ: "Europe/Madrid"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
depends_on:
- db
db:
image: 'jc21/mariadb-aria:latest'
container_name: nginx-proxy-manager-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: "root_password_super_segura"
MYSQL_DATABASE: "npm"
MYSQL_USER: "npm"
MYSQL_PASSWORD: "npm_password_super_segura"
TZ: "Europe/Madrid"
volumes:
- ./mysql:/var/lib/mysql
Recuerda cambiar las contraseñas antes de levantar:
docker compose down
docker compose up -d
🌐 Crear tu primer Proxy Host
Ejemplo: tienes WordPress corriendo en el puerto 8080 de tu servidor y quieres acceder con blog.tudominio.com.
1. Configurar DNS
En tu proveedor de dominio (Cloudflare, Namecheap, DuckDNS…), crea un registro A apuntando a la IP pública de tu servidor:
blog.tudominio.com → A → TU_IP_PUBLICA
2. Crear Proxy Host en NPM
En la interfaz de NPM (puerto 81):
- Ve a Hosts → Proxy Hosts
- Clic en Add Proxy Host
- Rellena:
- Domain Names:
blog.tudominio.com - Scheme:
http(o https si WordPress ya tiene SSL interno) - Forward Hostname/IP:
wordpress(nombre del contenedor) o192.168.1.100(IP interna) - Forward Port:
8080 - ✅ Block Common Exploits
- ✅ Websockets Support (si tu app lo necesita)
- Domain Names:
- Ve a la pestaña SSL
- Selecciona Request a new SSL Certificate
- ✅ Force SSL (redirige HTTP → HTTPS)
- ✅ HTTP/2 Support
- Acepta los términos de Let’s Encrypt
- Clic en Save
NPM solicitará el certificado a Let’s Encrypt automáticamente (tarda 10-30 segundos). Una vez completado, tu WordPress estará accesible en https://blog.tudominio.com con SSL válido. 🎉
🔐 Certificados Wildcard con DNS Challenge (Cloudflare)
Si quieres un solo certificado para todos tus subdominios (*.tudominio.com), necesitas usar DNS Challenge:
1. Obtener API Token de Cloudflare
- Entra en Cloudflare Dashboard
- Ve a My Profile → API Tokens
- Clic en Create Token
- Usa la plantilla Edit zone DNS
- Permissions:
- Zone → DNS → Edit
- Zone → Zone → Read
- Zone Resources: Include → Specific zone → tudominio.com
- Copia el token generado (solo se muestra una vez)
2. Crear certificado Wildcard en NPM
- Ve a SSL Certificates en NPM
- Clic en Add SSL Certificate → Let’s Encrypt
- Domain Names:
*.tudominio.comytudominio.com(añade ambos) - Email: tu email
- ✅ Use a DNS Challenge
- DNS Provider: Cloudflare
- Credentials File Content:
dns_cloudflare_api_token = TU_TOKEN_AQUI
Clic en Save. NPM validará vía DNS y obtendrá el certificado. Ahora puedes usarlo en todos tus proxy hosts sin solicitar uno nuevo por cada subdominio.
🛡️ Listas de Acceso: Protege tus servicios
Las Access Lists te permiten restringir quién puede acceder a tus servicios.
Crear lista de acceso con autenticación HTTP
- Ve a Access Lists
- Clic en Add Access List
- Name:
Solo admins - En la pestaña Authorization, añade usuarios:
Username: admin
Password: contraseña_segura
Puedes añadir múltiples usuarios. Clic en Save.
Aplicar lista a un Proxy Host
- Edita tu Proxy Host
- En la pestaña Details, sección Access List
- Selecciona Solo admins
- Save
Ahora, al acceder a ese servicio, el navegador pedirá usuario y contraseña antes de mostrar el contenido.
Restricción por IP
También puedes permitir/denegar acceso por IPs:
- En la Access List, pestaña Access
- Mode: Allow o Deny
- Añade direcciones IP:
- IP única:
192.168.1.50 - Rango:
192.168.1.1-192.168.1.100 - Wildcard:
192.168.1.* - CIDR:
192.168.1.0/24
- IP única:
Ejemplo: Solo permitir acceso desde tu red local (192.168.1.0/24) a tu panel de administración.
🚀 Configuración avanzada: Custom Locations
Si necesitas configuraciones específicas para rutas dentro de un proxy host, usa Custom Locations:
Ejemplo: tienes una API en /api que debe ir a otro contenedor:
- En tu Proxy Host, pestaña Custom Locations
- Clic en Add Location
- Define location:
- Location:
/api - Scheme:
http - Forward Hostname/IP:
api-backend - Forward Port:
3000
- Location:
Ahora https://tudominio.com/api se redirige al backend API mientras el resto va a tu frontend.
⚙️ Streams: Proxy para servicios TCP/UDP
NPM también puede hacer proxy de protocolos no-HTTP (bases de datos, SSH, juegos):
- Ve a Streams
- Clic en Add Stream
- Configura:
- Incoming Port:
3306(puerto externo) - Forwarding Host:
mysql-server - Forwarding Port:
3306 - TCP/UDP: TCP
- Incoming Port:
Ahora puedes conectarte a tu MySQL desde fuera usando el puerto 3306 de tu servidor NPM.
🔒 Asegurar la interfaz de administración (puerto 81)
Por defecto, la interfaz de admin está en el puerto 81 sin SSL. Mejoras recomendadas:
1. Cambiar puerto de admin
Edita docker-compose.yml:
ports:
- '8181:81' # Cambiar 81 por otro puerto menos obvio
docker compose up -d
2. Crear Proxy Host para el admin con SSL
- Crea subdominio DNS:
admin.tudominio.com → IP_SERVIDOR - En NPM, crea Proxy Host:
- Domain:
admin.tudominio.com - Forward to:
localhost:81(o el puerto que pusiste) - SSL: Request certificate con Let’s Encrypt
- Access List: Crea una lista solo para ti
- Domain:
Ahora accedes al admin en https://admin.tudominio.com con SSL y autenticación adicional.
3. Bloquear acceso externo al puerto 81
Si solo accedes desde tu red local, bloquea el puerto en el firewall:
sudo ufw deny 81/tcp
🐛 Troubleshooting: Problemas comunes
❌ Error: «This site can’t provide a secure connection»
Causa: El certificado SSL no se generó correctamente.
Soluciones:
- Verifica que el puerto 80 esté abierto en tu router (Let’s Encrypt valida por HTTP)
- Comprueba que el DNS apunte correctamente a tu IP pública
- Revisa los logs:
docker logs nginx-proxy-manager - Intenta borrar el certificado fallido y recrearlo
- Si usas DNS Challenge, verifica que el API token de Cloudflare sea correcto
❌ Error 502 Bad Gateway
Causa: NPM no puede conectar con el servicio backend.
Soluciones:
- Verifica que el contenedor backend esté corriendo:
docker ps - Si usas nombres de contenedor, asegúrate de que estén en la misma red Docker
- Prueba usar la IP interna del host en lugar del nombre:
172.17.0.1o192.168.1.X - Revisa que el puerto sea correcto (8080 vs 80, por ejemplo)
❌ Websockets no funcionan
Solución: Activa Websockets Support en la configuración del Proxy Host (pestaña Details).
❌ No puedo acceder a la interfaz admin (puerto 81)
Soluciones:
- Verifica que el contenedor esté corriendo:
docker ps - Comprueba que el puerto no esté ocupado:
sudo netstat -tlnp | grep 81 - Revisa los logs:
docker logs nginx-proxy-manager - Intenta acceder con la IP del servidor en lugar de localhost
📊 Comparativa: Nginx Proxy Manager vs Alternativas
| Característica | Nginx Proxy Manager | Traefik | Caddy | Nginx manual |
|---|---|---|---|---|
| Interfaz web | ✅ Sí, muy amigable | ✅ Dashboard básico | ❌ Solo CLI/archivos | ❌ Solo archivos |
| SSL automático | ✅ Let’s Encrypt 1 clic | ✅ Automático vía labels | ✅ Automático | ❌ Manual con certbot |
| Curva aprendizaje | ⭐⭐ Muy fácil | ⭐⭐⭐⭐ Media-alta | ⭐⭐⭐ Media | ⭐⭐⭐⭐⭐ Alta |
| Config as code | ❌ Solo GUI | ✅ Labels Docker | ✅ Caddyfile | ✅ nginx.conf |
| Listas de acceso | ✅ GUI integrada | ✅ Middlewares | ⚠️ Plugins | ✅ Manual |
| Wildcard SSL | ✅ DNS Challenge | ✅ DNS Challenge | ✅ DNS Challenge | ✅ Manual certbot |
| Performance | ⭐⭐⭐⭐ Muy buena | ⭐⭐⭐⭐ Muy buena | ⭐⭐⭐⭐⭐ Excelente | ⭐⭐⭐⭐⭐ Excelente |
| Mejor para | Homelabs, principiantes | K8s, entornos grandes | Configs simples | Expertos, control total |
💡 Tips y buenas prácticas
- Backups regulares: Respalda las carpetas
./datay./letsencryptantes de actualizar - Usa DNS Challenge para wildcard: Evitas solicitar un certificado por cada subdominio (límite 50/semana de Let’s Encrypt)
- Protege servicios sensibles: Usa Access Lists en servicios administrativos (Portainer, PHPMyAdmin, etc.)
- Monitoriza los logs:
docker logs -f nginx-proxy-managerpara detectar problemas - No expongas el puerto 81 a internet: Accede solo desde red local o vía VPN
- Usa HTTP/2: Actívalo en los certificados SSL para mejor rendimiento
- Actualiza regularmente:
docker compose pull && docker compose up -d
🔄 Actualizar Nginx Proxy Manager
cd ~/nginx-proxy-manager
docker compose pull
docker compose up -d
NPM mantiene tu configuración en los volúmenes, así que no perderás nada al actualizar.
❓ FAQs sobre Nginx Proxy Manager
¿Puedo usar NPM sin dominio propio?
Sí, puedes usarlo en tu red local con IPs o nombres de host (ej: http://192.168.1.100), pero no podrás obtener certificados SSL de Let’s Encrypt sin un dominio público. Alternativa: usa servicios gratuitos como DuckDNS, No-IP o FreeDNS para obtener un dominio gratis (ej: miservidor.duckdns.org).
¿Cómo renueva NPM los certificados SSL?
NPM renueva automáticamente los certificados de Let’s Encrypt ~30 días antes de que expiren. No tienes que hacer nada manualmente. Puedes ver el estado de renovación en SSL Certificates (columna «Expires»).
¿Puedo usar NPM con Docker Swarm o Kubernetes?
NPM está diseñado para entornos simples con Docker Compose. Para Swarm o K8s, es mejor usar Traefik o Nginx Ingress Controller que tienen mejor integración con orchestrators.
¿Qué pasa si dos servicios escuchan en el mismo puerto interno?
No hay problema. NPM diferencia por el dominio (ej: blog.tudominio.com vs cloud.tudominio.com), no por el puerto. Ambos pueden estar en el puerto 80 interno de sus contenedores, NPM se encarga del enrutamiento basándose en el nombre de dominio.
¿Puedo usar certificados SSL propios en lugar de Let’s Encrypt?
Sí, en SSL Certificates → Add SSL Certificate → Custom, puedes subir tus propios archivos .crt y .key. Útil para certificados comerciales o auto-firmados para desarrollo.
¿NPM funciona en Raspberry Pi?
Sí, la imagen Docker oficial jc21/nginx-proxy-manager:latest soporta arquitectura ARM (Raspberry Pi 3/4/5). Funciona perfectamente para homelabs pequeños.
¿Cómo limito el rate de peticiones para evitar ataques?
En el Proxy Host, pestaña Advanced, añade directivas personalizadas de Nginx:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=10r/s;
limit_req zone=mylimit burst=20 nodelay;
Esto limita cada IP a 10 peticiones/segundo con un burst de 20.
¿Puedo usar NPM con IPv6?
Sí, NPM soporta IPv6. Asegúrate de que tu servidor tenga una dirección IPv6 configurada y añade un registro AAAA en tu DNS apuntando a esa IPv6.
¿Qué logs genera NPM y dónde están?
Los logs están en ./data/logs/ dentro del volumen. Para ver en tiempo real:
docker logs -f nginx-proxy-manager
Logs de proxy hosts individuales: ./data/logs/proxy-host-*.log
¿Cómo migro mi configuración a otro servidor?
Simplemente copia las carpetas ./data y ./letsencrypt al nuevo servidor, levanta NPM con el mismo docker-compose.yml, y todo funcionará igual. No olvides actualizar tu DNS si la IP cambió.
¿Puedo usar NPM detrás de otro proxy (doble proxy)?
Sí, pero debes configurar correctamente los headers X-Forwarded-For y X-Real-IP en ambos proxies para que las IPs reales de los clientes se preserven. En NPM, activa Websockets Support si tu aplicación lo necesita.
¿NPM es compatible con Cloudflare Proxy (nube naranja)?
Sí, funciona perfectamente. Si activas el proxy de Cloudflare (nube naranja en el DNS), el tráfico pasa por los servidores de CF antes de llegar a NPM. Ventajas: DDoS protection, caching, CDN. Importante: en NPM, usa el certificado SSL de Let’s Encrypt normalmente (modo «Full SSL» en Cloudflare).
🎸 Resumen punk
Nginx Proxy Manager es la herramienta que necesitas para dejar de pelearte con archivos de configuración de Nginx y empezar a disfrutar de SSL automático, proxy hosts en segundos, y listas de acceso sin dramas.
Instálalo en 10 minutos, configura tus servicios con clics, y olvídate de renovar certificados manualmente. Perfecto para homelabs, servidores caseros, o cualquier entorno donde quieras simplicidad sin sacrificar funcionalidad.
Si tienes problemas, revisa los logs, consulta la documentación oficial, y no dudes en preguntar en la comunidad. ¡A proxear servicios! 🚀
