Install Nginx Proxy Manager with Docker Compose and Let's Encrypt on Ubuntu

Updated on Aug 24, 2026
Mila H
7 MINS READ
Table of Contents
Nginx Proxy Manager Docker Compose

If you are running multiple apps on a single VPS and need a way to route traffic to each one with HTTPS, Nginx proxy manager Docker Compose is one of the easiest setups you can do. Instead of writing Nginx config files or dealing with Certbot manually, Nginx Proxy Manager (NPM) gives you a simple web dashboard where you can add proxy hosts, request free SSL certificates from Let's Encrypt, and manage everything in a browser.

What Is Nginx Proxy Manager?

Nginx Proxy Manager is a free tool that wraps Nginx inside a friendly web GUI. It handles reverse proxy configuration, free SSL certificate generation via Let's Encrypt, redirects, access lists, and more, all without touching a single config file.

It is a great choice if you want:

  • A GUI-based reverse proxy you can manage without SSH every time.
  • Automatic Let's Encrypt SSL certificates with zero manual renewal.
  • A beginner-friendly alternative to Traefik or Caddy for single-server setups.
  • Support for WebSocket-based apps like Nextcloud, Vaultwarden, and Home Assistant.

Compared to Traefik or Caddy, NPM is the easiest option. Traefik has better Docker auto-discovery via labels. Caddy has simpler config files. For most self-hosted single-server setups, NPM is the best starting point. If you prefer a label-driven approach, you can check out our guide on setting up Traefik with Docker Compose.

Prerequisites for Nginx Proxy Manager Docker Compose Setup

Before you start, make sure you have the following ready:

  • A fresh Ubuntu 22.04 or 24.04 VPS.
  • Root or sudo access.
  • Docker and Docker Compose are installed.
  • A domain name with DNS access.
  • Ports 80, 81, and 443 are not in use by another service.
  • Your server's public IP address is ready.

Step 1. Install Docker on Ubuntu

First, update your system and install the required packages:

Bash
sudo apt update && sudo apt upgrade -ysudo apt install apt-transport-https ca-certificates curl software-properties-common -y

Add Docker's official GPG key and repository:

Bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpgsudo chmod a+r /etc/apt/keyrings/docker.gpg echo \  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Now install Docker Engine and the Compose plugin:

Bash
sudo apt updatesudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y

Verify Docker is running:

Bash
sudo systemctl status dockersudo docker run hello-world

To run Docker without sudo, add the user to the Docker group:

Bash
sudo usermod -aG docker $USERnewgrp docker

Step 2. Configure DNS Records

Before you deploy anything, your domain needs to point to your server. Log in to your DNS provider and create an A record for each subdomain you plan to use:

Type Name Value
A app Your server's public IP
A git Your server's public IP
A @ Your server's public IP

DNS changes can take a few minutes to a few hours to propagate. You can check with:

Bash
dig +short app.yourdomain.com

It should return your server's IP. Let's Encrypt will fail to issue a certificate if DNS is not pointing to your server at the time of the request.

Step 3. Open Firewall Ports

If UFW is active on your server, you need to allow the three ports that Nginx proxy manager Docker Compose uses:

Bash
sudo ufw allow 80    # HTTPsudo ufw allow 443   # HTTPSsudo ufw allow 22    # SSH (make sure this is allowed first!)sudo ufw reload

Security note: Port 81 (the admin UI) should not be opened in the firewall. You will access it via an SSH tunnel or restrict it to 127.0.0.1 in the Compose file. Exposing it to the internet is a security risk.

Check the firewall status:

Bash
sudo ufw status verbose

Step 4. Create the Docker Compose File

At this point, you must create a dedicated directory for NPM and move into it:

Bash
mkdir -p ~/nginx-proxy-managercd ~/nginx-proxy-manager

Create the Nginx proxy manager Docker Compose YAML file:

Bash
nano docker-compose.yml

Paste the following configuration:

YAML
services:  app:    image: 'jc21/nginx-proxy-manager:latest'    restart: unless-stopped    ports:      - '80:80'      - '443:443'      - '127.0.0.1:81:81'   # Admin UI — localhost only (secure)    volumes:      - ./data:/data      - ./letsencrypt:/etc/letsencrypt
  • image: jc21/nginx-proxy-manager:latest: pulls the official NPM image
  • restart: unless-stopped: NPM restarts automatically after a reboot.
  • 80:80 and 443:443: public HTTP and HTTPS ports.
  • 127.0.0.1:81:81: binds the admin UI to localhost only, keeping it off the internet.
  • ./data:/data and ./letsencrypt:/etc/letsencrypt: persistent storage so your config and certs survive container updates.

