Open-source project
NginxProxyManager/nginx-proxy-manager avatar
NginxProxyManager/nginx-proxy-manager

Nginx Proxy Manager: port 81 in the compose file, armv7 left behind at 2.13.7

Docker container for managing Nginx proxy hosts with a simple, powerful interface

34,294 stars3,920 forksTypeScriptMIT

At a glance

What is it?
Nginx Proxy Manager ships as a pre-built Docker image that puts a Tabler admin interface in front of Nginx proxy hosts, with free SSL from Let's Encrypt. The quick start publishes port 81, the image tag floats as latest, and armv7 boards are told to stay on 2.13.7.
Who is it for?
Nginx Proxy Manager suits someone who wants to add a reverse proxy host with a certificate in a browser, and who can accept that the admin interface is the configuration rather than a file. It does not suit a deployment that must keep its proxy definitions in a repository, or a 32-bit armv7 board, which the project tells you to pin at the 2.13.7 image tag.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The compose file publishes port 81, and the router guide says forward 80 and 443

The quick start compose file maps three ports to the container:

yml
services:
  app:
    image: 'docker.io/jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '80:80'
      - '81:81'
      - '443:443'
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Ports 80 and 443 are the obvious pair, since that is where HTTP and TLS traffic lands. The third line is the one to think about, because the admin interface is served on port 81 and the mapping exposes it on the same address as everything else. The project states two different things in two different sections. The home network walkthrough says to add port forwarding for ports 80 and 443 to the server hosting the project, and says nothing about forwarding 81. Take that as the intent: the admin interface is reached on the LAN, and 81 does not belong in a router rule.

The mapping is also unaddressed, so the container's port 81 binds to every interface the Docker host has. If something else on the same machine needs 81, the stack will not come up at all.

Two mounted directories hold everything, and the tag says latest

Everything the container keeps lives under the two volumes in that file. ./data is mounted at /data, which is where the application state and its SQLite database go, and ./letsencrypt is mounted at /etc/letsencrypt, which is where certificates are written. Nothing else in the quick start is persisted, so those two host directories are the entire backup surface. Losing ./letsencrypt means reissuing every certificate; losing ./data means re-creating every proxy host, user and access list by hand.

The image line is where a deployment gets a surprise. The tag is latest, not a version, so the image you run is whatever was last pushed to Docker Hub, and a later docker compose pull or a recreate can move you to a new version without any change on your side. The project itself demonstrates that version pinning matters: its warning about armv7 tells you to use the 2.13.7 image tag rather than the newest one. The same discipline applies everywhere else, and the releases page is where the tag list comes from, with v2.16.0 published on 2026-09-24.

armv7 stopped at 2.13.7 because Node dropped armhf

One architecture is explicitly out of the upgrade path. The README carries a warning that armv7 is no longer supported in version 2.14+, that this is due to Nodejs dropping support for armhf, and that you should use the 2.13.7 image tag if that applies to you.

The cause is worth understanding because it is not project specific. The application is TypeScript, and the Node runtime underneath it dropped 32-bit ARM, so the image can no longer be built for that target. Nothing in the fix path is offered: there is no replacement image and no configuration change, only an older tag. For anyone running one of these boards as a home lab reverse proxy, the practical consequence is that your install is now frozen at a 2022 era version with no further security or feature work, and the honest question is whether to move to a 64-bit machine instead. The README does not say when 2.13.7 was released or how long it will keep running, so that is a decision you make with the dates in front of you.

The first login can look like a hang, because of key entropy

Once the container runs, the admin interface is on port 81, and the README links http://127.0.0.1:81 as the place to connect. It then warns that this can take a little bit, because of the entropy of keys. That is a first boot cost: the container is generating its keys when it generates them, and on a host with a low entropy pool the wait is longer than a curl or a browser tab is willing to look like.

Two practical notes. Check that the container is up before concluding that the UI is broken, and note that the README does not state the initial username and password for that interface, so plan to get them from the project documentation or the container output rather than assuming a value. The point about entropy also lands on constrained hardware, which is the same class of machine as the armv7 boards in the previous section. A Raspberry Pi class host on a fresh image is exactly where a slow first boot turns into a false diagnosis.

The stated goal is a low barrier, and the advanced tab is the concession

The project states its own design constraint plainly. It was created to give users an easy way to accomplish reverse proxying hosts with SSL termination, and the requirement was that it be so easy that a beginner could do it. That goal is described as unchanged, with the caveat that while there might be advanced options, they are optional and the project should stay as simple as possible so the barrier to entry is low.

The feature list follows from that. An admin interface based on Tabler, forwarding domains, redirections, streams and 404 hosts created without knowing anything about Nginx, free SSL from Let's Encrypt or your own custom certificates, access lists and basic HTTP authentication, user management with permissions and an audit log, and advanced Nginx configuration for super users. That last item is the concession: the escape hatch exists, and it is gated behind a role rather than exposed as the default.

