Simple reverse proxy to expose services with

  • Proxy and stream hosts
  • A beginner-friendly UI
  • Let’s Encrypt certs generation and auto-renewal
  • Access lists
  • UI-toggleable options such as Connection upgrades and Block exploits
  • Access to the underling Nginx configuration and to an API

https://nginxproxymanager.com/

This is the central and unique point through which all services are accessed and guarded by an access list and ssl certificates. Services cannot be accessed directly because they do not expose their own ports. If they use http(s), they’ll be accessible through a proxy host and for other ports, the port should be expose on NPM instead a stream host used.

Setup

Stack config: https://github.com/one137/dockerhost-stacks/blob/main/stacks/80-npm.yml

Default login:

Create SSL Certificates

  • https://dash.cloudflare.com/profile/api-tokens > Create Token
    • one137.dev - Zone:Read, DNS:Edit
  • NPM > SSL certs > Add cert > Let’s encrypt
    • Enter Domain name(s), Email, “Use a DNS Challenge”
    • Enter DNS Provider “Cloudflare” and replace “01234…” with actual token
    • Leave Propagation empty, Agree to TCs, Save

Create Access List

  • Name: LAN + Wireguard
  • Satisfy Any
  • Access:
    • allow 192.168.137.0/24 for LAN, and
    • allow 10.100.0.3/32 for Wireguard
      • If DNSMasq is used alongside Wireguard, allow 10.100.0.3/32, where the static IP is that of wireguard-easy on its own docket network: docker exec ct-wireguard-easy ip a
      • Otherwise, use the entire reserved Docker subnet space, typically 172.16.0.0/12 + 192.168.0.0/16 (see Why)

Create Proxies

Examples (see Homelab Services for full list):

  • pihole1.one137.dev: http://pihole1:80 (pihole1 a local A record)
  • npm.one137.dev: http://ct-npm:81 (ct-npm a container name on docker network)
  • one137.dev: http://STATIC_FILES:1 (see below)

Create Streams

Examples:

  • 27017: ct-mongo:27017 TCP
  • 8025: ct-mailrise:8025 TCP/UDP

Use the API

https://github.com/NginxProxyManager/nginx-proxy-manager/tree/develop/backend/schema/paths/nginx.

Examples:

Get a token:

curl -sX POST -H "Content-Type:application/json" http://localhost:81/api/tokens -d '{"identity":"$NPM_EMAIL", "secret":"$NPM_PASS"}' | jq

Create a new Stream host:

curl -sX POST -H "Authorization: Bearer ${NPM_TOKEN}" -H "Content-Type:application/json" -d '{"incoming_port": 8025, "forwarding_port": 8025, "forwarding_host": "ct-mailrise", "tcp_forwarding": true, "udp_forwarding": false}' http://localhost:81/api/nginx/streams | jq

Try using https://npm.one137.dev/api if port 81 isn’t exposed anymore.

Use NPM as a Web Server

See Public Website and in particular Serve static files through NPM.