bolt Valebyte VPS desde $4/mes — NVMe, despliegue en 60s.

Obtener VPS arrow_forward
eco Principiante Tutorial/Cómo hacer

Nginx Proxy Manager: SSL y dominios para todos los contenedores en un solo VPS

calendar_month Sep 15, 2026 schedule 20 min de lectura visibility 65 vistas
Nginx Proxy Manager: SSL и домены для всех контейнеров на одном VPS
info

¿Necesitas un servidor para esta guía? Ofrecemos servidores dedicados y VPS en más de 50 países con configuración instantánea.

¿Necesitas un VPS para esta guía?

Explore otras opciones de servidores dedicados en

Nginx Proxy Manager: SSL y dominios para todos los contenedores en un solo VPS

TL;DR

Nginx Proxy Manager permite alojar decenas de contenedores Docker en un solo VPS, asignar a cada uno un dominio o subdominio independiente y emitir automáticamente certificados SSL de Let’s Encrypt sin configurar Nginx manualmente.

  • Una única dirección IP pública atiende varios sitios, API, paneles de administración y servicios self-hosted.
  • Nginx Proxy Manager recibe tráfico HTTP/HTTPS en los puertos 80 y 443 y lo dirige al contenedor correspondiente dentro de la red interna de Docker.
  • Los certificados SSL de Let’s Encrypt se emiten y renuevan automáticamente mediante la interfaz web.
  • El panel de administración de Nginx Proxy Manager no debe dejarse abierto a todo Internet sin protección adicional.
  • Para un conjunto pequeño de servicios, normalmente basta un VPS con 2 vCPU, 2–4 GB de RAM y un disco SSD de 30 GB o más.
  • Los datos críticos —archivos Docker Compose, volúmenes de Nginx Proxy Manager, base de datos SQLite o MariaDB y copias de seguridad de aplicaciones— deben exportarse regularmente fuera del VPS.

Qué configuramos y por qué

Схема: Что мы настраиваем и зачем
Esquema: Qué configuramos y por qué

Un VPS típico se convierte rápidamente en un conjunto de servicios: GitLab o Gitea, Mattermost, Vaultwarden, Nextcloud, Grafana, una página de inicio, API de aplicaciones, entornos de prueba y paneles de monitorización. Cada contenedor suele escuchar en su propio puerto interno: 3000, 8080, 9000, 5000 u otro. Abrir todos estos puertos a Internet resulta incómodo e inseguro.

Nginx Proxy Manager, en adelante NPM, resuelve esta tarea como reverse proxy con interfaz web. Recibe solicitudes en los puertos estándar HTTP 80 y HTTPS 443, determina el dominio a partir de la cabecera Host y redirige el tráfico al contenedor adecuado. Por ejemplo, una solicitud a git.example.com se envía a Gitea, chat.example.com a Mattermost y status.example.com a Uptime Kuma.

Como resultado, para el usuario externo no importa en qué puerto funciona realmente la aplicación. Todos los servicios están disponibles mediante direcciones HTTPS claras, y en el VPS basta con abrir únicamente SSH, HTTP y HTTPS. Los puertos internos de las aplicaciones permanecen cerrados dentro de la red Docker.

Arquitectura final

En esta guía se utilizará la siguiente arquitectura:

  • Un VPS con Ubuntu Server 24.04 LTS.
  • Docker Engine y Docker Compose Plugin.
  • Nginx Proxy Manager en un proyecto Docker Compose independiente.
  • Una red Docker externa compartida proxy.
  • Varias aplicaciones conectadas a esta red.
  • Registros DNS de dominios como app.example.com, que apuntan a la IP del VPS.
  • Let’s Encrypt para certificados TLS gratuitos.

El flujo de la solicitud será el siguiente: el navegador abre https://vault.example.com → DNS devuelve la IP del VPS → NPM recibe la solicitud en el puerto 443 → NPM termina TLS → NPM transmite HTTP al contenedor interno de Vaultwarden a través de la red Docker.

Qué obtendrá después de la configuración

  • Un único punto de entrada para todos los contenedores del servidor.
  • HTTPS para cada dominio sin crear manualmente configuraciones de Nginx.
  • Renovación automática de certificados Let’s Encrypt.
  • Posibilidad de habilitar WebSocket, access list, autenticación básica y redirecciones mediante la UI.
  • Aislamiento de servicios: las aplicaciones no tienen que publicar puertos en la IP del VPS.
  • Una migración de infraestructura más sencilla: la configuración se almacena en archivos Compose y Docker volumes.

