Deployment guide

Self-host ntfy on a VPS: push notifications for scripts and CI/CD

Deploy on a VPS Cloud →

Security & Monitoring4 min read

Self-host ntfy on a VPS: push notifications for scripts and CI/CD

Slack charges per seat. Emails get lost in noise. ntfy (Apache 2.0, ~32k ⭐, v2.26.3) takes a different approach: an HTTP pub/sub server you self-host on your VPS, where any script sends an alert with `curl -d`. The mobile app receives the push notification in real time. Single Docker container, < 30 MB RAM, no account required.

The problem: too many monitoring tools, too many notification channels

Uptime Kuma monitors your services, Beszel monitors your VPS metrics, Changedetection.io monitors your web pages, and your cron jobs go silent at night — except when they fail. Each has its own notification channel: Slack, email, webhook, Telegram. The result: five different integrations to maintain and no unified view when something breaks at 3 AM. ntfy solves this from the other direction: you host the notification hub, and every tool or script sends alerts to it over plain HTTP.

What ntfy gives you out of the box

  • Send a notification with a plain curl — curl -d "Build failed" http://your-vps/ci-alerts — zero SDK, zero library.
  • Receive notifications on Android (F-Droid / Play Store), iOS (App Store), desktop browser and the ntfy web UI — all subscribe to the same topic via WebSocket or SSE.
  • Notification actions — buttons in the push notification that trigger HTTP callbacks, open URLs or run commands on the subscriber device.
  • Scheduled notifications — delayed delivery (X-Delay: 30min) to schedule reminders from scripts.
  • Priority levels (min / low / default / high / urgent) with DND bypass on mobile for urgent alerts.
  • Attachments — images or files up to 15 MB via the X-Attach header or multipart upload.
  • Access control — add users, passwords and per-topic ACLs via ntfy user and ntfy access CLI.
  • < 30 MB RAM, SQLite, single container — the lightest self-hosted push notification server in its class.

Architecture: single-container HTTP pub/sub

ntfy is a Go binary that runs in a single Docker container. It exposes a simple HTTP interface: PUT or POST to /your-topic publishes a message; any client listening to that topic (via WebSocket, SSE or the mobile app) receives it instantly. Messages are cached in SQLite (/var/lib/ntfy/cache.db) with configurable retention (12 hours by default). NTFY_BEHIND_PROXY=true tells ntfy it is behind a reverse proxy (nginx) and should read the real client IP from X-Forwarded-For.

Deploy and use ntfy in 5 steps

01

Logging in for the first time

ntfy starts WITHOUT any account or password: the URL opens straight onto the interface, and anyone who knows the address can read AND publish on any topic. If your server is reachable from the internet, enable authentication before using it in earnest.

Tip: use topic names as namespaces

Organise your alerts by source: ci-builds for GitHub Actions/GitLab CI, server-alerts for Uptime Kuma/Beszel, cron-jobs for batch scripts. The ntfy app lets you mute specific topics at night (e.g., cron-jobs) while keeping server-alerts at maximum priority. No server-side configuration — just the topic name in the curl command.

Your notification hub under your control

Deploy ntfy on a ServOrbit VPS and centralise all your monitoring, CI/CD and cron alerts in one self-hosted notification hub — no SaaS, no subscription.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.