How to Install Nginx Proxy Manager with Docker Compose

Nginx Proxy Manager is one of the easiest ways to stop juggling ugly :3000 and :8080 URLs on self-hosted apps. Instead of hand-editing reverse proxy config files right away, you get a browser-based dashboard that helps you point a domain at an app, add HTTPS, and keep several services organized without turning your evening into an accidental Nginx certification course.

In this guide, you will install Nginx Proxy Manager with Docker Compose, open the admin interface, understand what the key ports and folders do, and create the foundation you will use for cleaner app URLs later.

Why self-host Nginx Proxy Manager?

If you run more than one web app, a reverse proxy quickly goes from “nice later” to “please save me now.”

Nginx Proxy Manager helps because it gives you:

  • one place to manage public-facing app domains

  • free HTTPS certificates through Let's Encrypt

  • a simpler UI for forwarding traffic to apps on different local ports

  • access lists, redirects, and a few other practical controls

  • less manual Nginx editing when you are still learning the basics

The official project describes it as a pre-built Docker image that makes it easier to forward traffic to your sites and apps, including free SSL, without needing deep Nginx knowledge first. That beginner-friendly angle is exactly why it belongs early in a self-hosting stack.

Is a VPS a good fit for Nginx Proxy Manager?

Usually, yes.

A small VPS is enough for many beginner setups if your main job is:

  • receiving traffic on ports 80 and 443

  • forwarding requests to a handful of self-hosted apps

  • requesting and renewing HTTPS certificates

You may want a larger server later if the same box is also running several heavier apps, databases, or media services. But for getting started, Nginx Proxy Manager itself is not usually the thing that crushes your server.

Docker also makes this easier because the official project already ships as a container image and publishes a straightforward Compose example.

What you'll need

Before you start, have these ready:

  • a VPS or server running Linux

  • SSH access to the server

  • a user account with sudo access

  • Docker installed and working

  • ports 80 and 443 available on the server

  • a domain name you can point at the server later

  • one web app to proxy eventually, such as something running on port 3000 or 8080

If Docker is not installed yet, start here first:

Reality check: Nginx Proxy Manager does not magically make a domain work if your DNS is wrong or your router/firewall blocks ports 80 and 443. It makes the proxy side much easier, but the surrounding network pieces still matter.

Before you start

All commands in this tutorial are run on your server over SSH, not on your home laptop unless that laptop is the machine hosting your apps.

If you are brand new to this, the flow is:

  1. connect to the server with SSH

  2. create an app folder

  3. start the Docker Compose stack

  4. open the web UI in your browser

  5. later, point a domain at your server and create proxy hosts

For a first install, the simplest path is the official SQLite-backed setup. The Nginx Proxy Manager docs also show MySQL and MariaDB options, but SQLite is the more beginner-friendly starting point unless you already know you need a separate database.

How the official quick-start is structured

The project's official README shows a very small Compose stack with:

  • the jc21/nginx-proxy-manager:latest image

  • ports 80, 81, and 443

  • a data volume for app data

  • a letsencrypt volume for certificates

The setup docs also mention an optional DB_SQLITE_FILE setting and an optional DISABLE_IPV6 flag if IPv6 is not enabled on your host.

I prefer that beginner path: start with the simple stack first, confirm the dashboard loads, and only then get fancy.

Step 1: Connect to your server

Use SSH from your local machine.

ssh your-user@your-server-ip

Replace:

  • your-user with your Linux username

  • your-server-ip with your server's public IP address

If this is your first login, SSH may ask whether you trust the host fingerprint. That is normal on the first connection.

If this fails with Permission denied, double-check the username, SSH key, or password you are using.

Step 2: Update package lists on the server

Refresh the server before adding more moving parts.

sudo apt update

If your server also has pending package upgrades, install them.

sudo apt upgrade -y

This helps reduce the chance that you debug something weird later that is really just an outdated base system.

Step 3: Create a folder for Nginx Proxy Manager

Keeping each app in its own folder makes updates and backups much less annoying.

sudo mkdir -p /opt/nginx-proxy-manager

Now move into that folder.

cd /opt/nginx-proxy-manager