Qué alternativas existen

Enfoque Ventajas Limitaciones
Cloud-managed ingress o load balancer Alta disponibilidad, certificados gestionados, menos administración Coste mensual, dependencia de la nube, a menudo excesivo para un solo VPS
Nginx convencional configurado manualmente Máxima flexibilidad, configuraciones conocidas, alto rendimiento Es necesario escribir por cuenta propia configuraciones de virtual host, configurar Certbot y las actualizaciones
Traefik Automatización práctica mediante Docker labels, adecuado para un gran número de servicios La configuración mediante labels y middleware puede ser más compleja para principiantes
Caddy Configuración sencilla, HTTPS automático, Caddyfile compacto Menos gestión visual, algunas tareas requieren trabajo manual con la configuración
Nginx Proxy Manager UI clara, Let’s Encrypt, access lists, proxy hosts sin Nginx manual Panel de administración adicional, es necesario proteger el acceso administrativo

Para un desarrollador individual, un equipo pequeño o el propietario de un VPS, NPM resulta práctico porque no requiere recordar la sintaxis de Nginx al añadir otro servicio. No elimina la necesidad de comprender las redes, DNS y la seguridad, pero reduce considerablemente el número de operaciones manuales.

Nginx Proxy Manager no sustituye a un firewall. Incluso si el servicio solo está disponible a través del proxy, los puertos Docker abiertos pueden eludir las reglas de UFW. Publique los puertos de las aplicaciones solo en 127.0.0.1 o no los publique en absoluto.

Qué configuración de VPS se necesita para esta tarea

Схема: Какой VPS-конфиг нужен под эту задачу
Esquema: Qué configuración de VPS se necesita para esta tarea

El propio Nginx Proxy Manager consume pocos recursos. En un servidor limpio, su contenedor suele requerir unos cientos de megabytes de RAM, y las operaciones TLS cargan notablemente la CPU solo con una gran cantidad de conexiones nuevas. Los recursos deben elegirse principalmente en función de las aplicaciones detrás del proxy: GitLab, Nextcloud, bases de datos, servidores de juegos y CI son mucho más exigentes que NPM.

Escenario CPU RAM Disco Red
NPM + 2–5 servicios ligeros 2 vCPU 2 GB 30 GB SSD 100 Mbit/s
NPM + Nextcloud, Gitea, Mattermost, monitorización 2–4 vCPU 4–8 GB 80–160 GB NVMe 100 Mbit/s o 1 Gbit/s
Muchos usuarios, archivos, CI, bases de datos 4–8 vCPU 8–16 GB 160 GB+ NVMe 1 Gbit/s

Una opción inicial práctica para NPM, Vaultwarden, Uptime Kuma, Gitea y una API pequeña es 2 vCPU, 4 GB de RAM, 60–80 GB NVMe y 1 Gbit/s. Si es necesario, puede elegir un VPS con las características indicadas o un plan similar de otro proveedor. Más importante que el nombre del plan es disponer de IPv4 público dedicado, una red estable, acceso por SSH y la posibilidad de crear snapshots.

Por qué se necesita una IP pública

Para la verificación HTTP-01 estándar de Let’s Encrypt, el servidor debe ser accesible desde el exterior por el puerto 80. Si el VPS se encuentra detrás de CGNAT o dispone solo de una IP privada, la emisión automática de certificados mediante la verificación HTTP habitual no funcionará. En ese caso se necesita un IPv4 público, IPv6 público con DNS configurado correctamente o DNS-01 challenge mediante el proveedor de DNS.

Cuándo se necesita un dedicated en lugar de un VPS

Para un único reverse proxy no se necesita un servidor dedicated. Se justifica cuando detrás del proxy funcionan servicios exigentes: un GitLab grande con CI-runner, una nube de archivos con terabytes de datos, transcodificación de vídeo, una base de datos de alta carga, decenas de miles de solicitudes por segundo o requisitos de rendimiento predecible del disco.

También conviene considerar un dedicated con alto tráfico de red, una gran cantidad de conexiones TLS simultáneas, requisitos de varios discos físicos en RAID y cuando la virtualización con otros clientes en un VPS no es aceptable según la política de seguridad. Para 5–30 servicios internos de un equipo pequeño, normalmente basta un VPS de calidad.

Cómo elegir la ubicación

