Deploy Gotify
Gotify push notification server on Railway, REST API plus WebSocket stream
Just deployed
/var/lib/postgresql/data
gotify
Just deployed
/data
Deploy and Host Gotify on Railway
Gotify is a small, self-hosted push notification server: your scripts and monitoring tools POST a JSON message to a REST endpoint, and every connected browser tab and Android phone receives it within milliseconds over a WebSocket. It is for people who want alerts on their phone without routing them through Pushover, Pushbullet or Firebase — homelab owners, sysadmins, and teams whose backup jobs and CI runs need somewhere to shout. MIT-licensed, written in Go, one binary with a web UI built in.
This template deploys Gotify with the durable setup its documentation recommends rather than the default single-file database. Two services come up: gotify, the server itself, which takes the public HTTPS URL, and Postgres, Railway's managed database, holding users, applications, client tokens and message history on the private network. A volume at /data keeps the application icons you upload. To self-host Gotify on Railway with real persistence, this is the whole setup.

Getting Started with Gotify on Railway
Deploy the template and open the generated URL on the gotify service. You land on a login screen. The first administrator is created when the database is initialised, from GOTIFY_DEFAULTUSER_NAME (admin) and GOTIFY_DEFAULTUSER_PASS, which the template generates — read it in the gotify service's Variables tab, then change it under ADMIN → Change Password. Public registration is off, so nobody else can sign up.
Next create an application: APPS → CREATE APPLICATION, name it something like "Server Monitoring", and copy the token it shows. That token is the credential your scripts use, and it is only displayed at creation time. Send yourself a message from a terminal to confirm the deployment works end to end:
curl -X POST "https://your-app.up.railway.app/message?token=YOUR_APP_TOKEN" \
-F "title=Backup completed" -F "message=pg_dump finished in 3m12s" -F "priority=5"
It should appear in the browser tab immediately, with no refresh — that is the WebSocket stream working through Railway's edge. Install the Gotify Android app from Google Play or F-Droid, point it at the same URL and log in, and those messages arrive as notifications.

