
In questo articolo ti guido passo passo per fare in modo che tutte le richieste gestite da Nginx Proxy Manager usino le stesse pagine di errore personalizzate (400, 401, 402, 403).
Ti spiego pensando a un’installazione tipica con Docker + docker-compose. Se non usi Docker, puoi comunque seguire la logica, ma i percorsi potrebbero cambiare leggermente.
Con Nginx Proxy Manager (NPM) in Docker hai due strade pulite per avere error pages personalizzate:
Globale (vale per tutti i proxy host): metti i file HTML in un posto “fisso” e fai in modo che NPM li serva + un blocco error_page che rimappa tutti i codici.
Per singolo Proxy Host: stessa cosa ma aggiungi la config solo su quel host.
CONFIGURAZIONE GLOBALE
🧩 STEP 1 – Mettere i file di errore sul server
Entrare via SSH nel server dove gira Nginx Proxy Manager quindi creare le seguenti cartelle per le pagine di errore con i comandi:
|
0
1
2
|
mkdir -p /data/nginx/custom
mkdir -p /data/nginx/error_pages
|
Creare quindi il file di configurazione server_proxy.conf con il comando:
|
0 |
touch /data/nginx/custom/server_proxy.conf
|
📦 STEP 2 – Montare la cartella nel container NPM
Aprire il docker-compose.yml (quello con il servizio app / nginxproxymanager).
Dentro la sezione volumes: del servizio NPM aggiungere una riga per la cartella:
|
0
1
2
3
4
5
6
7
|
services:
app:
image: jc21/nginx-proxy-manager:latest
...
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
- ./error_pages:/data/error_pages
|
ATTENZIONE: non rimuovere i volumi esistenti aggiungere solo la riga – ./error_pages:/data/error_pages
Salvare e chiudere il file di configurazione.
Riavviare NPM con i seguenti comandi:
|
0
1
2
3
4
|
cd /cartella/del/tuo/docker-compose
docker compose down
docker compose up -d
|
Ora dentro il container i file saranno visibili in:
|
0
1
2
3
4
|
/data/error_pages/400.html
/data/error_pages/401.html
/data/error_pages/402.html
/data/error_pages/403.html
...
|
🌍 STEP 3 – Creare una configurazione Nginx globale
In questa sezione faremo in modo che la configurazione venga caricata da tutti i VirtualHost generati da NPM.
Editare il file server_proxy.conf posizionato nella cartella /data/nginx/custom folder con il comando:
|
0 |
nano /data/nginx/custom/server_proxy.conf
|
Incollare dentro il file di configurazione questo contenuto:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
error_page 400 /error_pages/400.html;
error_page 401 /error_pages/401.html;
error_page 402 /error_pages/401.html;
error_page 403 /error_pages/403.html;
error_page 404 /error_pages/404.html;
error_page 405 /error_pages/405.html;
error_page 407 /error_pages/407.html;
error_page 408 /error_pages/408.html;
error_page 409 /error_pages/409.html;
error_page 410 /error_pages/410.html;
error_page 411 /error_pages/411.html;
error_page 412 /error_pages/412.html;
error_page 413 /error_pages/413.html;
error_page 416 /error_pages/416.html;
error_page 418 /error_pages/418.html;
error_page 429 /error_pages/429.html;
error_page 500 /error_pages/500.html;
error_page 501 /error_pages/501.html;
error_page 502 /error_pages/502.html;
error_page 503 /error_pages/503.html;
error_page 504 /error_pages/504.html;
error_page 505 /error_pages/505.html;
proxy_intercept_errors on;
location /error_pages/ {
alias /data/nginx/error_pages/;
internal;
}
|
Salvare e chiudere il file di configurazione.
Spiegazione veloce:
error_page …: dice a Nginx quale URL usare per ogni codice di errore.
location /error_pages/: dice dove trovare fisicamente i file (root /data; → quindi /data/error_pages/400.html ecc.)
internal: fa sì che le pagine non siano raggiungibili direttamente via browser (solo tramite error_page).
Nginx Proxy Manager carica automaticamente i file in data/nginx/custom/*.conf all’interno dei blocchi server generati.
In questo modo tutti i proxy host avranno queste direttive senza doverle reinserire a mano in ogni Advanced → Custom Nginx Configuration
🔁 STEP 4 – Riavviare Nginx Proxy Manager
Dopo aver creato il file .conf riavviare il container con i seguenti comandi:
|
0
1
2
3
4
|
cd /cartella/del/tuo/docker-compose
docker compose down
docker compose up -d
|
Questo fa rileggere tutte le configurazioni a Nginx.
✅ STEP 5 – Testare le pagine di errore
Ora testare le seguenti cose:
- Una pagina che dia 403 (ad esempio una location protetta)
- Una richiesta che generi 400 (URL volutamente malformato o qualche backend che risponde 400)
- Analogamente per 401/402 se hai contesti in cui vengono generati.
In pratica aprire un dominio gestito da NPM
Fare un’azione che generi quell’errore
Se tutto è ok dovresti vedere le pagine personalizzate.
🧪 STEP 6 – Se qualcosa non funziona
Se non vedi le pagine personalizzate eseguire gli steps che elenco di seguito:
- Controllare dentro il container che i file siano davvero dove devono essere con i seguenti comandi:
|
0
1
2
|
docker exec -it <nome_container_npm> sh
ls -l /data/error_pages
|
2. Verificare che il file error_pages.conf sia montato correttamente con i seguenti comandi:
|
0
1
2
|
ls -l /data/nginx/custom
cat /data/nginx/custom/error_pages.conf
|
3. Analizzare i log di Nginx Proxy Manager con il comando:
|
0 |
docker logs <nome_container_npm>
|
CONFIGURAZIONE PER SINGOLO HOST
🧩 STEP 1 – Creazione della cartella sul server e dei file HTML
Creare la cartella custom-errors con il comando:
|
0 |
sudo mkdir -p /opt/npm/custom-errors
|
Creare/Copiare i files (uno per codice). Esempio per 404 e 50x:
|
0
1
2
|
sudo nano /opt/npm/custom-errors/404.html
sudo nano /opt/npm/custom-errors/50x.html
|
📦 STEP 2 – Montare la cartella dentro il container di NPM
Aprire il file docker-compose.yml di Nginx Proxy Manager (dove hai jc21/nginx-proxy-manager o simile) con il comando:
|
0 |
sudo nano docker-compose.yml
|
Aggiungere il volume al fondo della configurazione del file como mostrato di seguito:
|
0
1
2
3
4
5
6
7
|
services:
npm:
image: jc21/nginx-proxy-manager:latest
# ...
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
- /opt/npm/custom-errors:/data/custom-errors:ro
|
Salvare e chiudere il file di configurazione.
Riavviare Docker con il comando:
|
0 |
docker compose up -d
|
Verificare che i file siano visibili nel container eseguendo il comando:
|
0 |
docker exec -it <nome_container_npm> ls -la /data/custom-errors
|
Se è tutto OK dovremmo visualizzare il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
total 492
drwxr-xr-x 3 root root 4096 Jan 3 12:21 .
drwxr-xr-x 8 root root 4096 Jan 3 12:23 ..
-rw-r--r-- 1 root root 21880 Mar 26 2023 400.html
-rw-r--r-- 1 root root 21911 Mar 26 2023 401.html
-rw-r--r-- 1 root root 21872 Mar 26 2023 403.html
-rw-r--r-- 1 root root 21875 Mar 26 2023 404.html
-rw-r--r-- 1 root root 21935 Mar 26 2023 405.html
-rw-r--r-- 1 root root 22054 Mar 26 2023 407.html
-rw-r--r-- 1 root root 21953 Mar 26 2023 408.html
-rw-r--r-- 1 root root 21913 Mar 26 2023 409.html
-rw-r--r-- 1 root root 21852 Mar 26 2023 410.html
-rw-r--r-- 1 root root 22031 Mar 26 2023 411.html
-rw-r--r-- 1 root root 22002 Mar 26 2023 412.html
-rw-r--r-- 1 root root 22018 Mar 26 2023 413.html
-rw-r--r-- 1 root root 22023 Mar 26 2023 416.html
-rw-r--r-- 1 root root 21920 Mar 26 2023 418.html
-rw-r--r-- 1 root root 21910 Mar 26 2023 429.html
-rw-r--r-- 1 root root 21911 Mar 26 2023 500.html
-rw-r--r-- 1 root root 21949 Mar 26 2023 502.html
-rw-r--r-- 1 root root 21924 Mar 26 2023 503.html
-rw-r--r-- 1 root root 21848 Mar 26 2023 504.html
-rw-r--r-- 1 root root 21982 Mar 26 2023 505.html
|
🌍 STEP 3 – Creare un server interno per servire quei file (snippet globale)
NPM genera la config di Nginx automaticamente quindi il modo più pratico è usare Advanced config e/o snippet.
Opzione consigliata: Custom Nginx Configuration globale
NPM (di solito) permette snippet globali in /data/nginx/custom/.
Creare una cartella e un file come di seguito:
|
0 |
sudo mkdir -p /opt/npm/npm-custom
|
ATTENZIONE: per usare /data/nginx/custom/ devi avere quel path nel container. In NPM normalmente esiste già in /data/nginx/. Quindi creiamo direttamente dentro i volumi già montati di NPM.
Nel compose montare ./data:/data e sul server la cartella è ./data nella directory del compose.
Ad esempio se il compose sta in /opt/npm/compose/docker-compose.yml allora /opt/npm/compose/data è mappata a /data nel container
Quindi creare la cartella ed il file http.conf con i seguenti comandi:
|
0
1
2
|
sudo mkdir -p /opt/npm/compose/data/nginx/custom
sudo nano /opt/npm/compose/data/nginx/custom/http.conf
|
Dentro http.conf inserire un blocco server interno che serve i file (non esposto su internet) così possiamo fare proxy_intercept_errors e error_page puntando a URI locali:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# /data/nginx/custom/http.conf
# Questo viene incluso nel contesto http { ... }
# Server interno per servire i file statici delle error pages
server {
listen 127.0.0.1:8181;
server_name _;
location /errors/ {
alias /data/custom-errors/;
default_type text/html;
add_header Cache-Control "no-store";
}
}
|
Salvare e chiudere il file di configurazione.
Quindi riavviare NPM con il comando:
|
0 |
docker restart <nome_container_npm>
|
🔁 STEP 4 – Agganciare le error pages ai Proxy Host
Ora dobbiamo dire a ogni server/proxy host di:
- intercettare gli errori (proxy_intercept_errors on;)
- mappare ogni status code su una URL interna
- fare un subrequest verso 127.0.0.1:8181
Collegarsi alla gui di NPM
Cliccare su Proxy Hosts come mostrato nell’immagine sovrastante
Cliccare sui tre puntini del Proxy Host che vogliamo modificare quindi selezionare Edit
Cliccare sull’ingranaggio (Advanced)
Incollare all’interno di Custom Nginx Configuration il seguente output:
|
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
proxy_intercept_errors on;
error_page 400 = /_error/400;
error_page 401 = /_error/401;
error_page 403 = /_error/403;
error_page 404 = /_error/404;
error_page 405 = /_error/405;
error_page 407 = /_error/407;
error_page 408 = /_error/408;
error_page 409 = /_error/409;
error_page 410 = /_error/410;
error_page 411 = /_error/411;
error_page 412 = /_error/412;
error_page 413 = /_error/413;
error_page 416 = /_error/416;
error_page 418 = /_error/418;
error_page 429 = /_error/429;
error_page 500 = /_error/500;
error_page 502 = /_error/502;
error_page 503 = /_error/503;
error_page 504 = /_error/504;
error_page 505 = /_error/505;
location ^~ /_error/ {
internal;
# ricava il codice dalla URI: /_error/404 -> 404
set $code $uri;
if ($code ~ "^/_error/([0-9]+)$") { set $code $1; }
proxy_pass http://127.0.0.1:8181/errors/$code.html;
# assicura che il codice HTTP rimanga quello originale
proxy_intercept_errors off;
# Header utili
proxy_set_header Host $host;
# Se manca il file, fallback 50x o 4xx (opzionale)
# (Nginx non fa try_files su proxy_pass, quindi fallback lo gestisci
# creando TUTTI i file richiesti oppure usando solo 4xx.html / 50x.html)
}
|
Dopo aver inserito l’output cliccare Save
ATTENZIONE: Accertarsi di avere davvero i file:
/opt/npm/custom-errors/400.html
…
/opt/npm/custom-errors/505.html
Altrimenti Nginx proverà a prenderli e otterrai un errore.
Ripetere sugli altri Proxy Host dove si intende applicare questa configurazione.
✅ STEP 5 – Testare le pagine di errore
Test 404: apri una URL inesistente sul dominio
Test 502/504: fermare temporaneamente l’app upstream e provare ad aprire il dominio
Dovremmo visualizzare la pagina di errore caricata in precedenza
Se invece vediamo la pagina standard di Nginx vuol dire che c’è qualcosa che non ha funzionato nella configurazione.
Controllare quindi i log Nginx di NPM con il comando:
|
0 |
docker logs <nome_container_npm> --tail 200
|
🧪 STEP 6 – Note importanti (per evitare sorprese)
401/403: spesso dipendono da auth (basic auth, app, access list). NPM può intercettarli se l’errore viene generato dal layer Nginx/proxy.
413 (payload too large): può essere generato da Nginx prima che la richiesta arrivi all’upstream; comunque lo gestisci uguale.
Errori generati dall’app: se la tua app risponde “200” con una pagina “Errore” in HTML, Nginx non lo vede come errore e non lo sostituisce.
Variante più semplice (se vuoi 2 file soltanto). Se vuoi evitare 25 file, puoi creare:
/opt/npm/custom-errors/4xx.html
/opt/npm/custom-errors/50x.html
e rimappare tutti i 4xx e 50x all’interno dei due file.
DOWNLOAD TEMPLATE DI ERROR PAGES (HTML/CSS)
Di seguito una serie di link dove è possibile scaricare gratuitamente delle Custom Page già belle e fatte:
Template HTML per pagine 404 – design pronti per essere adattati o modificati: 63 HTML 404 Templates
Collezione di template per error pages HTTP (404, 500, ecc.) su GitHub – HTML gratuiti per sostituire le pagine standard di server web: https://github.com/PecceG2/HTML_Template_http_codes
Raccolta di template gratuiti (404, 500, ecc.) con varie grafiche – spesso con anteprime + codice pronto: https://colorlib.com/wp/free-error-page-templates/?utm_source=chatgpt.com
Template gratuiti 404 in HTML/CSS (16 esempi): https://democoding.in/blogs/free-html-error-page-templates Demo Coding
Raccolta di template 500 error pages (puoi adattarli ad altri errori): https://uicookies.com/500-error-page-templates

0 commenti