Self-Hosting Gotify: Simple Push Notifications for Your Server
Your server sent a backup failure alert at 3 AM. Where did it go? A log file nobody reads? An email buried in spam? You need push notifications — real ones, on your phone, immediately.
Gotify is a self-hosted push notification server. It sends messages to your phone or desktop via a simple REST API. No third-party services, no accounts to create, no rate limits. Send a curl request, get a notification.
Gotify vs. ntfy
These are the two main self-hosted notification servers, and they take different approaches:
| Feature | Gotify | ntfy |
|---|---|---|
| Protocol | WebSocket | HTTP (Server-Sent Events) |
| Android app | Yes (Google Play + F-Droid) | Yes (Google Play + F-Droid) |
| iOS app | No | Yes |
| UnifiedPush | Yes (via plugin) | Yes (built-in) |
| Web interface | Yes (with history) | Yes |
| Authentication | Required (token-based) | Optional (open by default) |
| Message priority | Yes (1-10) | Yes (1-5) |
| File attachments | No | Yes |
| Click actions | No | Yes |
| Markdown support | Yes (with plugin) | Yes |
| Self-hosted | Yes | Yes (or use ntfy.sh) |
| Written in | Go | Go |
| Resource usage | Very low | Very low |
Which one should you choose?
Choose Gotify if you:
- Only need Android/desktop notifications
- Want a simpler, more focused tool
- Prefer mandatory authentication (security-first approach)
- Like the message history web interface
Choose ntfy if you:
- Need iOS support
- Want file attachments in notifications
- Prefer the option to use a hosted service (ntfy.sh) as fallback
- Want click actions (tap notification to open a URL)
This guide covers Gotify. For ntfy, see our ntfy guide.
Self-Hosting Gotify: Setup
Server requirements
Gotify is tiny:
- Minimum: 64 MB RAM, any CPU
- Recommended: 128 MB RAM, 1 CPU core
- Storage: < 100 MB for the application; database grows with message history
Docker Compose setup
version: "3.8"
services:
gotify:
container_name: gotify
image: gotify/server:latest
ports:
- "8080:80"
volumes:
- gotify-data:/app/data
environment:
GOTIFY_DEFAULTUSER_NAME: admin
GOTIFY_DEFAULTUSER_PASS: your-secure-password-here
restart: always
volumes:
gotify-data:
Starting Gotify
docker compose up -d
Access the web interface at http://your-server:8080. Log in with the default credentials you set.
First-time setup
Create an application: Go to Apps → Create Application. Each application represents a notification source (e.g., "Backup System", "Uptime Monitor", "Server Alerts"). You'll get a unique token for each.
Install the Android app: Download from Google Play or F-Droid. Enter your server URL and login credentials.
Send a test notification:
curl -X POST "http://your-server:8080/message?token=YOUR_APP_TOKEN" \
-F "title=Test" \
-F "message=Hello from Gotify!" \
-F "priority=5"
Your phone should buzz within seconds.
Sending Notifications
Basic API usage
Every notification is a simple HTTP POST:
# Simple message
curl -X POST "http://your-server:8080/message?token=APP_TOKEN" \
-F "title=Alert" \
-F "message=Disk space low on server1"
# With priority (1-10, higher = more urgent)
curl -X POST "http://your-server:8080/message?token=APP_TOKEN" \
-F "title=Critical" \
-F "message=Database connection lost" \
-F "priority=8"
# With Markdown (if plugin installed)
curl -X POST "http://your-server:8080/message?token=APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Deploy Complete",
"message": "**v2.1.0** deployed to production\n- 3 new features\n- 2 bug fixes",
"priority": 5,
"extras": {
"client::display": {
"contentType": "text/markdown"
}
}
}'
Priority levels
| Priority | Meaning | Android behavior |
|---|---|---|
| 0 | Minimum | Silent, no notification |
| 1-3 | Low | Normal notification, no sound |
| 4-7 | Normal | Sound + vibration |
| 8-10 | High | Sound + vibration + wakes screen |
Integration Examples
Cron job monitoring
Wrap any cron job to get notified on failure:
#!/bin/bash
GOTIFY_URL="http://your-server:8080"
GOTIFY_TOKEN="YOUR_APP_TOKEN"
# Run the backup
if ! /usr/local/bin/backup.sh 2>&1; then
curl -s -X POST "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" \
-F "title=Backup Failed" \
-F "message=Daily backup failed at $(date)" \
-F "priority=8"
fi
Disk space monitoring
#!/bin/bash
THRESHOLD=90
GOTIFY_URL="http://your-server:8080"
GOTIFY_TOKEN="YOUR_APP_TOKEN"
USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
if [ "$USAGE" -gt "$THRESHOLD" ]; then
curl -s -X POST "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" \
-F "title=Disk Space Warning" \
-F "message=Root partition at ${USAGE}% usage" \
-F "priority=7"
fi
SSH login alerts
Get notified when someone logs into your server. Add to /etc/pam.d/sshd:
session optional pam_exec.so /usr/local/bin/gotify-ssh-alert.sh
Create /usr/local/bin/gotify-ssh-alert.sh:
#!/bin/bash
if [ "$PAM_TYPE" = "open_session" ]; then
curl -s -X POST "http://your-server:8080/message?token=APP_TOKEN" \
-F "title=SSH Login" \
-F "message=User $PAM_USER logged in from $PAM_RHOST" \
-F "priority=5"
fi
Docker container monitoring
#!/bin/bash
GOTIFY_URL="http://your-server:8080"
GOTIFY_TOKEN="YOUR_APP_TOKEN"
# Check if critical containers are running
for container in postgres redis nginx; do
if ! docker ps --format '{{.Names}}' | grep -q "^${container}$"; then
curl -s -X POST "$GOTIFY_URL/message?token=$GOTIFY_TOKEN" \
-F "title=Container Down" \
-F "message=$container is not running" \
-F "priority=9"
fi
done
Integration with monitoring tools
Prometheus Alertmanager:
Use the Alertmanager webhook receiver:
# alertmanager.yml
receivers:
- name: gotify
webhook_configs:
- url: "http://gotify:8080/message?token=APP_TOKEN"
You'll need a small webhook-to-Gotify adapter since Alertmanager sends JSON in a different format. Several community adapters exist on GitHub.
Uptime Kuma:
Uptime Kuma has built-in Gotify support:
- Go to Settings → Notifications
- Select Gotify as the notification type
- Enter your server URL and application token
Grafana:
Grafana supports Gotify via webhook alert channel:
- Go to Alerting → Contact Points
- Add a webhook contact point
- Use
http://gotify:8080/message?token=APP_TOKENas the URL
Message History and Management
Web interface
The Gotify web interface shows:
- All received messages, grouped by application
- Message timestamps and priorities
- Read/unread status
- Ability to delete messages individually or in bulk
API for reading messages
# Get all messages
curl -H "X-Gotify-Key: CLIENT_TOKEN" "http://your-server:8080/message"
# Get messages for a specific app
curl -H "X-Gotify-Key: CLIENT_TOKEN" "http://your-server:8080/application/1/message"
# Delete all messages for an app
curl -X DELETE -H "X-Gotify-Key: CLIENT_TOKEN" "http://your-server:8080/application/1/message"
Note: Use a client token (not an app token) for reading messages. App tokens are for sending; client tokens are for receiving.
Reverse Proxy Setup
For HTTPS access (important for mobile apps over the internet):
Caddy:
gotify.yourdomain.com {
reverse_proxy localhost:8080
}
Nginx:
server {
server_name gotify.yourdomain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support (required for real-time notifications)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
WebSocket support is required — Gotify uses WebSockets to push notifications to clients in real-time.
Plugins
Gotify supports plugins for extended functionality:
- Markdown renderer — render Markdown in the web UI
- Custom webhook receivers — accept webhooks from external services
- Message formatters — transform incoming messages
Plugins are Go shared libraries placed in the data/plugins directory.
Honest Trade-offs
Gotify is great if you:
- Need simple, reliable push notifications
- Use Android or desktop only
- Want something lightweight (64 MB RAM)
- Prefer a security-first approach (mandatory authentication)
- Need a message history with web UI
Choose ntfy instead if you:
- Need iOS support (Gotify has no iOS app)
- Want file attachments in notifications
- Need click actions (open URL from notification)
- Want the option of a hosted fallback (ntfy.sh)
Consider a commercial service if you:
- Need SMS or phone call escalation
- Need on-call rotation and scheduling (use PagerDuty or Opsgenie)
- Need team acknowledgment workflows
The bottom line: Gotify does one thing well — send push notifications to your devices. The API is dead simple (one curl command), the server is tiny, and it just works. If you're on Android and want to know when things break on your server, Gotify is all you need.