La ubicación del VPS afecta a la latencia, los requisitos legales y la velocidad de carga inicial. Si la audiencia principal se encuentra en Europa, elija un centro de datos europeo; si los usuarios están en Kazajistán, Rusia, Turquía o Oriente Medio, mida previamente el ping hacia varias ubicaciones. Para los paneles de administración, la diferencia entre 20 y 60 ms apenas se nota, pero para juegos, servicios de voz, API y almacenamiento de archivos es más importante.

No ubique el servidor solo según la cercanía a usted si el servicio lo utiliza un equipo de otro país. Compruebe también si los puertos necesarios están permitidos, si hay reverse DNS para servicios de correo cuando sea necesario y si hay almacenamientos de copia de seguridad disponibles en otra ubicación.

Preparación del servidor

A continuación se asume un servidor nuevo con Ubuntu Server 24.04 LTS e inicio de sesión como usuario root. Si utiliza Debian 12 o Debian 13, la lógica sigue siendo la misma, pero algunos comandos de instalación de paquetes pueden diferir. Antes de configurar los dominios, cree registros A: por ejemplo, npm.example.com, vault.example.com y status.example.com deben apuntar al IPv4 público del servidor.

Actualice el sistema y cree un administrador

Realice la configuración inicial mediante SSH. En lugar de admin, indique su propio nombre de usuario y, en lugar del ejemplo de clave pública, inserte la clave del archivo ~/.ssh/id_ed25519.pub en el equipo local.

apt update && apt upgrade -y
apt install -y sudo curl ca-certificates gnupg fail2ban ufw vim git
adduser admin
usermod -aG sudo admin

El comando actualiza el sistema, instala utilidades básicas, Fail2ban y UFW, y luego crea un usuario con privilegios sudo.

install -d -m 700 -o admin -g admin /home/admin/.ssh
nano /home/admin/.ssh/authorized_keys
chmod 600 /home/admin/.ssh/authorized_keys
chown admin:admin /home/admin/.ssh/authorized_keys

Este bloque crea el directorio SSH y añade la clave pública. Pegue la clave en una sola línea, guarde el archivo y no cierre la sesión actual de root hasta comprobar el nuevo acceso.

ssh -i ~/.ssh/id_ed25519 admin@SERVER_IP

El comando comprueba que el nuevo usuario realmente puede conectarse con la clave. Abra una ventana de terminal independiente y asegúrese de que el inicio de sesión se realiza sin contraseña.

Desactive el acceso SSH mediante contraseña

Después de una comprobación correcta, edite un archivo de configuración SSH independiente. Es más seguro que modificar el archivo principal /etc/ssh/sshd_config, que puede actualizarse mediante el gestor de paquetes.

sudo nano /etc/ssh/sshd_config.d/99-hardening.conf

Añada los siguientes parámetros:

PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
X11Forwarding no
MaxAuthTries 3
sudo sshd -t && sudo systemctl restart ssh

El comando comprueba la sintaxis de la configuración y solo después reinicia SSH. Si la comprobación devuelve un error, no reinicie el servicio hasta corregir el archivo.

Configure el firewall y Fail2ban

NPM debe recibir conexiones externas en los puertos 80 y 443. Es recomendable limitar SSH a la dirección IP de la oficina o de la VPN doméstica, pero para la primera puesta en marcha puede dejar temporalmente el acceso desde cualquier IP. Docker tiene particularidades al interactuar con UFW, por lo que la principal protección de los contenedores es no publicar sus puertos hacia el exterior.

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Los comandos bloquean el tráfico entrante de forma predeterminada y permiten únicamente SSH, HTTP y HTTPS. Más adelante puede añadir una restricción de SSH por IP de origen o trasladar el acceso al panel de NPM detrás de una VPN.

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

Este bloque inicia Fail2ban y muestra el estado de la jail de SSH. Fail2ban reduce el efecto de los intentos de descifrado de contraseñas, pero no sustituye las claves SSH, las actualizaciones ni la restricción de acceso.

Compruebe el DNS antes de emitir el certificado

El certificado Let’s Encrypt no se emitirá hasta que el registro DNS apunte al servidor actual. Compruebe el registro desde el VPS y, preferiblemente, mediante resolutores DNS externos.

getent hosts npm.example.com
curl -4 ifconfig.me
dig +short npm.example.com A @1.1.1.1

La IP devuelta por DNS debe coincidir con el IPv4 público del VPS. Si el DNS aún se está propagando, espere al TTL del registro. No cree decenas de solicitudes fallidas de certificado: Let’s Encrypt aplica rate limits.

Instalación del software — paso a paso

Схема: Установка ПО — пошагово
Esquema: Instalación del software — paso a paso