If you created the folder with sudo, give your normal user ownership so you can edit files without fighting permissions all day.

sudo chown "$USER":"$USER" /opt/nginx-proxy-manager

Step 4: Create folders for app data and certificates

The official examples persist Nginx Proxy Manager data and Let's Encrypt files outside the container.

mkdir -p data letsencrypt

Those folders matter because they hold the settings and certificates you do not want to lose every time a container is recreated.

Step 5: Create the compose.yaml file

Create the Compose file with the official quick-start shape.

cat > compose.yaml <<'EOF'
services:
  app:
    image: docker.io/jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "81:81"
      - "443:443"
    environment:
      TZ: "Etc/UTC"
      # Uncomment this if you want to change the SQLite DB file location:
      # DB_SQLITE_FILE: "/data/database.sqlite"
      # Uncomment this if IPv6 is not enabled on your host:
      # DISABLE_IPV6: "true"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
EOF

What each important part does

image: docker.io/jc21/nginx-proxy-manager:latest

This is the official Docker image used in the project's quick-start documentation.

Port 80:80

This handles normal HTTP traffic and is also important for some certificate validation flows.

Port 81:81

This is the admin dashboard port. The official README says to connect to port 81 for the admin interface after the container is running.

Port 443:443

This handles HTTPS traffic for the sites and apps you proxy through Nginx Proxy Manager.

./data:/data

This stores application data, including the internal SQLite database in the default simple setup.

./letsencrypt:/etc/letsencrypt

This stores certificate material so renewals and existing certs survive container recreation.

TZ: "Etc/UTC"

Set your server timezone here if you want logs and timestamps to reflect your local region.

Step 6: Start Nginx Proxy Manager

Now start the stack.

docker compose up -d

Docker will pull the image the first time, so this may take a minute.

When it finishes, check the container state.

docker compose ps

You want to see the service running rather than crashing in a loop.

If it keeps restarting, check the logs next.

docker compose logs --tail=100

Step 7: Open the admin interface

Once the container is up, open this address in your browser to create the admin account and access the dashboard:

http://your-server-ip:81

If the page does not load yet, wait a moment and refresh. The official project notes that the first startup can sometimes take a little longer.

Now I am creating the admin user...

...and I am on the dashboard.

At this stage, your dashboard may still be using a raw IP address and the :81 port, which is fine. The point of this install is to get the management layer working before you ask it to front your other apps.

Step 8: Point your domain to the server

Before you can create a useful proxy host for app.yourdomain.com, the DNS record needs to point at this server.

A common beginner setup is:

  • create an A record for a subdomain like app.yourdomain.com

  • point it to your server's public IPv4 address

  • wait for DNS to update

If your DNS is not pointing at the server yet, Nginx Proxy Manager cannot finish the illusion of effortless magic because the internet still needs to know where your server lives.

Step 9: Create your first proxy host

Once the dashboard opens and DNS is ready, you can add a proxy host for one of your apps.

The basic idea is:

  • domain: app.yourdomain.com

  • forward hostname or IP: the machine running the target app

  • forward port: the app's local port, such as 3000, 8080, or 8096

  • scheme: usually http for many internal app containers

This is the first moment where Nginx Proxy Manager becomes genuinely satisfying. Your messy internal app port stays messy on the inside, and your public-facing URL becomes civilized.

Step 10: Request HTTPS with Let's Encrypt

After your domain resolves correctly, open the SSL options for the proxy host and request a certificate.

In plain English, that means:

  • tell Nginx Proxy Manager which domain belongs to this app

  • let it prove domain control through the normal validation flow

  • have it create and renew a certificate for you

If this step fails, the most common causes are:

  • DNS is not pointing at the server yet

  • ports 80 or 443 are blocked

  • another service is already occupying those ports

  • the domain record is wrong

Optional: Use a dedicated database later

The official setup docs also show MySQL and MariaDB examples.

That path can make sense if you:

  • already run a small database stack for other services

  • want more control over how Nginx Proxy Manager stores data

  • are building a more customized environment

For a first deployment, though, the default SQLite-backed setup is simpler and usually the better call.

Common problems and quick fixes

Port 80 or 443 is already in use

