NGINX Proxy Manager (NPM) è un software open-source ampiamente utilizzato per la gestione del traffico web. Grazie alla sua architettura efficiente e scalabile, è diventato una scelta popolare come server web, reverse proxy e load balancer per distribuire il traffico su più server. Progettato per gestire migliaia di connessioni simultanee con un basso consumo di memoria, eccelle come reverse proxy, fungendo da intermediario tra client e server backend.

Particolarmente utile per utenti non esperti, NGINX Proxy Manager consente di gestire configurazioni di rete complesse senza modificare manualmente i file di configurazione di NGINX. È la soluzione ideale per gestire il traffico del proprio homelab o della rete aziendale.

Funzionamento & Requisiti

Essendo un servizio che gestisce il traffico in entrata, è importante comprenderne il funzionamento e i prerequisiti per l’installazione. Il reverse proxy riceve le richieste sulle porte 80 (HTTP) e 443 (HTTPS) e le inoltra ai servizi interni in base alla configurazione.

flowchart LR subgraph Pubblico U[👤 Utente] D[🔍 DNS] end subgraph Privato N[⬡ NGINX] S[🖥️ Servizio] end U -->|1. Richiede dominio| D D -->|2. Restituisce IP| U U -->|3. Connessione| N N -->|4. Inoltra| S S -->|5. Risposta| N N -->|6. Risposta| U

Possiamo considerare NGINX come un punto di ingresso tra la rete pubblica e il nostro ambiente privato. Ecco il flusso di una richiesta:

  1. L’utente digita un indirizzo (es. app.miodominio.it) nel browser.
  2. Il browser interroga un server DNS per ottenere l’indirizzo IP associato al dominio.
  3. Il DNS restituisce l’IP pubblico del nostro server, dove è in ascolto NGINX.
  4. Il browser si connette a NGINX, che riceve la richiesta e la inoltra al servizio interno corrispondente.
  5. Il servizio elabora la richiesta e restituisce la risposta a NGINX.
  6. NGINX inoltra la risposta all’utente.

In sintesi, per utilizzare un reverse proxy sono necessari: un dominio configurato per puntare al nostro IP pubblico, e un server esposto su cui installare NGINX Proxy Manager e i servizi da rendere accessibili.

Processo di Installazione

Dopo aver installato Docker Engine e Docker Compose, è possibile procedere con l’installazione di NGINX Proxy Manager utilizzando un container Docker. La configurazione è suddivisa in due file: il file docker-compose.yml, che definisce i servizi (NPM e il database MariaDB), e il file .env, che contiene le variabili sensibili per garantire la sicurezza.

Apertura delle Porte

Prima di procedere, apri le porte 80 (HTTP), 443 (HTTPS) e 81 (interfaccia web) sul firewall/router. Sono indispensabili per gestire il traffico in entrata e accedere al pannello di amministrazione.

Creiamo il File Docker Compose

Il file docker-compose.yml qui sotto configura due servizi: NGINX Proxy Manager (nginx-proxy-manager) e un database PostgreSQL (services_db) per la persistenza dei dati. Sebbene il container possa funzionare anche senza database esterno, l’uso di un DB dedicato (qui utilizziamo PostgreSQL, ma in alternativa si può utilizzare anche MariaDB) consente di mantenere configurazioni, certificati SSL e log di accesso, facilitando backup e migrazioni.

yaml
services:
  
  nginx-app:
    container_name: NGINX_App
    image: 'jc21/nginx-proxy-manager:latest'
    restart: always
    ports:
      - '80:80'     # HTTP Port
      - '443:443'   # HTTPS Port
      - '81:81'     # Web-Admin
    environment:
      TZ: "Europe/Italy"
      DB_POSTGRES_HOST: 'nginx-db'
      DB_POSTGRES_USER: ${DATABASE_USER}
      DB_POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      DB_POSTGRES_NAME: ${DATABASE_TABLE_NAME}
    volumes:
      - nginx_data:/data
      - nginx_certs:/etc/letsencrypt
    networks:
      - nginx_network   
    depends_on:
      - nginx-db

  nginx-db:
    container_name: NGINX_DB
    image: postgres:17
    environment:
      POSTGRES_USER: ${DATABASE_USER}
      POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
      POSTGRES_DB: ${DATABASE_TABLE_NAME}
    restart: always
    volumes:
      - nginx-proxy-db:/var/lib/postgresql
    networks:
      - nginx_network

volumes:
    nginx_data:
    nginx_certs:
    nginx_db:

networks:
    nginx_network:
        driver: bridge

In questa configurazione abbiamo creato dei volumi, rispettivamente: nginx_data che ha lo scopo di memorizzare le configurazioni di NGINX Proxy Manager, nginx_certs che contiene i certificati SSL generati tramite Let’s Encrypt ed infine nginx_db che garantisce la persistenza dei dati del database.

Entrambi i container sono collegati alla rete nginx_network. Questo permette la comunicazione interna tra NPM e MariaDB senza esporre la porta del database all’esterno, migliorando la sicurezza.

Definiamo le Variabili (.env)