Para Nginx Proxy Manager, utilice Docker Engine del repositorio oficial de Docker, no el paquete obsoleto docker.io del repositorio estándar de Ubuntu. En 2026, la rama actual Docker Engine 29 es compatible con Compose Plugin; compruebe el número de versión menor específico en la documentación oficial de Docker antes de instalarlo.

Instale Docker Engine y Compose Plugin

sudo apt remove -y docker.io docker-compose docker-compose-v2 podman-docker containerd runc || true
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Los comandos eliminan paquetes antiguos en conflicto y añaden la clave GPG del repositorio oficial de Docker.

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Este bloque añade el repositorio e instala Docker Engine, containerd, Buildx y el moderno Compose Plugin.

sudo usermod -aG docker admin
newgrp docker
docker version
docker compose version

El comando añade el usuario al grupo Docker y muestra las versiones de Docker y Compose. Tenga en cuenta que la pertenencia al grupo docker concede de facto privilegios de nivel root. No añada usuarios normales de aplicaciones a este grupo.

Cree una red Docker compartida

Los contenedores a los que NPM debe acceder mediante el DNS interno de Docker se conectarán a una misma red externa. Esto es mejor que reenviar los puertos de cada aplicación a la interfaz pública del servidor.

docker network create proxy
docker network inspect proxy

Los comandos crean la red bridge proxy y muestran sus parámetros. En el futuro, NPM podrá acceder al contenedor por el nombre del servicio, por ejemplo, vaultwarden o uptime-kuma.

Cree el directorio de Nginx Proxy Manager

mkdir -p ~/stacks/nginx-proxy-manager
cd ~/stacks/nginx-proxy-manager
mkdir -p data letsencrypt
chmod 700 data letsencrypt

Este bloque crea el directorio de trabajo y los directorios persistentes. En data, NPM almacena la configuración y la base de datos SQLite; en letsencrypt, los certificados y los datos ACME.

Prepare el archivo Compose

Para un VPS pequeño puede utilizar la base de datos SQLite integrada. Esto minimiza el número de contenedores y es suficiente para una única instancia de NPM. En instalaciones grandes y cuando se requieren redundancias, normalmente se utiliza MariaDB, pero para un único reverse proxy SQLite es más sencillo de mantener.

nano compose.yml

Inserte la configuración con la imagen fijada de NPM de la rama 2.12.3. Antes de un nuevo despliegue, revise GitHub Releases del proyecto y el changelog: no sustituya la etiqueta estable por latest sin realizar pruebas.

services:
  npm:
    image: jc21/nginx-proxy-manager:2.12.3
    container_name: nginx-proxy-manager
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "127.0.0.1:81:81"
    environment:
      TZ: "Europe/Berlin"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - proxy

networks:
  proxy:
    external: true

Los puertos 80 y 443 se publican para todo Internet, mientras que el puerto administrativo 81 está vinculado únicamente a 127.0.0.1. Esta es una opción de seguridad importante: el panel no estará disponible directamente mediante http://SERVER_IP:81.

docker compose pull
docker compose up -d
docker compose ps
docker logs --tail=100 nginx-proxy-manager

Los comandos descargan la imagen, inician el stack en segundo plano, muestran el estado del contenedor y los últimos registros. El estado debe ser Up. Si el contenedor se reinicia, revise los registros completos.

Abra el panel administrativo mediante un túnel SSH

Como el puerto 81 solo está disponible localmente en el VPS, cree un túnel desde el equipo de trabajo. El comando se ejecuta en su equipo local, no en el servidor.

ssh -L 8181:127.0.0.1:81 admin@SERVER_IP

Mientras la sesión SSH esté abierta, acceda en el navegador a http://127.0.0.1:8181. Para el primer inicio de sesión, utilice los datos estándar de NPM: email [email protected], contraseña changeme. Inmediatamente después de iniciar sesión, la interfaz le pedirá cambiar el email y la contraseña.

No publique el puerto 81 mediante 81:81 salvo que exista una necesidad estricta. Incluso con una contraseña robusta, el panel de administración no debe ser una superficie adicional de ataque público.

Configuración

Diagrama: Configuración
Diagrama: Configuración

Ahora configuraremos un ejemplo con dos aplicaciones: Vaultwarden y Uptime Kuma. Funcionarán sin puertos externos publicados. NPM las verá a través de la red compartida proxy, y los usuarios accederán a ellas mediante los dominios vault.example.com y status.example.com.

