Merge pull request 'fix(ntfy): publish ntfy host port so the external reverse proxy can reach it' (#95) from fix/ntfy-published-port into main
All checks were successful
Build container images / build (push) Successful in 57s
Build container images / deploy (push) Successful in 34s
SonarQube / analysis (push) Successful in 2m31s

Reviewed-on: #95
Reviewed-by: Colby Whitlock <whitlocktech@gmail.com>
This commit is contained in:
2026-07-22 09:08:13 +00:00
3 changed files with 26 additions and 5 deletions

View File

@@ -131,6 +131,12 @@ UOLINK_PROTOCOL=1
# register endpoints on a different host than NTFY_BASE_URL. # register endpoints on a different host than NTFY_BASE_URL.
# NTFY_PUBLISH_TOKEN Optional. The content-free-tickle design needs NO token; # NTFY_PUBLISH_TOKEN Optional. The content-free-tickle design needs NO token;
# set one only to require auth on backend→ntfy publishes. # set one only to require auth on backend→ntfy publishes.
# NTFY_HOST_PORT Host port the ntfy container publishes :80 on (default
# 2586). The public reverse proxy forwards the notification
# subdomain to host:NTFY_HOST_PORT — required because the
# proxy lives outside the compose network and cannot reach
# ntfy any other way. Change only on a host-port conflict.
NTFY_BASE_URL=https://ntfy.example.com NTFY_BASE_URL=https://ntfy.example.com
# NTFY_ALLOWED_ORIGINS=https://ntfy.example.com # NTFY_ALLOWED_ORIGINS=https://ntfy.example.com
# NTFY_PUBLISH_TOKEN= # NTFY_PUBLISH_TOKEN=
# NTFY_HOST_PORT=2586

View File

@@ -74,9 +74,20 @@ services:
volumes: volumes:
- ntfydata:/var/lib/ntfy - ntfydata:/var/lib/ntfy
- ./ntfy/server.yml:/etc/ntfy/server.yml:ro - ./ntfy/server.yml:/etc/ntfy/server.yml:ro
# No published host port — devices reach ntfy through the public reverse proxy # Published so the PUBLIC reverse proxy (Pangolin) can forward the
# on its own hostname; the backend publisher reaches it over the private # notification subdomain here. Pangolin lives OUTSIDE the compose network and
# compose network. Never publish this directly. # reaches every service through a published host port — never by joining the
# internal network — exactly like `app` above (3000). So ntfy must publish a
# port too: the reverse proxy maps notify.<host> -> host:NTFY_HOST_PORT ->
# ntfy:80. Unlike INTERNAL_PORT / the bot, ntfy is DEVICE-facing, so it is
# SUPPOSED to be reachable through the proxy. Binds 0.0.0.0 (no 127.0.0.1
# prefix) so Pangolin can reach the container. Both the app (SSE subscribe) and
# the backend (POSTing content-free tickles to each device's registered
# endpoint) reach ntfy on this same public origin — NTFY_ALLOWED_ORIGINS pins
# it — so all ntfy traffic flows through the proxy; there is no separate
# internal publish port.
ports:
- "${NTFY_HOST_PORT:-2586}:80"
bot: bot:
# Same as app: prebuilt bot image, pulled in production. Build locally via # Same as app: prebuilt bot image, pulled in production. Build locally via

View File

@@ -13,8 +13,12 @@
# a placeholder for a bare `ntfy serve`. # a placeholder for a bare `ntfy serve`.
base-url: "https://ntfy.localhost" base-url: "https://ntfy.localhost"
# Served on the private compose network; the public reverse proxy terminates TLS # ntfy listens on :80 inside the container. docker-compose.yml publishes this on
# and forwards to this port. docker-compose.yml publishes NO host port for ntfy. # a host port (NTFY_HOST_PORT, default 2586) so the public reverse proxy — which
# lives OUTSIDE the compose network — can terminate TLS and forward the
# notification subdomain to it. Both the app (SSE subscribe) and the backend
# (POSTing content-free tickles to registered device endpoints) reach ntfy on
# that public origin, so all traffic flows through the proxy.
listen-http: ":80" listen-http: ":80"
behind-proxy: true behind-proxy: true