Skip the Cloud, Keep the Alerts
Push notifications have become so entangled with third-party cloud services that most developers and homelab enthusiasts barely question it. You want an alert when your backup job finishes, your server goes offline, or a script throws an error – so you route it through a commercial service, hand over an API key, and hope their free tier never disappears. Gotify offers a different path: a self-hosted notification server you run on your own hardware, with no accounts, no rate limits, and no external dependencies.
Gotify is an open-source project written in Go, which means the binary is small, the memory footprint is minimal, and it runs comfortably on a Raspberry Pi, a VPS with 512MB of RAM, or tucked inside a Docker container alongside your other self-hosted services. The architecture is simple – a server receives messages via a REST API, and connected clients (a web interface or Android app) display them in real time over WebSockets. That simplicity is precisely what makes it worth setting up.

Installing Gotify with Docker
Docker is the fastest way to get Gotify running without touching your host system’s dependencies. Before starting, make sure Docker and Docker Compose are installed on your machine. Create a directory for Gotify’s data – this is where the SQLite database and configuration will live, so choose somewhere with adequate storage and backup access.
Create a docker-compose.yml file in that directory with the following content:
- Image: gotify/server:latest
- Port mapping: 8080:80 (or whichever host port you prefer)
- Volume: map your local data directory to /app/data inside the container
- Environment variable: GOTIFY_DEFAULTUSER_PASS set to a strong password
- Restart policy: unless-stopped
Once the file is saved, run docker compose up -d from that directory. Docker will pull the image and start the container. Within a few seconds, Gotify’s web interface should be accessible at your server’s IP address on port 8080. The default admin username is admin and the password is whatever you set in the environment variable. If you skipped that variable, it defaults to admin – change it immediately after first login.
For those who prefer running Gotify directly on the host without Docker, precompiled binaries for Linux (amd64, arm, arm64) are available on the project’s GitHub releases page. Download the appropriate archive, extract it, make the binary executable, and run it. Gotify will generate a default config.yml on first launch that covers database path, server port, and default credentials. This bare-metal approach suits users who want fewer moving parts or who are already cautious about Docker’s networking overhead on low-memory devices.
Creating Applications and Sending Your First Message
Once you are logged in, every notification source in Gotify is represented as an “application.” An application is essentially a named channel with its own API token. You might create one application called “Backups,” another called “Home Assistant,” and another called “Uptime Monitor.” This separation keeps notifications organized and lets you revoke access for one source without affecting the others.
To create an application, navigate to the Apps section in the web interface and click Create Application. Give it a name and an optional description, then save it. Gotify will generate a token string – copy this immediately, because it is the only credential needed to send messages to that application. Store it somewhere safe, like a password manager or an environment variable in the script that will use it.

Sending a message is a single HTTP POST request. Using curl, the command looks like this: curl -X POST “http://your-server:8080/message?token=YOUR_APP_TOKEN” -F “title=Test Alert” -F “message=Hello from Gotify” -F “priority=5”. The priority field accepts integers from 1 to 10, where higher numbers can trigger more prominent alerts on the Android client. That one command is enough to verify your setup is working end to end before wiring it into anything more complex.
Most automation tools have native HTTP request support, which makes Gotify easy to integrate without installing any special libraries. Bash scripts can use curl directly. Python scripts can use the built-in requests library. Home Assistant has a Gotify integration in HACS, and n8n supports it through a generic HTTP node. Any system that can fire a POST request can send a Gotify notification, which covers nearly every homelab scenario worth automating.
Setting Up the Android Client
The Gotify Android app is available on F-Droid and GitHub, though notably absent from the Google Play Store. Install it from either source, then open the app and enter your server URL and admin credentials. After logging in, you will see all your registered applications and can browse notification history. The real value is persistent background connectivity – the app maintains a WebSocket connection to your server and delivers push alerts with no polling delay and no cloud relay in the middle.
Battery usage is worth monitoring on older devices, since a persistent WebSocket connection does consume some background resources. In practice, the drain is low compared to commercial push notification clients, but if you are running the app on a dedicated low-power device or an old phone acting as a dashboard, it is worth checking your Android battery optimization settings to ensure the Gotify app is excluded from aggressive background killing. Whitelisting it keeps the connection stable and prevents missed notifications.
Putting Gotify Behind a Reverse Proxy
Running Gotify on a raw port over HTTP is fine for a local network, but if you want to reach your notifications from outside your home or office, you need HTTPS. A reverse proxy like Nginx or Caddy handles SSL termination and lets you serve Gotify under a subdomain such as notify.yourdomain.com. Caddy is the easier choice here because it handles certificate provisioning automatically through Let’s Encrypt with minimal configuration.
The one non-obvious requirement for Gotify behind a reverse proxy is WebSocket support. Because the Android client and web interface both rely on WebSocket connections for real-time delivery, your reverse proxy configuration must explicitly pass WebSocket upgrade headers. In Nginx, this means including proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection “upgrade”; in your location block. Skipping this step produces a setup that appears to work – messages send correctly via the REST API – but the live notification stream silently fails, and you will only see messages after a page refresh.
Gotify also supports client management directly from the web interface, where you can see every connected device, revoke tokens, and delete old applications. If you are running multiple services on the same server and want visibility into what is happening across all of them at a system level, pairing Gotify with a monitoring tool like Glances for real-time system monitoring gives you both the alert layer and the diagnostic layer without leaving your own infrastructure. The notification token system means you can hand a token to a script on a remote machine and that machine can send you alerts without ever having login credentials to your Gotify instance.

One thing to plan for before going all-in: Gotify uses SQLite by default, and the database grows as message history accumulates. There is a configurable message retention limit under Settings in the web interface, and setting a reasonable cap – somewhere in the range of a few hundred messages per application – prevents the database from expanding unchecked on a system with limited storage. On a Raspberry Pi with a microSD card, that is not a theoretical concern.