About Hosting Gotify
Gotify separates senders from receivers. An application is a sender: it owns a token, can only POST messages, and appears in the sidebar with its own icon, so you can see at a glance whether an alert came from your backup job or your uptime checker. A client is a receiver — a browser session or a phone — holding a token that reads the stream. Deleting a leaked application token revokes that one sender.
- REST API for sending, WebSocket stream for receiving, both documented with OpenAPI
- Priority levels that map to Android notification importance
- Markdown message bodies and click-through URLs via message
extras - Per-application icons, sort order and default priority
- Optional OIDC sign-on against Keycloak, Authelia, Dex and similar
- Multi-user, with admin and ordinary roles, and session elevation before token-revealing actions
Why Deploy Gotify on Railway
Railway removes the parts of running a push server that are not about notifications:
- HTTPS and a public domain issued automatically, which the Android app requires
- Managed Postgres with backups, instead of a SQLite file you look after yourself
- A persistent volume keeps uploaded application icons across deploys
- The health check watches the database connection, not just the process
Common Use Cases
- Homelab and server alerts — disk thresholds, failed systemd units and certificate expiry, pushed to your phone
- Backup and cron reporting — a one-line
curlat the end of each job, so silence means something broke - CI/CD notices — a build posting to a "Deploys" application with the version and duration
- Monitoring fan-out — Grafana, Uptime Kuma and Alertmanager reach Gotify through a plain webhook
Dependencies for Gotify
- gotify — the
gotify/server:latestimage from Docker Hub. Serves the web UI, REST API and WebSocket stream on one port. - Postgres — Railway's managed PostgreSQL. Gotify creates and migrates its own schema on first boot; nothing to import.
- Volume — mounted at
/datafor uploaded application images and any plugins.
Environment Variables Reference
| Variable | Purpose |
|---|---|
GOTIFY_SERVER_PORT | Port Gotify binds; must match Railway's PORT |
GOTIFY_DATABASE_DIALECT | postgres; the alternative is sqlite3 |
GOTIFY_DATABASE_CONNECTION | Connection string, wired to the Postgres service |
GOTIFY_DEFAULTUSER_NAME | First admin username, applied to an empty database |
GOTIFY_DEFAULTUSER_PASS | First admin password, applied to an empty database |
GOTIFY_REGISTRATION | false keeps public sign-up closed |
GOTIFY_UPLOADEDIMAGESDIR | Where application icons are stored, on the volume |
GOTIFY_OIDC_* | Optional single sign-on settings, blank by default |
Deployment Dependencies
- Image: hub.docker.com/r/gotify/server — source github.com/gotify/server
- Docs: gotify.net/docs, REST reference gotify.net/api-docs
- Clients: gotify/android, gotify/cli
Hardware Requirements for Self-Hosting Gotify
Gotify is one static Go binary and runs comfortably on the smallest instance you can buy.
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 0.1 vCPU | 0.5 vCPU |
| RAM | 64 MB | 256 MB |
| Storage | 1 GB volume | 5 GB volume |
| Database | SQLite file | PostgreSQL 13+ |
| Runtime | Go (bundled in the image) | — |
Memory scales with open WebSocket connections, not message volume; history lives in Postgres.
Self-Hosting Gotify with Docker
Outside Railway, the smallest working deployment is one container with a volume, on the same image this template uses:
docker run -d --name gotify -p 8080:80 \
-v gotify_data:/app/data \
-e GOTIFY_DEFAULTUSER_PASS=change-me \
gotify/server:latest
For the Postgres-backed setup, point the two database variables at your server. Gotify 3.x is configured by environment variables (or a gotify-server.env file), and process variables always win:
docker run -d --name gotify -p 8080:80 -v gotify_data:/app/data \
-e GOTIFY_DATABASE_DIALECT=postgres \
-e "GOTIFY_DATABASE_CONNECTION=host=db port=5432 user=gotify dbname=gotify password=secret sslmode=disable" \
gotify/server:latest
You then need TLS in front of it, a public DNS record so the Android app can reach it, and a database backup plan — the three things this template already handles.
How Much Does Gotify Cost to Self-Host?
Gotify is free and open source under the MIT licence. There is no paid tier, message quota, per-device charge or vendor account: every feature is in the image you deploy, and the Android app is free on Google Play and F-Droid. On Railway you pay only for compute, the managed Postgres instance and the volume — a small footprint for a personal or small-team notification server.
FAQ
What is Gotify? An open-source, self-hosted push notification server. Applications send it messages over a REST API, and connected web and Android clients receive them in real time over a WebSocket.
What does this Railway template deploy?
Two services: the Gotify server, with a public HTTPS URL and a /data volume, and a managed PostgreSQL database on the private network holding users, applications and messages.
Why does the template include Postgres instead of using SQLite? SQLite is Gotify's default and keeps everything in one file on disk. Postgres is the database its documentation lists for production use, and on Railway it brings managed backups and message history independent of the app container.
How do I send a notification to self-hosted Gotify from a script?
Create an application in the web UI, copy its token, then POST to /message?token=YOUR_TOKEN with title, message and priority fields. Any HTTP client works: curl, Python requests, a Grafana webhook or the gotify CLI.
Can I use the Gotify Android app with this deployment? Yes. Install it from Google Play or F-Droid, enter the public URL, and log in with your Gotify username and password. It registers itself as a client and holds a background connection open for delivery.
How do I add more users, and can people register themselves?
Public registration is disabled by default. An administrator adds accounts under USERS → CREATE USER, choosing whether each is an admin. To use an identity provider instead, the GOTIFY_OIDC_* variables enable single sign-on against any PKCE-capable issuer.
Where did my uploaded application icon go after a redeploy?
It is kept on the volume at /data, so it survives redeploys. If you point GOTIFY_UPLOADEDIMAGESDIR outside that mount, images land on the container filesystem and are lost on the next deploy.
Template Content
