Your homelab runs monitoring checks, backups, health probes, and automation workflows — each one generating output that you need to see. The typical approach is checking dashboards, tailing logs, or waiting for an email that might land in spam. In 2026, with homelabs running dozens of services, reactive monitoring is dead. You need push notifications that reach your pocket instantly.
ntfy.sh is the simplest self-hosted push notification server you can run. A single HTTP POST sends a notification to your phone. No SDKs, no SDK registration, no per-app tokens. One curl command and you’re done.
This guide covers deploying ntfy on Docker Compose, setting up authentication, and wiring it into your monitoring stack — Uptime Kuma, Prometheus Alertmanager, Grafana, cron jobs, and every script you’ve ever written.
Why ntfy Instead of Gotify, Apprise, or Pushover
There are several options for self-hosted notifications. Here’s how they compare:
- ntfy.sh — Single-binary server with a dead-simple HTTP API. Push via
curl -d "message" ntfy.sh/topic. No client library needed. Native Android and iOS apps with persistent connections. Open source (Apache 2.0), ~10MB binary. - Gotify — Mature, websocket-based. Requires a client app on the phone. Docker container ~15MB. Excellent, but the push mechanism is slightly more involved (requires the Gotify client to maintain a websocket).
- Apprise — A notification library, not a server. Wraps dozens of providers (Slack, Telegram, email). Great as a relay, but you still need something to trigger it.
- Pushover — Hosted service, $5/mo. Works great but locks you into a third party.
ntfy wins for sheer simplicity. The entire API is POST /{topic} with the message body. It supports priorities, tags, markdown, click actions, and attachments — all via HTTP headers. For a homelab where you want notifications from bash scripts without installing anything, ntfy is the clear choice.
Deploying ntfy on Docker Compose
Here is the complete docker-compose.yml for a production-ready ntfy deployment behind Traefik:
|
|
Nginx Proxy or Traefik Configuration
If you use Traefik, add these labels:
|
|
For Caddy, a minimal Caddyfile:
ntfy.gntech.me {
reverse_proxy ntfy:80
}
Authentication Setup
Deploy first with NTFY_AUTH_DEFAULT_ACCESS=deny-all (as shown above), then create users and tokens:
|
|
Store the tokens securely. Each token grants access to specific topics. The format is: tk_xxxxxxxxxxxxx.
Without auth enabled, anyone who can reach your ntfy instance can publish. With deny-all as default, you control exactly which services can push and which topics they can access.
Publishing Notifications — The API
ntfy’s API is refreshingly simple. No JSON body required unless you need structured content:
|
|
Priority levels available: urgent, high, default, low, min. Each maps to how aggressively your phone notifies you — urgent bypasses Do Not Disturb on Android.
Integrating with Your Monitoring Stack
Uptime Kuma
Uptime Kuma natively supports ntfy as a notification provider:
- Go to Settings > Notifications
- Click Add Notification
- Select ntfy from the provider list
- Set URL to your ntfy instance:
https://ntfy.gntech.me - Set Topic to
alerts - Set Token if authentication is enabled
- Select priority (default: high)
- Click Test — you should receive a test notification
Kuma sends status changes (down → up, up → down) directly to your phone with the service name and current status.
Prometheus Alertmanager
Alertmanager supports generic webhook receivers, which work perfectly with ntfy. Add this to alertmanager.yml:
|
|
Alertmanager will POST each alert group as JSON. ntfy will render the JSON body, which is readable enough. For cleaner messages, use Alertmanager’s text template field or pipe through a small middleware.
Grafana Contact Points
Grafana supports webhook contact points:
- Alerting > Contact points → Add contact point
- Name:
ntfy - Integration: Webhook
- URL:
https://ntfy.gntech.me/alerts - HTTP method:
POST - Add custom header:
Authorization: Bearer tk_xxxxxxxxxxxxx - Optional message template — Grafana’s templating lets you build cleaner notifications:
{{ define "ntfy/message" }}
{{ range .Alerts }}
**{{ .Labels.alertname }}**
Severity: {{ .Labels.severity }}
Instance: {{ .Labels.instance }}
{{ .Annotations.summary }}
{{ end }}
{{ end }}
Docker Container Healthchecks
Docker healthchecks can push to ntfy on failure. Add this to any compose service:
|
|
Then a separate cron or watchdog checks health status and alerts:
|
|
Run it every 5 minutes via a systemd timer or crontab:
|
|
Shell Script Notification Function
Add this to your .bashrc or common library:
|
|
One function, zero dependencies, works from any shell script.
Advanced Configuration
Topic-Based Access Control
Fine-tune who can publish and subscribe to each topic:
|
|
Topic reservations ensure only authorized tokens can use specific topic names:
|
|
Rate Limiting and Caching
ntfy caches messages by default so new subscribers see recent notifications. Control cache size in server.yml:
|
|
Behind Traefik with Rate Limiting
Add a middleware to protect ntfy from abuse:
|
|
Mobile Setup — Push Where It Matters
- Install ntfy from F-Droid, Google Play, or Apple App Store
- Tap Add topic
- Enter your server URL:
https://ntfy.gntech.me - Topic:
alerts - If auth is enabled, add your read token
- Configure per-topic settings:
- alerts: priority threshold “high” (only wake me for real problems)
- backup-notify: priority threshold “default” (backup completion, not urgent)
- server-status: mute during night (silent maintenance messages)
Security Hardening
Secure your ntfy instance against unwanted access:
|
|
If you don’t want authentication, restrict by network instead:
|
|
For the reverse proxy, add IP allowlists:
# Caddy
ntfy.gntech.me {
@internal remote_ip 10.0.0.0/8 192.168.0.0/16 172.16.0.0/12
handle @internal {
reverse_proxy ntfy:80
}
respond 403
}
Monitoring ntfy Itself
ntfy exposes a health endpoint at /v1/health:
|
|
Add this to your Uptime Kuma monitor or Prometheus blackbox target:
|
|
Conclusion
Self-hosted push notifications with ntfy transform how you interact with your homelab. Instead of checking dashboards, notifications come to you. Instead of email gateways that silently fail, a single curl command reaches your phone with priority, tags, and actionable links.
The setup is minimal — one Docker Compose file, one docker compose up -d, and a few tokens. The integrations cover Uptime Kuma, Prometheus Alertmanager, Grafana, and every cron job or script you write. For a service that costs nothing to run, ntfy pays for itself the first time it alerts you to a failed backup before your data is gone.
Start with a simple deployment, add authentication, then wire in your monitoring tools one by one. Your homelab will thank you — and so will your sleep when only the urgent alerts wake you up.