·4 min read

Nginx Proxy Manager: Reverse Proxy + SSL in Minutes

How I use Nginx Proxy Manager to front all my self-hosted services with Let's Encrypt SSL and subdomain routing — no manual nginx config files.

NetworkingSSLSelf-hostedDocker

Running 20+ Docker services on a home server means you quickly tire of remembering port numbers. Nginx Proxy Manager (NPM) solves this with a web GUI that provisions subdomains, terminates SSL, and proxies traffic to internal containers — all without writing a single nginx config file by hand.

The problem it solves

Without a reverse proxy, accessing services means hitting IP:PORT directly. That means no SSL, no meaningful hostnames, and opening a separate port for every service. Instead, NPM sits in front of everything on ports 80 and 443, routes requests by subdomain, and handles TLS termination using Let's Encrypt certificates it manages automatically.

yaml
# docker-compose.yml for NPM
services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    ports:
      - "80:80"
      - "443:443"
      - "81:81"   # admin UI
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

Setting up a new proxy host

In the NPM GUI, you create a 'Proxy Host': set the public subdomain (immich.domain.com), the internal hostname (the Docker container name or IP), and the internal port. Flip on 'SSL' and it requests a Let's Encrypt certificate and auto-renews it. The whole process takes under two minutes per service.

  • Wildcard certificates via DNS challenge mean one cert covers all subdomains
  • Access lists let you restrict services to local network only
  • HTTP/2 and WebSocket support work out of the box
  • Logs per-proxy-host make debugging 502s straightforward

DNS setup

For internal-only services, I use a local DNS override in Pi-hole that points *.internal.domain.com to the NPM server IP. For publicly accessible services, real DNS A records point to the external IP with port forwarding on the router.

Note:Pair NPM with TinyAuth for SSO in front of services that lack built-in authentication. TinyAuth adds a login wall to any proxy host with a few extra headers.