Skip to main content

NTFY

Simple HTTP-based pub-sub notification service. Send notifications to your phone or desktop via scripts.

Getting Started​

  1. Enable it in .env.shared:
    EXIST_IS_SERVICES_NTFY=true
  2. Render and start, from the repo root:
    ./existential.sh && docker compose up -d

That is the whole setup. ntfy's server.yml denies every publish by default, so a fresh install would otherwise accept nothing until someone ran a manual command — which is exactly the sort of step that gets missed and then looks like a broken notification path. Its entrypoint.sh creates two users on first boot: your admin login, from NTFY_ADMIN_USER / NTFY_ADMIN_PASSWORD in services/ntfy/.env, and the publishing bot, from EXIST_NTFY_USER / EXIST_NTFY_PASSWORD in .env.shared — granted read-write on every topic. It waits for ntfy to create its auth database first, since ntfy user add cannot run before that exists, and it is a no-op on every later start.

Decree publishes as that user, so automations report in with no further configuration, and a run that fails or waits for you says so on the decree topic (Decree).

Subscribe​

Install the ntfy app (or open ntfy in a browser: https://<machine>.<tailnet>.ts.net:8443 in Core), sign in with the admin login above, and subscribe to the decree topic, where routines report by default (a routine can name its own with ntfy_topic:). Check it with ./existential.sh test ntfy.

Customization​

Ntfy emojis: https://docs.ntfy.sh/emojis/

API Usage​

Simple Notification​

curl -d "Backup completed successfully" \
-H "Authorization: Bearer tk_REPLACE_BOT_TOKEN" \
https://<machine>.<tailnet>.ts.net:8443/exist/backup

Services​

In Core, ntfy is on the host's tailnet name, port 8443: ./existential.sh runs tailscale serve for it, and the container publishes on loopback only. With the Caddy add-on and no tailnet name, it is https://ntfy.<domain>. entrypoint.sh sets ntfy's base URL, the address the phone app and ntfy's own links use, to whichever applies; NTFY_BASE_URL in services/ntfy/.env overrides it.

EndpointCore (Tailscale)Caddy add-on
Web Interfacehttps://<machine>.<tailnet>.ts.net:8443https://ntfy.<domain>
APIhttps://<machine>.<tailnet>.ts.net:8443/{topic}https://ntfy.<domain>/{topic}
Health Checkhttps://<machine>.<tailnet>.ts.net:8443/v1/healthhttps://ntfy.<domain>/v1/health

Debugging​

# List users
docker exec -it ntfy ntfy user list