Why Push Notifications Belong on Your Own Server
Most push notification services work fine until they don’t – a rate limit kicks in, a pricing tier changes, or the service quietly deprecates the free plan you built your workflow around. Ntfy sidesteps all of that by giving you a self-hosted server that sends notifications directly to your devices through a simple HTTP request. No API keys to manage, no third-party accounts, no monthly bill. Just a server you control and a URL you can curl from anywhere.
The setup process is unusually straightforward for a self-hosted tool. Ntfy runs as a single binary or a Docker container, accepts plain HTTP POST requests, and delivers notifications to Android, iOS, and desktop clients with no intermediary. Whether you want alerts from a backup script, a cron job, a home automation trigger, or a monitoring tool, ntfy treats them all the same way: send a request to a topic URL, and every subscribed device receives the message within seconds.

Installing Ntfy with Docker
Docker is the fastest path to a working ntfy installation. Pull the official image from binwiederhier/ntfy and write a basic compose file. A minimal docker-compose.yml looks like this: set the image to binwiederhier/ntfy, map port 80 to port 80 inside the container, mount a local directory to /etc/ntfy for config and another to /var/cache/ntfy for message caching, then add command: serve as the container’s default command. Run docker compose up -d and the server is live on your local network immediately.
Before exposing the instance to the internet, add a configuration file at /etc/ntfy/server.yml. At minimum, set base-url to your domain, enable HTTPS either through a reverse proxy like Nginx or Caddy, and configure cache-duration to hold messages for clients that reconnect after going offline. A reasonable cache window is 12 hours. Caddy is the easier choice here because it handles certificate provisioning automatically – point your domain at the server, write a one-block Caddyfile that proxies to the ntfy container on its internal port, and Caddy fetches and renews a Let’s Encrypt certificate without any manual steps.
Access control is off by default, which is fine for a local-only setup but a real problem on a public server. Ntfy supports two auth models: token-based and username/password. Generate a token with ntfy token add or create a user account with ntfy user add username. Set auth-default-access: deny-all in the server config so unauthenticated clients cannot publish or subscribe to any topic. From that point, every publish request needs an Authorization header – either Bearer your-token or Basic auth credentials. Keeping a separate read-only token for mobile clients and a write token for scripts is a clean way to limit blast radius if a credential leaks.

Subscribing on Android and iOS
The Android app is available on Google Play and through F-Droid for users who avoid Google services. After installing, tap the plus icon to add a subscription, enter your server URL and topic name, and authenticate if the server requires it. Notifications arrive as native Android push messages, which means they respect Do Not Disturb rules, support notification channels, and show up in the pull-down shade like any other app alert. The iOS app follows the same flow – add a server, subscribe to topics, and grant notification permissions when prompted.
Topic names are arbitrary strings. There is no registration step, no dashboard to click through – if a client subscribes to https://ntfy.example.com/backup-alerts and a script publishes to that same URL, the client receives the message. That simplicity is also a minor security consideration: anyone who knows your topic name and has credentials can publish to it. Using long, random topic strings – the way you would name a private S3 bucket – adds an extra layer of obscurity on top of auth controls.
Sending Notifications from Scripts and Services
Publishing a notification is a single curl command. The most basic form is curl -d "Backup complete" https://ntfy.example.com/backup-alerts. That sends a plain-text notification with no title, no priority, and default styling. Add headers to enrich the message: -H "Title: Backup Finished" sets a subject line, -H "Priority: high" makes the notification more visible on mobile, and -H "Tags: white_check_mark" adds an emoji icon pulled from the standard emoji shortcode list. Ntfy’s documentation maps shortcodes to emoji characters, so a failed job can send a red circle icon and a success can send a checkmark without any special setup.
Cron jobs benefit from this immediately. A backup script that previously sent no feedback at all can append a one-line curl call at the end – one for success, one for failure in the error trap – and you get a record of every run on your phone without setting up email or a separate logging system. For services like Uptime Kuma, ntfy works as a notification provider out of the box. Add your ntfy server URL and topic in Uptime Kuma’s notification settings, and downtime alerts route directly to your subscribed devices without any relay through a third-party service.
Ntfy also supports actions inside notifications. By passing an Actions header, you can attach buttons that trigger HTTP requests or open URLs when tapped. A deployment notification can include a “View Logs” button that opens a URL directly, or a home automation alert can attach a “Dismiss” button that hits a local API endpoint. These actions are defined inline in the header value, so no server-side configuration is required to use them – just format the header correctly in your publishing script.

Message attachments are supported too. Pass a file with the request and ntfy stores it temporarily on the server, making it available for download from the notification. This matters for monitoring scripts that generate small reports or screenshots – instead of emailing a file or writing to a shared drive, the script can push the file directly into the notification. File size limits and retention duration are both configurable in the server config, so storage usage stays predictable. A setup running on a Raspberry Pi with an attached SSD can handle attachment storage without hitting memory constraints, since ntfy writes attachments to disk rather than holding them in RAM.