Step 5. Start Nginx Proxy Manager Docker Compose

Now bring up the container in detached mode:

Bash
docker compose up -d

Check that it is running:

Bash
docker compose psdocker compose logs app

You should see the container status as Up.

Step 6. Access to Nginx Proxy Manager Admin Panel

The Nginx proxy manager Docker Compose setup uses port 81 for the admin interface. Since it is bound to 127.0.0.1, you must open an SSH tunnel from your local machine:

Bash
ssh -L 8181:127.0.0.1:81 your_user@your_server_ip

Then open your browser and go to:

Bash
http://localhost:8181

Create your admin account:

Nginx Proxy Manager Login

Step 7. Add a Proxy Host and Enable Let's Encrypt SSL

This is the core feature of the Nginx proxy manager Docker Compose setup. A proxy host tells NPM where to forward incoming traffic for a given domain.

Once you access the NPM dashboard, click Hosts > Proxy Hosts and click Add Proxy Host.

Add Proxy Host in NPM

Fill in the Details tab with:

Field What to enter
Domain Names app.yourdomain.com
Scheme http
Forward Hostname / IP Container name or host Docker bridge IP, for example, 172.17.0.1
Forward Port The internal port your app runs on, for example, 3000
Block Common Exploits Enable ✓
Websockets Support Enable if your app needs it ✓

Finding the Docker bridge IP if your app runs in another container:

Bash
ip addr show docker0# Usually 172.17.0.1

Or, if your app is on the same Docker network as NPM, use the container service name directly as the hostname.

Now switch to the SSL tab:

  • SSL Certificate > select Request a new SSL Certificate.
  • Enable Force SSL to redirect HTTP to HTTPS automatically.
  • Enable HTTP/2 Support.
  • Enable HSTS, optional but recommended.
  • Click Save.

NPM will reach out to Let's Encrypt, complete the HTTP-01 challenge, and install the certificate automatically. This usually takes about 10 to 30 seconds.

Certificates renew automatically. Let's Encrypt certificates expire every 90 days, but NPM renews them without any cron jobs or manual steps needed.

Set SSL on Nginx

Step 8. Connect Apps on the Same Docker Network

The best way to use the Nginx proxy manager Docker Compose stack is to put NPM and your apps on a shared Docker network. This lets you use container names as hostnames instead of IP addresses.

Update your NPM Docker Compose YAML file:

YAML
services:  app:    image: 'jc21/nginx-proxy-manager:latest'    restart: unless-stopped    ports:      - '80:80'      - '443:443'      - '127.0.0.1:81:81'    volumes:      - ./data:/data      - ./letsencrypt:/etc/letsencrypt    networks:      - proxy networks:  proxy:    name: proxy    driver: bridge

And in your app's docker-compose.yml, attach it to the same network:

YAML
services:  myapp:    image: myapp:latest    networks:      - proxy networks:  proxy:    external: true

Now in NPM's proxy host, set Forward Hostname / IP to myapp, and it resolves directly via Docker DNS.

Update and Maintain NPM

Keeping Nginx proxy manager Docker Compose up to date is easy. To do this, you can use the commands below:

Bash
cd ~/nginx-proxy-managerdocker compose pulldocker compose up -d

Your configuration, proxy hosts, and certificates are stored in the ./data and ./letsencrypt volumes and survive updates.

To back up your NPM data, you can use:

Bash
docker compose downtar czf npm-backup-$(date +%F).tar.gz data letsencryptdocker compose up -d

For the official documentation and latest Docker image tags, you can visit the Nginx Proxy Manager official documentation.

Conclusion

The Nginx proxy manager Docker Compose combination is one of the fastest ways to get a reverse proxy running on a Linux VPS. You get a GUI, automatic Let's Encrypt SSL, and persistent storage, all without touching a single Nginx config file. Whether you are self-hosting a few small apps or building a full stack, this setup handles it well and stays easy to manage as you grow.

For anything more complex, like label-based auto-discovery or multi-server setups, you can always migrate to Traefik later.

If you need a fresh Linux VPS for your reverse proxy and app stack, you can start with a PerLod Linux VPS.

Yes. Put NPM and your apps on the same Docker network and use container names as the forward hostname.

NPM is GUI-based and beginner-friendly. Traefik auto-discovers Docker services via labels and is better for larger automated setups.

Yes. NPM handles Let's Encrypt renewal automatically, no cron jobs needed.