Despliegue los contenedores de prueba

Cree un proyecto Compose independiente. No guarde secretos en el código fuente ni los publique en Git. Para Vaultwarden, utilice un archivo .env con permisos solo para el propietario.

mkdir -p ~/stacks/apps
cd ~/stacks/apps
nano .env
chmod 600 .env

Agregue una contraseña aleatoria larga al archivo .env. Puede generarla con el comando openssl rand -base64 48.

VAULTWARDEN_ADMIN_TOKEN=replace_with_a_long_random_secret
TZ=Europe/Berlin
nano compose.yml
services:
  vaultwarden:
    image: vaultwarden/server:1.34.3
    container_name: vaultwarden
    restart: unless-stopped
    environment:
      DOMAIN: "https://vault.example.com"
      WEBSOCKET_ENABLED: "true"
      ADMIN_TOKEN: "${VAULTWARDEN_ADMIN_TOKEN}"
      TZ: "${TZ}"
      SIGNUPS_ALLOWED: "false"
    volumes:
      - ./vaultwarden-data:/data
    networks:
      - proxy

  uptime-kuma:
    image: louislam/uptime-kuma:1.23.16
    container_name: uptime-kuma
    restart: unless-stopped
    volumes:
      - ./uptime-kuma-data:/app/data
    networks:
      - proxy

networks:
  proxy:
    external: true

En este ejemplo no hay una sección ports. Los contenedores solo son accesibles para sus vecinos en la red proxy. Si una aplicación necesita acceso a una base de datos, conecte también la base a una red interna independiente y no publique su puerto 3306, 5432 o 6379 hacia el exterior.

docker compose up -d
docker compose ps
docker network inspect proxy

Los comandos inician las aplicaciones y verifican que los contenedores estén conectados a la red. En la salida de docker network inspect proxy deben aparecer nginx-proxy-manager, vaultwarden y uptime-kuma.

Compruebe la conectividad interna

Antes de crear un proxy host, asegúrese de que NPM vea los contenedores de destino. Dentro del contenedor NPM puede realizar una solicitud HTTP mediante el nombre DNS de Docker. Vaultwarden utiliza el puerto 80 de forma predeterminada y Uptime Kuma el 3001.

docker exec nginx-proxy-manager curl -I http://vaultwarden:80
docker exec nginx-proxy-manager curl -I http://uptime-kuma:3001

Para Vaultwarden se espera una respuesta HTTP como 200, 301 o 302. Para Uptime Kuma también se admite una respuesta de redirección. El error Could not resolve host significa que el contenedor no está conectado a la red proxy.

Cree un Proxy Host para Vaultwarden

Abra un túnel SSH hacia el panel, vaya a Hosts → Proxy Hosts → Add Proxy Host y complete los campos:

  • Domain Names: vault.example.com
  • Scheme: http
  • Forward Hostname / IP: vaultwarden
  • Forward Port: 80
  • Cache Assets: desactivado para el primer inicio
  • Block Common Exploits: activado
  • Websockets Support: activado

En la pestaña SSL, seleccione Request a new SSL Certificate, indique un email para Let’s Encrypt, active Force SSL, HTTP/2 Support y acepte los términos de Let’s Encrypt. Luego guarde la entrada.

Para el desafío HTTP-01, el dominio debe apuntar al VPS y el puerto entrante 80 debe estar disponible. NPM utiliza por sí mismo una lógica ACME integrada, similar a Certbot: no es necesario ni posible instalar manualmente Certbot o Caddy sobre NPM, porque competirán por los puertos 80 y 443.

Cree un Proxy Host para Uptime Kuma

Agregue un segundo host de forma similar, pero con otros valores:

  • Domain Names: status.example.com
  • Scheme: http
  • Forward Hostname / IP: uptime-kuma
  • Forward Port: 3001
  • Websockets Support: activado
  • Block Common Exploits: activado

En la pestaña SSL, solicite de nuevo un certificado independiente. Puede emitir un certificado para varios dominios, pero los certificados independientes son más fáciles de mantener y más seguros desde el punto de vista del aislamiento. Un certificado wildcard requerirá un desafío DNS-01 y la API del proveedor DNS.

Configure una access list para los paneles internos

No todos los servicios deben estar disponibles para todos los usuarios. Por ejemplo, es mejor proteger con Basic Auth y, si es posible, con una lista de IP permitidas un panel de administración, Grafana, Portainer o una API de prueba. En NPM, vaya a Access Lists → Add Access List, cree la lista admins-only, agregue un usuario con una contraseña larga e indique las redes CIDR permitidas en la pestaña Access.

