Self hosted Mobile Push Notifications using NTFY
I am slowly moving to LineageOS on my personal phone. The most important features I use on that phone are Email, Messaging, Mapping, and Alerts. I have found decent alternatives for Email, Messaging, and Mapping. Alerts or Notifications are something I depend on a lot; currently, they are Google or Apple features. I could settle down for pulls (I get a few alerts by way of RSS feeds), but push would be great. Especially for alerts from my home or servers. Hence was looking for it. NTFY suited my needs from all angles. Therefore I took some time to deploy it.
When I was looking for a solution, five primary factors were
- Based on Open Web Standards
- Free and Open Source Software
- Self hostable
- Auth and RBAC possible
- Android and other clients
ntfy did satisfy all those conditions.
ntfy (pronounce: notify) is a simple HTTP-based pub-sub notification service. It allows you to send notifications to your phone or desktop via scripts from any computer, entirely without signup, cost or setup. It's also open source if you want to run your own.ntfy website
When you are running a service like this on Android, power consumption can become as an issue. But I have been running it for a week now with Instant Delivery (foreground service) switched on. Battery consumption has been negligible. Delivery has been on time and stable.
Currently, I am running a self-hosted version using Docker. I have a few channels subscribed on a browser, a few Android phones, and desktops (CLI). It's been stable and working as expected.
My initial idea was to run the docker instance on cloud run, but billing is complicated for WebSockets on it. The next choice was AWS lightsail or one of my DO machines. But finally, I settled for Fly; it looked effortless and cheap to run such a machine on Fly. And it has been.
Another option was to deploy it on my internal machine. But I didn't want to open a port to it from outside. The only option was to connect to it using a VPN, limiting its usage. It's a duct-tape system connecting many things. So it makes sense to be available on the public internet.
I created a docker file and a new server.yml file for my server configuration. Added paths to my cache and auth SQLite databases. The path /data is mapped to a volume. So data gets saved even if the Docker is restarted.
COPY server.yml /etc/ntfy/server.yml
ENTRYPOINT ["ntfy", "serve"]
server.yml looks like this
Once deployed. I logged into the system, created users, and added access.
ntfy on the top looks like a very simple service. But it's a simple and compelling pub/sub service with an excellent predefined message format and clients. I use their JSON message format with POST and Authorization header. That way, if I want to save a topic in the future, I can directly pipe it to a CouchDB. The message and Android provide a lot of wiring features.
- Supports click action - where you can open the URL by clicking the message. Useful if you are sharing links between machines.
- You can add actions like View a URL or Open an App. These actions are visible as a button that you can click to continue with the action. For example, email client app using mailto:// or open map using geo:// etc.
- You can also tie it to HTTP request to send further requests. Imagine one-time use capability URLs sent as part of message. I generally use HTTP Shortcut App for that and shortcuts:// as a link works.
- You can also broadcast the message so other apps can capture and consume it. Works well with tasker or macrodroid apps. This can be used to automate things.
- Can carry attachments (directly attached or as URL) as part of the message
- It supports UnifiedPush
I have not configured email delivery yet. I am working on that. I will enable it. This way the most important messages from my home can be delivered both on ntfy app and on my regular email client.
Note: There is a hosted service at ntfy.sh, try it first before jumping into self-hosting.