Nginx Proxy Manager
Web UI for nginx reverse proxy hosts and Let's Encrypt certificates
Nginx Proxy Manager wraps nginx (OpenResty) and certbot in a web interface where you fill in a domain, an upstream host and port, and tick a box to get a certificate. It replaces hand-written nginx server blocks and certbot cron jobs for people who do not want to learn either.
Our verdict on Nginx Proxy Manager#
Nginx Proxy Manager is the right answer for one specific person: you want a web form, not a config file. Type a domain, an upstream host and port, tick "request a Let's Encrypt certificate", done. Nothing else in this category is that low-friction. Be clear-eyed about the project though. It is effectively one maintainer, 2.15.1 shipped in June 2026, and recent releases have been Debian base image, OpenResty and certbot updates plus CVE patches rather than new capability. The v3 rewrite (Go backend, React frontend) has had an open status issue since June 2021 and has not landed; there are roughly 890 open issues. That is not abandonment, but do not choose it expecting the feature set to grow. Practically it also means the UI is the source of truth: it generates nginx config into /data/nginx and rewrites it, so anything you hand-edit outside the per-host "Advanced" box gets overwritten on the next save.
Who Nginx Proxy Manager is for#
Choose it if
- Someone putting their first five self-hosted services behind real hostnames who has never written an nginx server block
- A household or small office where more than one person needs to add a proxy host without SSH access
- TCP/UDP stream forwarding cases (game servers, SMTP relays) that Caddy and Traefik make awkward
- Anyone who wants HTTP basic auth access lists on a few internal tools without deploying an auth proxy
Look elsewhere if
- You want your proxy config in git and reviewed; this stores it in SQLite and generates the files
- You are on 32-bit ARM hardware, since armv7 images stopped at 2.13.7
- You need OIDC or forward auth integration, which means Traefik plus Authelia or Caddy plus
forward_authinstead
What running it actually looks like#
One container, two volumes: ./data:/data and ./letsencrypt:/etc/letsencrypt. Publish 80, 443 and 81 for the admin UI. SQLite is the default and needs no second service; MariaDB/MySQL and PostgreSQL are supported if you want them, at the cost of a second container and a startup ordering dependency. First run creates the account admin@example.com with password changeme and forces you to replace both at first login, so do not leave 81 reachable from the internet even briefly. Certificate issuance runs certbot inside the container and needs port 80 reachable from outside unless you configure one of the bundled DNS provider plugins. Upgrades are a tag bump; the app runs its own knex migrations on start. Note that 2.14 dropped armv7 builds over Node.js requirements, so 32-bit Raspberry Pi installs are frozen at 2.13.7.
Resource profile#
- Memory
- 100 MB idle, around 200 MB in ordinary use. One container running nginx workers, a Node.js API and a Python certbot; the Node process is the bulk of it and does not shrink.
- CPU and acceleration
- Idle while proxying. Certificate renewal runs certbot inside the container and briefly spikes; nothing here needs a GPU or more than one core.
- Storage growth
- The database and generated nginx config are a few megabytes. Access and error logs under /data/logs grow per proxy host and are not rotated aggressively by default.
- Operational load
- 2 of 5, Light. One container, SQLite, schema migrations run automatically on start. It stays at 2 rather than 1 because two coupled data directories must be restored together and the generated config is not something you can safely hand-edit.
Figures describe a small single-household install and are the working assumptions behind our stack planner. Your numbers will differ with library size, user count and hardware. See methodology.
Data and backup surface#
/data holds everything the app owns: database.sqlite, the generated server blocks under /data/nginx, uploaded certificates under /data/custom_ssl, and per-host logs under /data/logs. /etc/letsencrypt holds the ACME account and every issued certificate. Back both up together and restore them together: proxy hosts reference certificates by numeric ID, so restoring one without the other leaves you with hosts pointing at certificates that do not exist and nginx refusing to start. Stop the container before copying, or run sqlite3 database.sqlite ".backup out.db". /data/nginx is regenerated from the database on start and /data/logs is disposable, so both can be excluded. If you moved to MySQL or PostgreSQL, dump the database and still copy /etc/letsencrypt.
Derived backup shape
SQLite backup. sqlite3 <db> ".backup out.db" while running, or stop the container and copy. A live cp of a WAL-mode SQLite file can restore corrupt.
Traps and surprises#
Published default credentials on port 81
First boot creates admin@example.com / changeme. These are documented publicly, and port 81 has no rate limiting in front of it. People expose 81 to the internet "just for setup", get scanned within hours, and hand over a proxy that can be pointed at anything on their LAN. Bind 81 to a LAN address or leave it behind a VPN, and complete the forced credential change before you touch DNS.
The UI overwrites hand-edited nginx config
Everything under /data/nginx/proxy_host/*.conf is regenerated from the database whenever you save that host. Edits vanish silently. If you need custom directives, use the per-host Advanced tab, which is stored in the database and injected into the generated block, or drop global snippets into /data/nginx/custom/ where the templates include them. Debugging "my config keeps reverting" is a rite of passage here.
armv7 support ended at 2.13.7
Version 2.14 dropped 32-bit ARM images because of the Node.js version bump. A Raspberry Pi 2 or a Pi 3 running 32-bit Raspberry Pi OS will pull an image that does not exist, or stay pinned on 2.13.7 and miss the OpenResty CVE fixes that shipped in 2.15.0. The fix is a 64-bit OS on the same hardware, or moving the container elsewhere.
Websockets and HTTP/2 are per-host toggles, off by default
A new proxy host does not pass websocket upgrade headers until you tick "Websockets Support", and HTTP/2 is a separate checkbox on the SSL tab. This surfaces as an app that loads but whose live updates never arrive: Home Assistant, Jellyfin's sync play, anything with a socket. Nothing in the UI hints at it, and the nginx error log stays empty because the request is simply proxied as plain HTTP.
v3 has been coming since 2021
The official v3 status issue (opened June 2021) describes a Go backend, a React frontend, acme.sh instead of certbot and SQLite only. Five years later it has not shipped, and the released line is still the original Express and certbot stack. Plan around v2 as it exists today, not around the rewrite. If a maintained, actively developed proxy matters more than the GUI, that argues for Caddy or Traefik.
Specifications#
- Category
- Networking, DNS and remote access
- Licence
- MIT (Permissive)
- Written in
- Node.js (Express) driving nginx/OpenResty
- First release
- 2018
- Maturity
- Mature
- Datastore
- SQLite by default; MariaDB/MySQL or PostgreSQL optional
- Default ports
80,443,81- Ships as
- docker
- arm64 builds
- Yes
- Identity
- Local accounts only. Local accounts only, with per-user permissions and an audit log. No OIDC, no LDAP, and none is planned in the v2 line.
- Replaces
- Cloudflare Tunnel, Nginx Plus, AWS Application Load Balancer
- Project site
- nginxproxymanager.com
- Source
- github.com/NginxProxyManager/nginx-proxy-manager
- Documentation
- nginxproxymanager.com/guide
Alternatives to Nginx Proxy Manager#
Everything else in networking, dns and remote access, closest in operational weight first.
| Tool | Ops load | Idle RAM | Licence |
|---|---|---|---|
| AdGuard Home | 2, Light | 60 MB | GPL-3.0 |
| Pi-hole | 2, Light | 100 MB | EUPL-1.2 |
| wg-easy | 2, Light | 90 MB | AGPL-3.0-only |
| Caddy | 1, Set and forget | 25 MB | Apache-2.0 |
| Headscale | 3, Moderate | 40 MB | BSD-3-Clause |
| Technitium DNS Server | 3, Moderate | 130 MB | GPL-3.0 |
Where Nginx Proxy Manager comes up elsewhere#
Research
Sources#
Facts on this page were checked against the project's own material. Where a number is our own estimate rather than a published figure, the text says so.
Published . Last reviewed . Found something out of date? Tell us and we will fix it and log the change.