Self-Hosting·7 min read·

Self-Hosted Stacks: Put a Reverse Proxy First

Route every self-hosted app through one Nginx Proxy Manager entry point so TLS, hostnames, and access rules stay consistent as your stack grows.

NB

Netbay Engineering

Netbay Engineering

On this page

The moment a homelab grows past two or three things, the ports begin to fight. Every dashboard wants port 8080, every app has its own UI on some random 4-digit port, and you eventually memorize an address book just to reach your own services. A reverse proxy collapses all of that into a single, predictable entry point: one IP, port 80 and 443, and hostnames that mean something. Nginx Proxy Manager (NPM) is the friendliest way to get there because it wraps the underlying Nginx behavior behind a web UI, yet still lets you see exactly what is happening under the hood.

One entry point for the whole stack CLIENT one IP, 80/443 NGINX PROXY MGR TLS, hostnames access control media.example git.example notes.example hostname routing fans out to any internal service

Why Hostnames Beat Ports

Port-based access chains you to the port forever. Move an app to a different port to fix a conflict and every bookmark is now wrong. With a proxy you give each app a subdomain, and the proxy keeps the "one port to this service" mapping private and internal. The public URL stays stable while the underlying port can change freely during maintenance. It also means exactly one way in: your firewall can drop everything except 80 and 443, and every piece of public behavior lives in one config surface.

Installing Nginx Proxy Manager

NPM ships as a Docker container with its own database and admin UI. On a Ubuntu host with Docker installed, a compose file keeps it reproducible:

yaml
services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
    networks:
      - proxy
networks:
  proxy:
    name: proxy

The compose file mounts two volumes so your proxy config and certificates survive container rebuilds, and puts NPM on a named network called proxy. Remember to set a strong password and change the default admin email on first login at port 81.

Wiring Up a Real App

Once NPM is up, connect your other services to the same proxy network. This is the key architectural move: NPM can only forward to a container by name if both are on the same user-defined bridge network. Bring an app like Uptime Kuma onto that shared network, then register it in NPM.

yaml
services:
  uptime:
    image: louislam/uptime-kuma:1
    restart: unless-stopped
    networks:
      - proxy
    volumes:
      - ./data:/app/data
networks:
  proxy:
    external: true

In the NPM dashboard you then create a Proxy Host: choose a domain, set Forward Hostname to the container name uptime, Forward Port to 3001, and request a Let's Encrypt certificate. NPM handles the ACME flow and TLS termination, and the request path becomes client -> NPM -> uptime:3001 with no other port open to the world.

Access Lists, Not Just TLS

NPM's proxy host form also exposes access lists and advanced settings that most people skip on install. An access list lets you restrict which source networks may reach a host — a single row that keeps an admin panel private to your home IP range even when it is otherwise public. Adding one is cheap insurance for anything that should not be open to the whole internet. The list is evaluated at NPM before the request is forwarded, so an unauthorized client is cut off before it ever reaches the application behind the proxy.

ini
# Access List: Home and office only
allow 192.168.1.0/24
allow 203.0.113.10
deny all

Pair the access list with the centralized auth pattern from later in this series, and a service like Uptime Kuma or a dashboard gets both a network gate and an identity gate. TLS already happened before either of them, so the request that finally reaches the app is encrypted, authenticated, and from an approved network.

Records You Should Keep

Because everything funnels through one entry point, the reverse proxy is also the natural place to keep a small manifest of what is running where. Even a plain text file or a git-tracked markdown table mapping hostname to container and internal port saves you a lot of rediscovery later. When you add service number twelve, you update the table and the pattern stays boring — which is exactly the point.

Takeaway

A reverse proxy is the layer that makes every other self-hosting pattern — TLS, subdomains, centralized auth, even backups — easier to reason about. Get one in front of your stack before the port chaos starts. On a Netbay Lucknow VPS you can run NPM in Docker in under an hour, and netbayhosts.in gives you a fresh host in under 60 seconds to start the stack.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance