LIVEReading: Run a Reverse Proxy with Free SSL in 10 MinutesTotal time: 8 minSteps: 5Worked first time: 78% LIVEReading: Run a Reverse Proxy with Free SSL in 10 MinutesTotal time: 8 minSteps: 5Worked first time: 78%
CBW
Run a Reverse Proxy with Free SSL in 10 Minutes
Mediumgithub.com/nginxproxymanager/nginx-proxy-manager2026-06-21

Run a Reverse Proxy with Free SSL in 10 Minutes

Nginx Proxy Manager gives you a web dashboard to route traffic to your home services and add free SSL certificates — no Nginx knowledge needed. Runs entirely in Docker.

// Build stats

  • Total time8 min
  • Number of steps5
  • DifficultyMedium
  • Worked first time78%
// Before you start

What you need

  • A Linux machine, VPS, or home server (Windows with WSL2 also works)
  • Docker and Docker Compose installed
  • Port 80 and 443 open on your router or firewall
  • A domain name pointed at your server's IP (or a free DuckDNS subdomain)
  • Basic comfort opening a terminal and running commands
01
Step 1 of 5

Create a project folder

1 min

We need one dedicated folder to hold the config file and all data Nginx Proxy Manager saves. Keeping it separate makes backups and upgrades much easier.

Terminal · mac
$ mkdir ~/nginx-proxy-manager && cd ~/nginx-proxy-manager
What you should see
No output — your terminal prompt changes to show the new folder path.
02
Step 2 of 5

Create the docker-compose file

2 min

This file tells Docker exactly which image to run, which ports to open, and where to store data. Port 80 and 443 handle real web traffic. Port 81 is the private admin dashboard — never expose port 81 to the public internet.

Terminal · mac
$ cat > docker-compose.yml << 'EOF'
$ 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
$ EOF
What you should see
No output. Run `cat docker-compose.yml` to confirm the file looks correct.
This might happen

Port 80 or 443 is already in use by another service (Apache, Caddy, etc.)

Stop the conflicting service first: `sudo systemctl stop apache2` or equivalent. Only one service can own a port at a time.

03
Step 3 of 5

Start the container

2 min

Docker will pull the image from the internet (about 100 MB) and start it in the background. The `-d` flag means it runs detached — your terminal stays free.

Terminal · mac
$ docker compose up -d
What you should see
You should see lines like `Pulling app ...`, then `Container nginx-proxy-manager-app-1 Started`. Run `docker compose ps` to confirm the status shows `running`.
This might happen

`docker compose` command not found — you may have the older `docker-compose` (with a hyphen) installed

Replace `docker compose` with `docker-compose` in every command, e.g. `docker-compose up -d`.

04
Step 4 of 5

Log in to the admin dashboard

2 min

Open a browser and go to your server's IP address on port 81. If you are on the same machine, use localhost. The first login uses default credentials that you must change immediately after.

Terminal · mac
$ open http://localhost:81
What you should see
A login page appears. Use email `admin@example.com` and password `changeme`. You will be prompted to update both immediately — do it.
This might happen

The page doesn't load right away

Wait 30–60 seconds after starting the container — it generates encryption keys on first boot. Then refresh.

05
Step 5 of 5

Add your first proxy host with SSL

5 min

In the dashboard, click 'Hosts' → 'Proxy Hosts' → 'Add Proxy Host'. Enter your domain name (e.g. app.yourdomain.com), set the Forward Hostname to the local IP of the service you want to proxy (e.g. 192.168.1.50) and its port. Then click the 'SSL' tab, choose 'Request a new SSL Certificate', tick 'Force SSL', and save. Nginx Proxy Manager contacts Let's Encrypt automatically.

Terminal · mac
$ # This step is done entirely in the web dashboard — no commands needed.
What you should see
The proxy host row shows a green SSL padlock icon. Visiting your domain in a browser should load your service over HTTPS.
This might happen

SSL certificate request fails with a Let's Encrypt error

Your domain must publicly resolve to this server's IP and port 80 must be reachable from the internet. Check your DNS records and router port forwarding before retrying.

// Status

cooked. baked. worked.

A running web dashboard at port 81 where you can point any domain at any internal service and get a valid HTTPS certificate in a few clicks — no Nginx config files required.

// the honest bit

The honest part

This guide covers the quick-start path only. Nginx Proxy Manager can also handle redirects, stream proxies, access lists, and custom Nginx config — but those require reading the official docs. Free Let's Encrypt SSL only works if your server is publicly reachable on port 80; it will not work on a fully private network without DNS challenge setup. The armv7 architecture (older Raspberry Pi models) is not supported in versions 2.14 and above — use image tag `2.13.7` if that applies to you. Never expose port 81 to the public internet.