NPM » History » Version 1
Redmine Admin, 10/25/2026 04:25 PM
| 1 | 1 | Redmine Admin | # Nginx Proxy Manager + Let's Encrypt |
|---|---|---|---|
| 2 | |||
| 3 | Unit: `nginx-proxy-manager.container`. Published on **host 81 → 80, 444 → 443** |
||
| 4 | |||
| 5 | (rootless can't bind <1024); admin UI on **:8181, VPN only**. The FortiGate VIP |
||
| 6 | |||
| 7 | does the public **443 → 444** translation. No hairpin NAT, so from inside the |
||
| 8 | |||
| 9 | public names resolve to the WAN IP and don't work — see [Health Check](#). |
||
| 10 | |||
| 11 | NPM must be a member of every site's network to reach `site-<name>:80` by |
||
| 12 | |||
| 13 | container name. Each new site adds three lines to the unit, above the |
||
| 14 | |||
| 15 | `# --- next site: …` marker comments (`add-wordpress-site.sh` does this |
||
| 16 | |||
| 17 | automatically; for Redmine/Snipe-IT do it by hand): |
||
| 18 | |||
| 19 | ``` |
||
| 20 | [Unit] |
||
| 21 | After=net-<name>-network.service |
||
| 22 | Requires=net-<name>-network.service |
||
| 23 | [Container] |
||
| 24 | Network=net-<name>.network |
||
| 25 | ``` |
||
| 26 | |||
| 27 | then `cp` to `~/.config/containers/systemd/`, `daemon-reload`, `restart nginx-proxy-manager.service`. |
||
| 28 | |||
| 29 | Proxy host (UI or API): Domain `<domain>` → scheme http, Forward Hostname |
||
| 30 | |||
| 31 | `site-<name>`, Forward Port 80 (Redmine: 3000), Block Common Exploits, |
||
| 32 | |||
| 33 | Websockets; SSL tab → Let's Encrypt, Force SSL, HTTP/2. |
||
| 34 | |||
| 35 | LE needs DNS A record + FortiGate VIP live first (HTTP-01 challenge comes in |
||
| 36 | |||
| 37 | over 80 → 81). The LE contact email is the NPM *user account's* email, not a |
||
| 38 | |||
| 39 | per-cert setting. |
||
| 40 | |||
| 41 | API credentials are Podman secrets `npm-admin-identity` / `npm-admin-secret`. |
||
| 42 | |||
| 43 | Quick API test: |
||
| 44 | |||
| 45 | ``` |
||
| 46 | curl -s http://localhost:8181/api/ | head -c 200 |
||
| 47 | podman network inspect net-<name> | jq '.[0].containers | keys' # must list nginx-proxy-manager |
||
| 48 | ``` |
||
| 49 | |||
| 50 | Restrict an internal-only app (Snipe-IT, Redmine admin): NPM **Access List** |
||
| 51 | |||
| 52 | with the VPN/office ranges attached to that proxy host. |
||
| 53 | |||
| 54 | --- |
||
| 55 | |||
| 56 | *Source: `dmz-web-podman-cheatsheet.md` v1.1.1 in the `dmz-web-deploy` repo ([Releases](#)). Edit the wiki and the repo copy together.* |