Project

General

Profile

Actions

NPM » History » Revision 1

Revision 1/3 | Next »
Redmine Admin, 10/25/2026 04:25 PM


Nginx Proxy Manager + Let's Encrypt

Unit: nginx-proxy-manager.container. Published on host 81 → 80, 444 → 443

(rootless can't bind <1024); admin UI on :8181, VPN only. The FortiGate VIP

does the public 443 → 444 translation. No hairpin NAT, so from inside the

public names resolve to the WAN IP and don't work — see Health Check.

NPM must be a member of every site's network to reach site-<name>:80 by

container name. Each new site adds three lines to the unit, above the

# --- next site: … marker comments (add-wordpress-site.sh does this

automatically; for Redmine/Snipe-IT do it by hand):

[Unit]
After=net-<name>-network.service
Requires=net-<name>-network.service
[Container]
Network=net-<name>.network

then cp to ~/.config/containers/systemd/, daemon-reload, restart nginx-proxy-manager.service.

Proxy host (UI or API): Domain <domain> → scheme http, Forward Hostname

site-<name>, Forward Port 80 (Redmine: 3000), Block Common Exploits,

Websockets; SSL tab → Let's Encrypt, Force SSL, HTTP/2.

LE needs DNS A record + FortiGate VIP live first (HTTP-01 challenge comes in

over 80 → 81). The LE contact email is the NPM user account's email, not a

per-cert setting.

API credentials are Podman secrets npm-admin-identity / npm-admin-secret.

Quick API test:

curl -s http://localhost:8181/api/ | head -c 200
podman network inspect net-<name> | jq '.[0].containers | keys'   # must list nginx-proxy-manager

Restrict an internal-only app (Snipe-IT, Redmine admin): NPM Access List

with the VPN/office ranges attached to that proxy host.


Source: dmz-web-podman-cheatsheet.md v1.1.1 in the dmz-web-deploy repo (Releases). Edit the wiki and the repo copy together.

Updated by Redmine Admin 12 days ago · 3 revisions