What the goal implies for a team is more important than the feature list. The configuration lives in the application, not in a file you can read in a pull request, and the repository root holds backend/, frontend/, docker/, docs/, scripts/ and test/ rather than a set of Nginx templates. The README describes no export or import of proxy definitions, so treating this as infrastructure as code means finding another way in.

Pull requests target develop, and the default branch is develop

The contribution model is worth reading before you clone. Pull requests are welcome against the develop branch, official releases are created from the master branch, and the repository's default branch is develop. So a plain clone of the project gives you the development line, not the line the released images are built from, and a contributor reading the code on the default branch is reading code that has not shipped.

The rest of the process is spelled out. CI is used and all pull requests must pass before being considered, and after passing, Docker builds for pull requests are published to Docker Hub so a change can be verified by hand before it is merged. Documentation inside the develop branch is previewable at develop.nginxproxymanager.com, which is the site to read when you need to know what the next release will change. Support runs through GitHub issues, GitHub discussions and the subreddit, in that order.

For an operator, the practical takeaway is that the documentation you find in a search result may describe either line. Check which branch a docs page was built from before you follow its instructions against a running container, because the released images follow master and the docs you are reading may not.

Home deployments need a router rule and a dynamic DNS answer

The project explains the home network case in four steps, and two of them are outside its own control. Your home router has a port forwarding section, so you log in and add forwarding for ports 80 and 443 to the machine running the project. Then the domain has to point at your home, either through a static IP or through a service: DuckDNS, Amazon Route53 with the route53-ddns helper linked from the README, or Cloudflare with the cloudflare-ddns helper. Only the fourth step is inside the application, using Nginx Proxy Manager as the gateway that forwards to your other web based services.

The consequence is that this is not a single container install. Certificate issuance for a domain you do not own a static IP for depends on the DNS record pointing back at you, so a dynamic DNS helper failing quietly presents as a renewal problem rather than a DNS problem. And the two port forwards are the whole public surface of your home network, which is a larger decision than installing a proxy. Read the step list as the dependency graph for the feature, not as optional background.

Editorial conclusion

Nginx Proxy Manager suits someone who wants to add a reverse proxy host with a certificate in a browser, and who can accept that the admin interface is the configuration rather than a file. It does not suit a deployment that must keep its proxy definitions in a repository, or a 32-bit armv7 board, which the project tells you to pin at the 2.13.7 image tag. Before you deploy: forward only ports 80 and 443 on the router and leave 81 unexposed, replace the floating latest tag with the version you tested, confirm ./data and ./letsencrypt are on the backup schedule because they are the only two paths the quick start persists, and check whether v2.16.0, released 2026-09-24, changes anything you depend on.

Frequently asked questions

What is the nginx proxy manager used for?

It is a pre-built Docker image for forwarding to websites running at home or elsewhere, including free SSL, without needing much knowledge of Nginx or Let's Encrypt. From its admin interface you create forwarding domains, redirections, streams and 404 hosts, set access lists and basic HTTP authentication, and manage users, permissions and an audit log.

How do I install nginx proxy manager?

Install Docker, create a docker-compose.yml with the image 'docker.io/jc21/nginx-proxy-manager:latest' and the ports and volumes shown in the quick setup, then run `docker compose up -d`. The compose file is described as the bare minimum configuration required.

How do I access nginx proxy manager?

Connect to port 81 of the running container, at http://127.0.0.1:81. The first connection can take a little while because of the entropy of keys, so a slow first response is expected rather than a fault.

How do I set up nginx proxy manager with cloudflare?

The README lists Cloudflare among the services you can use to point a domain at a home connection that has no static IP, alongside DuckDNS and Amazon Route53, and links a cloudflare-ddns helper for it. From there Nginx Proxy Manager acts as the gateway forwarding to your other web services.

How do I back up nginx proxy manager?

The quick start compose file persists only two host paths, ./data mounted at /data and ./letsencrypt mounted at /etc/letsencrypt, so those directories hold everything the container keeps, including the certificates. The README does not document an export or backup command beyond those volumes.

How do I use nginx proxy manager?

Log in to the admin interface on port 81, create a proxy host for the service you want to reach, and let it obtain a free SSL certificate through Let's Encrypt or supply your own custom certificate. Advanced Nginx configuration is available for super users when the defaults are not enough.

Official sources

  1. Official documentation
  2. Official README
  3. Project repository
  4. Release notes
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nginxproxymanager-nginx-proxy-manager.svg)](https://hysenlabs.com/projects/nginxproxymanager-nginx-proxy-manager)