Después, seleccione la lista creada en la configuración del Proxy Host correspondiente. Basic Auth es una capa adicional, no un sustituto de la autenticación de la propia aplicación. Para paneles críticos, es mejor utilizar WireGuard, Tailscale o un túnel SSH.

Parámetros adicionales del proxy host

Algunas aplicaciones requieren transmitir la IP real del cliente, un límite de carga mayor o tiempos de espera prolongados. NPM ya agrega los proxy headers estándar, pero en el campo Advanced puede añadir directivas seguras para un host específico:

client_max_body_size 2g;
proxy_connect_timeout 60s;
proxy_send_timeout 3600s;
proxy_read_timeout 3600s;
send_timeout 3600s;

Este ejemplo es necesario para cargar archivos grandes en Nextcloud o un servicio similar. No inserte directivas aleatorias de foros en la configuración global: un error de sintaxis puede romper la generación de configuraciones de Nginx para todos los dominios.

Compruebe HTTPS y el certificado

curl -I https://vault.example.com
curl -I https://status.example.com
curl -Iv https://vault.example.com 2>&1 | grep -E "SSL certificate verify|subject:|issuer:"

La respuesta debe contener un código HTTP correcto y no debe mostrar un error de verificación TLS. Si utiliza Cloudflare en modo proxy, para el diagnóstico inicial desactive temporalmente el modo proxy del registro o asegúrese de que su modo SSL no entre en conflicto con el certificado de origen.

docker logs --tail=100 nginx-proxy-manager
docker exec nginx-proxy-manager nginx -t

Estos comandos muestran los logs de NPM y comprueban la sintaxis de la configuración de Nginx generada. Ejecútelos después de modificar configuraciones avanzadas complejas o cuando haya errores 502/503.

Copias de seguridad y mantenimiento

Diagrama: Copias de seguridad y mantenimiento
Diagrama: Copias de seguridad y mantenimiento

Nginx Proxy Manager puede recrearse rápidamente, pero sin una copia de seguridad perderá los proxy hosts, las access lists, los usuarios, los certificados y la configuración. Además de NPM, debe realizar copias de seguridad por separado de los datos de las aplicaciones: directorios de Nextcloud, Vaultwarden, repositorios Git, bases de datos PostgreSQL y MariaDB, archivos de Mattermost y configuraciones Compose.

Qué incluir en la copia de seguridad

Objeto Ubicación Por qué es necesario
Datos de NPM ~/stacks/nginx-proxy-manager/data Base de datos SQLite, proxy hosts, usuarios, configuración
Let’s Encrypt ~/stacks/nginx-proxy-manager/letsencrypt Certificados, cuenta ACME, claves
Archivos Compose y .env ~/stacks Despliegue reproducible y secretos
Datos de aplicaciones bind mounts o named volumes Archivos de usuarios, bases de datos, configuración
Volcados de bases de datos directorio de backup independiente Restauración coherente de PostgreSQL/MariaDB

No considere un snapshot del VPS como una copia de seguridad completa. Un snapshot es útil antes de una actualización, pero si se almacena en la misma cuenta o centro de datos, no protege contra la eliminación de la cuenta, el compromiso de las credenciales o una incidencia del proveedor. Utilice la regla 3-2-1: al menos tres copias, en dos tipos de almacenamiento y una fuera del servidor principal.

Copia de seguridad sencilla con Restic en S3

Restic admite cifrado en el lado del cliente y almacenamientos compatibles con S3. Cree un bucket independiente, un usuario independiente con acceso solo a ese bucket y guarde las claves en un archivo protegido.

sudo apt install -y restic
sudo install -d -m 700 /root/.config/restic
sudo nano /root/.config/restic/env
sudo chmod 600 /root/.config/restic/env

Agregue las variables de acceso al archivo. Sustituya los valores por los datos de su almacenamiento S3.

export RESTIC_REPOSITORY="s3:https://s3.example-storage.net/server-backups/npm-vps"
export RESTIC_PASSWORD="use_a_long_unique_backup_password"
export AWS_ACCESS_KEY_ID="YOUR_ACCESS_KEY"
export AWS_SECRET_ACCESS_KEY="YOUR_SECRET_KEY"
sudo bash -c 'source /root/.config/restic/env && restic init'

El comando crea un nuevo repositorio cifrado. Guarde la contraseña RESTIC_PASSWORD por separado del VPS: en un gestor de contraseñas o almacenamiento offline. La pérdida de esta contraseña hace que las copias de seguridad sean irrecuperables.