Per migliorare la sicurezza, le variabili sensibili (password, username, ecc.) devono essere definite nel file .env, che deve essere creato nella stessa posizione del file docker-compose.yml. Di seguito è riportato un esempio delle variabili utilizzabili:

bash
DATABASE_USER=nginx_user
DATABASE_PASSWORD=5up3r_P4s5w0rd_DB
DATABASE_TABLE_NAME=nginx_db

Consiglio: Utilizzare password complesse e uniche, preferibilmente generate tramite un gestore di password, per proteggere il database e il servizio.

Avvio dei container

Per avviare i container, spostarsi nella directory contenente i file docker-compose.yml e .env ed eseguire il seguente comando:

bash
docker-compose up -d

Questo comando avvia i servizi in modalità detached, consentendo loro di funzionare in background. Una volta avviati, NGINX Proxy Manager sarà accessibile tramite l’interfaccia web all’indirizzo http://<indirizzo_IP_server>:81.

Credenziali di Primo Accesso

Le credenziali predefinite sono admin@example.com / changeme. Modificale immediatamente al primo accesso.

Dettaglio dei servizi

I servizi definiti nel file docker-compose.yml hanno le seguenti caratteristiche:

  • NGINX Proxy Manager (nginx-app): Servizio principale per la gestione del traffico web. La porta 80 gestisce il traffico HTTP, la 443 il traffico HTTPS e la 81 l’interfaccia di amministrazione.
  • PostgreSQL (nginx-db): Database per memorizzare configurazioni, certificati SSL e log in modo persistente.
  • Politica di avvio: La direttiva depends_on garantisce che nginx-app venga avviato solo dopo che il database nginx-db è attivo.
  • Riavvio automatico: La politica restart: always assicura che entrambi i servizi si riavviino automaticamente in caso di problemi.
  • Rete condivisa: Entrambi i container sono collegati a nginx_network, permettendo la comunicazione interna senza esporre la porta del database all’esterno.
  • Persistenza dei dati: I volumi Docker (nginx_data, nginx_certs, nginx-proxy-db) preservano configurazioni, certificati e dati del database.

Configurazione di NGINX Proxy Manager

Dopo aver avviato i container, è necessario configurare NPM attraverso la sua interfaccia web per gestire il routing del traffico, creare certificati SSL e definire regole di accesso.

Step 1: Login e Creazione delle Credenziali

Aprire un browser e accedere all’interfaccia di gestione all’indirizzo http://<indirizzo_IP_server>:81. Nel form di login, inserire le credenziali di default (admin@example.com / changeme). Al primo accesso verrà richiesto di impostare nuove credenziali.

Step 2: Attivazione di un Certificato (Let’s Encrypt)

Per configurare un certificato SSL, accedere al menu SSL Certificates e cliccare su Add SSL Certificate. Selezionare il metodo di validazione (solitamente Let’s Encrypt via DNS), inserire il dominio (es. *.esempio.cc) e il provider DNS per verificare la proprietà del dominio. Ogni provider richiede la generazione di token specifici: consultare la documentazione del proprio provider per le istruzioni.

Interfaccia SSL Certificates

Step 3: Configurazione di un Dominio

Per configurare un proxy inverso, accedere a Hosts > Proxy Hosts e inserire nel tab “Details” le informazioni richieste: nome di dominio (es. app.example.com), protocollo del servizio backend (HTTP o HTTPS), indirizzo IP e porta del servizio. Nel tab “SSL” è possibile associare il certificato creato in precedenza.

Interfaccia Proxy Hosts

Troubleshooting & Consigli

Se si riscontra un errore 502 Bad Gateway, verificare che il servizio backend sia raggiungibile: controllare IP e porta configurati, e assicurarsi che il container sia sulla stessa rete Docker di NPM.

In caso di problemi con la generazione del certificato SSL, verificare che le porte 80 e 443 siano aperte sul firewall/router e che il dominio punti correttamente all’IP del server. Controllare i log con docker logs NGINX_App per dettagli sull’errore.

Se il container non si avvia, consultare i log per identificare eventuali errori di connessione al database PostgreSQL. Verificare che il container nginx-db sia attivo e che le credenziali nel file .env siano corrette.

È consigliabile utilizzare password complesse e uniche per il file .env e le credenziali di accesso a NPM, in modo da migliorare la sicurezza della piattaforma.

È consigliato limitare l’accesso alla porta 81 (interfaccia di amministrazione) solo agli indirizzi IP autorizzati, oppure disabilitarla quando non è necessaria.

Mantenere i container a una versione specifica, evitando il tag latest, per escluderli da aggiornamenti automatici. Prima di aggiornarli, verificare le release notes per evitare interruzioni di servizio. In caso di problemi dopo l’aggiornamento, è possibile ripristinare la versione precedente.

Eseguire backup regolari dei volumi nginx_data e nginx_certs per preservare configurazioni e certificati SSL in caso di problemi.

Abilitare l’opzione Force SSL nei Proxy Hosts per reindirizzare automaticamente il traffico HTTP verso HTTPS.