Project

General

Profile

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.*