Check what is listening first.

sudo ss -tulpn | grep -E ':80|:81|:443'

If Apache, plain Nginx, or another reverse proxy is already bound to those ports, stop or rework that service before expecting Nginx Proxy Manager to start cleanly.

The admin page on port 81 will not open

First confirm the container is still running.

docker compose ps

Then inspect recent logs.

docker compose logs --tail=100

Also confirm your VPS firewall or cloud provider firewall allows the traffic you expect.

HTTPS certificate requests fail

Usually this is a DNS or port-reachability issue, not a mysterious curse from the certificate gods.

Check that:

  • the domain resolves to your server's public IP

  • ports 80 and 443 are open

  • your router is forwarding those ports correctly if this is a home setup

  • you did not point the domain at the wrong host

The proxied app itself does not load

Make sure the target app is actually reachable from the Nginx Proxy Manager host on the forward port you entered.

For example, if your app is supposed to be on port 3000, test that locally on the server first.

curl http://127.0.0.1:3000

If that fails, the problem is probably the app or container behind the proxy, not Nginx Proxy Manager itself.

How to update Nginx Proxy Manager

A safe routine update looks like this.

Pull the latest image.

docker compose pull

Recreate the stack with the new image.

docker compose up -d

Confirm it is healthy afterward.

docker compose ps

Because your data and certificates live in mounted folders, this update flow is much less scary than manually reinstalling everything.

How to back it up

For a simple deployment, the most important things to back up are:

  • /opt/nginx-proxy-manager/data

  • /opt/nginx-proxy-manager/letsencrypt

Those folders hold the app data and certificate files that make your setup worth keeping.

A straightforward archive example looks like this:

sudo tar -czf /root/nginx-proxy-manager-backup.tar.gz /opt/nginx-proxy-manager/data /opt/nginx-proxy-manager/letsencrypt

If you are already backing up your entire app directories, make sure these paths are included.

How to remove it

If you decide you do not want Nginx Proxy Manager on this server after all, stop and remove the stack.

docker compose down

If you also want to delete the persisted data and certificates, remove the folders afterward.

rm -rf /opt/nginx-proxy-manager/data /opt/nginx-proxy-manager/letsencrypt

Only run that second command if you are sure you no longer need the saved configuration or certificates.

You're done

You now have Nginx Proxy Manager running in Docker Compose, with persistent storage for app data and certificates, and a dashboard ready to manage reverse proxy rules. The next practical step is to put one real app behind it, request HTTPS, and start replacing those awkward port-number URLs with proper domains that look like you planned this all along.

Frequently Asked Questions

Do I need Nginx experience before using Nginx Proxy Manager?
No. That is the main appeal of Nginx Proxy Manager. It gives you a web UI for common reverse proxy tasks so you can point domains at apps and request HTTPS certificates without hand-writing full Nginx server blocks.
Can I use Nginx Proxy Manager on a small VPS?
Yes. A small VPS is usually enough for a modest set of web apps as long as you are not also piling on heavy databases, media workloads, or very high traffic.
Does Nginx Proxy Manager require a separate database?
Not for a basic setup. The official setup docs show a simple SQLite-backed configuration as the easy starting point, while larger or more customized deployments can use MySQL or MariaDB instead.

Related articles

🔁
Reverse Proxies
How to Use Caddy as a Reverse Proxy for Self-Hosted Apps
Use Caddy with Docker Compose to put a self-hosted app behind one clean domain name, add automatic HTTPS, and keep the setup simple enough to maintain.
📊
Monitoring
How to Install Uptime Kuma with Docker Compose
Install Uptime Kuma with Docker Compose on a Linux server, create your first admin account, and start monitoring websites or services from a simple web dashboard.
🐳
Docker & Containers
Docker Compose for Self-Hosted Apps: A Beginner-Friendly Guide
Learn how to use Docker Compose for self-hosted apps, including folder layout, compose files, environment variables, volumes, safe restarts, and basic update habits.
🎬
Media Servers
How to Install Immich with Docker Compose
Install Immich with Docker Compose on a Linux server, set up storage paths safely, start the stack, and finish the first web-based admin setup.