
Nginx Proxy Manager
DeprecatedNginx Proxy Manager (NPM) is a docker contained app that provides a easy yet reliable and secure way to achieve reverse proxying using Nginx.
It provides a user-friendly UI, automated SSL certs renewal, easy setup, user management and advanced configuration over Nginx reverse proxy.
Here, we use NPM to easily interface all our apps without exposing there port on the host directly and by taking benefits off docker bridge network driver.
Before starting make sure you already created the homelab bridge network by running :
docker network create -d bridge homelab
Now create a docker-compose.yml
file and paste this :
version: "3.7"
services: app: container_name: npm_app image: jc21/nginx-proxy-manager:2.9.19 restart: unless-stopped ports: - "80:80" - "81:81" - "443:443" - "25500-25600:25500-25600" - "5440:5440" env_file: - stack.env healthcheck: test: ["CMD", "/bin/check-health"] interval: 10s timeout: 3s depends_on: - db volumes: - /home/raphaelgc/apps/nginx-pm/data:/data - /home/raphaelgc/apps/nginx-pm/letsencrypt:/etc/letsencrypt networks: - homelab
db: container_name: npm_db hostname: npm_db image: jc21/mariadb-aria:latest restart: unless-stopped env_file: - stack.env volumes: - /home/raphaelgc/apps/nginx-pm/data/mysql:/var/lib/mysql networks: - homelab
networks: homelab: external: true
2 containers are now running : npm_app (NPM itself) and npm_db (the mariadb database).
Error pages
Section titled “Error pages”404 pages
Section titled “404 pages”<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>404 Not found</title> <style> *, :before, :after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: #e5e7eb; margin: 0; }
:root { --bg: #f9fafb; --text-primary: #333; --text-secondary: #64748b; --button-text: #f8fafc; --button-bg: #2563eb; --button-accent: #3b82f6; }
html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', Segoe UI Symbol, 'Noto Color Emoji'; }
body { margin: 0; line-height: inherit; display: flex; align-items: center; justify-content: center; flex-direction: column; text-align: center; height: 100vh; overflow: hidden; color: var(--text-primary); background-color: var(--bg); }
h1 { position: relative; padding-bottom: 0.75rem; margin-bottom: 0.75rem; }
p { color: var(--text-secondary); }
h1:after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; margin: auto; width: 70%; height: 1px; background-color: var(--text-secondary); }
a { padding: 0.5rem 0.75rem; margin-top: 1rem; background-color: var(--button-bg); border-radius: 10px; color: var(--button-text); text-decoration: none; transition: all 200ms linear; }
a:hover { background-color: var(--button-accent); box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
a:focus { outline: var(--button-accent) 2px solid; outline-offset: 2px; }
@media (prefers-color-scheme: dark) { :root { --bg: #0f172a; --text-primary: #f1f5f9; --text-secondary: #cbd5e1; --button-bg: #1e40af; --button-accent: #1d4ed8; } } </style> </head> <body> <h1>404 Not found</h1> <p>Please ask Raphaël for details on error.</p> <p>Merci de demander à Raphaël pour plus d'informations.</p> <a href="https://dashboard.lab.raphael-catarino.fr/">Go home</a> </body></html>
502 Bad Gateway
Section titled “502 Bad Gateway”error_page 502 /error-bad-gateway.html; proxy_intercept_errors on; location /error-bad-gateway.html { internal; root /data/nginx/error_pages;}
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>502 Bad gateway</title> <style> *, :before, :after { box-sizing: border-box; border-width: 0; border-style: solid; border-color: #e5e7eb; margin: 0; }
:root { --bg: #f9fafb; --text-primary: #333; --text-secondary: #64748b; --button-text: #f8fafc; --button-bg: #2563eb; --button-accent: #3b82f6; }
html { line-height: 1.5; -webkit-text-size-adjust: 100%; -moz-tab-size: 4; -o-tab-size: 4; tab-size: 4; font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', Segoe UI Symbol, 'Noto Color Emoji'; }
body { margin: 0; line-height: inherit; display: flex; align-items: center; justify-content: center; flex-direction: column; height: 100vh; text-align: center; overflow: hidden; color: var(--text-primary); background-color: var(--bg); }
h1 { position: relative; padding-bottom: 0.75rem; margin-bottom: 0.75rem; }
p { color: var(--text-secondary); }
h1:after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; margin: auto; width: 70%; height: 1px; background-color: var(--text-secondary); }
a { padding: 0.5rem 0.75rem; margin-top: 1rem; background-color: var(--button-bg); border-radius: 10px; color: var(--button-text); text-decoration: none; transition: all 200ms linear; }
a:hover { background-color: var(--button-accent); box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); }
a:focus { outline: var(--button-accent) 2px solid; outline-offset: 2px; }
@media (prefers-color-scheme: dark) { :root { --bg: #0f172a; --text-primary: #f1f5f9; --text-secondary: #cbd5e1; --button-bg: #1e40af; --button-accent: #1d4ed8; } } </style> </head> <body> <h1>502 Bad gateway</h1> <p>Please ask Raphaël for details on error.</p> <p>Merci de demander à Raphaël pour plus d'informations.</p> <a href="https://dashboard.lab.raphael-catarino.fr/">Go home</a> </body></html>
Backuping
Section titled “Backuping”To create a complete backup, be sure to backup data
and letsencrypt
folders, then run the following command to backup the sql db :
docker exec -it npm_db mysqldump --user=npm --password=npm db1 -h 127.0.0.1 > ~/apps/nginx-pm/backups/npm-export-$(date +'%d-%m-%Y_%H:%M:%S').sql
To recover from a backup, copy those two folders, and the .sql backup file, then run :
docker exec -i npm_db mysql --user=npm --password=npm db1 -h 127.0.0.1 < npm-export.sql
Deprecated
Section titled “Deprecated”Replaced by Traefik for simplicity and security reasons.