sudo nano /usr/local/sbin/backup-stacks.sh
sudo chmod 700 /usr/local/sbin/backup-stacks.sh

Cree el script:

#!/usr/bin/env bash
set -euo pipefail

source /root/.config/restic/env

STAMP=$(date +%F)
BACKUP_DIR="/root/backup-work/$STAMP"

mkdir -p "$BACKUP_DIR"

docker exec vaultwarden /bin/sh -c 'sqlite3 /data/db.sqlite3 ".backup /data/db-backup.sqlite3"' || true

restic backup /home/admin/stacks \
  --exclude='/node_modules' \
  --exclude='/cache' \
  --tag docker-stacks

restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check

El script guarda los directorios de los stacks, elimina snapshots antiguos según la política de retención y comprueba el repositorio. Para aplicaciones con PostgreSQL o MariaDB, agregue pg_dump o mariadb-dump antes de la copia de seguridad; copiar los archivos de una base de datos activa sin un volcado puede producir una copia dañada o lógicamente incoherente.

sudo crontab -e

Agregue una ejecución diaria por la noche:

15 3   * /usr/local/sbin/backup-stacks.sh >> /var/log/backup-stacks.log 2>&1

Después de configurarlo, realice obligatoriamente una restauración en un directorio de prueba. Una copia de seguridad solo se considera funcional tras comprobar correctamente la restauración.

sudo bash -c 'source /root/.config/restic/env && restic snapshots'
sudo mkdir -p /root/restore-test
sudo bash -c 'source /root/.config/restic/env && restic restore latest --target /root/restore-test'

Actualizaciones de NPM y contenedores

Para un único VPS, el modelo óptimo es una ventana de mantenimiento: elija un período, por ejemplo una vez cada dos semanas, haga una copia de seguridad, lea las release notes y actualice un stack a la vez. Una rolling update es útil en un clúster con varias réplicas, pero en un servidor único normalmente no proporciona alta disponibilidad: reiniciar NPM durante 10–30 segundos seguirá interrumpiendo brevemente las conexiones.

cd ~/stacks/nginx-proxy-manager
docker compose pull
docker compose up -d
docker image prune -f
docker compose ps

Los comandos descargan la imagen, recrean el contenedor si cambia la versión, eliminan imágenes dangling no utilizadas y muestran el estado final. Primero fije la versión de la imagen en compose.yml y después actualícela de forma consciente. No ejecute sin pensar docker system prune -a --volumes: el comando puede eliminar datos que Docker considera no utilizados.

Una vez al mes, compruebe las actualizaciones del sistema operativo, la validez de los certificados, el tamaño de los logs y el espacio libre:

sudo apt update && sudo apt upgrade -y
df -h
docker system df
openssl s_client -connect vault.example.com:443 -servername vault.example.com < /dev/null 2>/dev/null | openssl x509 -noout -dates

Solución de problemas + FAQ

¿Por qué aparece Internal Error o timeout al emitir un certificado Let’s Encrypt?

Primero compruebe el DNS: el dominio debe devolver la IP de este VPS. Después, asegúrese de que el puerto 80 esté abierto en UFW, en el panel del proveedor y que no esté ocupado por otro contenedor o Nginx en el host. Ejecute sudo ss -lntp | grep -E ":80|:443" y compruebe que Docker está escuchando los puertos. Si se utiliza un proxy CDN, desactívelo temporalmente para el diagnóstico. Compruebe también docker logs nginx-proxy-manager y no supere los límites de Let’s Encrypt con intentos repetidos.

¿Por qué Nginx Proxy Manager devuelve 502 Bad Gateway?

El error 502 casi siempre significa que NPM no puede conectarse al contenedor upstream. Compruebe el nombre del contenedor, el puerto interno y la red Docker. Ejecute docker exec nginx-proxy-manager curl -I http://SERVICE:PORT. Si el nombre no se resuelve, ambos contenedores no están en la red proxy. Si la conexión es rechazada, la aplicación escucha en otro puerto o no se ha iniciado. No indique el dominio público del propio VPS en el campo Forward Hostname: esto puede crear un bucle de proxy.

¿Por qué el dominio se abre por HTTP, pero no redirige a HTTPS?

Abra la configuración del Proxy Host correspondiente y asegúrese de que el certificado esté seleccionado y el interruptor Force SSL activado. Si el certificado no se ha emitido, NPM no podrá redirigir de forma segura a HTTPS. Compruebe si se utiliza un registro DNS IPv6 AAAA independiente que apunte a otro servidor: el navegador puede conectarse mediante IPv6 mientras usted comprueba IPv4. Los comandos dig A domain y dig AAAA domain ayudan a ver rápidamente las discrepancias.

¿Qué configuración de VPS es la mínima adecuada?

Para un solo Nginx Proxy Manager y varios contenedores ligeros, la opción mínima razonable es 2 vCPU, 2 GB de RAM, 30 GB SSD e IPv4 público. Una vCPU y 1 GB de RAM pueden funcionar para pruebas, pero las actualizaciones, las operaciones TLS y los servicios adicionales agotarán rápidamente la memoria. Para Vaultwarden, Uptime Kuma, una Gitea pequeña y un reverse proxy, es mejor elegir directamente 2 vCPU, 4 GB de RAM y 60 GB NVMe.

¿Qué elegir: VPS o dedicated para esta tarea?

Para Nginx Proxy Manager, servicios personales y un equipo pequeño, elija VPS: es más económico, se despliega más rápido y normalmente se escala fácilmente en CPU, RAM y disco. Dedicated se justifica no por el proxy, sino por la carga de las aplicaciones detrás de él: un GitLab grande, una base de datos pesada, almacenamiento de archivos de terabytes, CI, procesamiento de vídeo o tráfico muy alto. Si el servidor atiende a menos de varias decenas de usuarios activos, un VPS suele ser suficiente.

¿Por qué la aplicación funciona por IP y puerto, pero no mediante el dominio?

Compruebe la configuración de Proxy Host: el scheme correcto, el nombre del contenedor y el puerto. Muchas aplicaciones generan enlaces, cookies y URL de redirección basándose en variables como DOMAIN, URL, ROOT_URL o PUBLIC_URL. Indique allí el dominio HTTPS externo, no http://localhost:PORT. Para servicios con WebSocket, active Websockets Support. Después de cambiar las variables de entorno, vuelva a crear el contenedor mediante docker compose up -d.

¿Es necesario abrir los puertos de las aplicaciones, por ejemplo 3000, 8080 o 3001, en UFW?

No, si NPM y la aplicación están conectados a la misma red Docker. No añada reglas de UFW para puertos internos ni los publique mediante ports. NPM accede al servicio mediante el nombre del contenedor dentro de la red Docker. La excepción es la depuración, pero incluso entonces es más seguro vincular temporalmente el puerto a 127.0.0.1, por ejemplo 127.0.0.1:3001:3001, y conectarse mediante un túnel SSH.

¿Cómo abrir de forma segura el panel de administración de NPM?

La mejor opción sencilla es mantener el puerto 81 vinculado a 127.0.0.1 y utilizar un túnel SSH. Para acceso permanente, puede crear un proxy host independiente con HTTPS, access list y autenticación adicional, pero esto aumenta la superficie de ataque externa. Un enfoque más fiable es acceder al panel solo mediante WireGuard o Tailscale. Cambie siempre las credenciales predeterminadas, use una contraseña única y actualice el contenedor periódicamente.

Conclusiones y próximos pasos

Esquema: Conclusiones y próximos pasos
Esquema: Conclusiones y próximos pasos

Ahora un VPS puede atender varias aplicaciones Docker mediante dominios independientes con HTTPS automático. Nginx Proxy Manager oculta los puertos internos de los contenedores, centraliza los certificados TLS y simplifica la incorporación de nuevos servicios.

  1. Añada monitorización de disponibilidad de dominios mediante Uptime Kuma y configure notificaciones en Telegram, email o Mattermost.
  2. Mueva las interfaces administrativas detrás de WireGuard o Tailscale y deje públicos únicamente los servicios destinados a los usuarios.
  3. Configure comprobaciones periódicas de restauración de copias de seguridad y documente dominios, contenedores, puertos y secretos en un repositorio privado o password manager.

Cuando aumente el número de servicios, separe las aplicaciones por proyectos Compose, limite los recursos de los contenedores y considere una base de datos independiente o un segundo VPS para copias de seguridad y monitorización.

¿Te fue útil esta guía?

Tus comentarios nos ayudan a mejorar nuestras guías.

Compartir esta publicación:

Envía esta guía a alguien a quien pueda resultarle útil.

Telegram VKVK WhatsApp Facebook LinkedIn XX

nginx proxy manager: SSL y dominios para todos los contenedores en un mismo VPS
support_agent
Valebyte Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.