Skip to content

Deploying a Gotify App

Introduction

Gotify is a powerful, open-source self-hosted notification server written in Go that enables you to send and receive push notifications in real-time. Whether you’re building automated alerting systems, monitoring infrastructure, or creating custom notification workflows, Gotify provides a simple REST API and WebSocket support for seamless integration with your applications and services.

Deploying Gotify on Klutch.sh gives you a managed, scalable platform for running your notification server with automatic HTTPS, persistent storage for your messages and users, and easy configuration through environment variables. This comprehensive guide walks you through deploying Gotify using a Dockerfile, configuring persistent volumes for data retention, setting up security, and managing your notification server in production.


Prerequisites

  • A Klutch.sh account (sign up here)
  • A GitHub repository for your Gotify deployment
  • Basic familiarity with Docker and environment variables
  • (Optional) A custom domain for your notification server

What You’ll Deploy

  • Inputs: GitHub repository with a Dockerfile for Gotify
  • Outputs: Running Gotify notification server on Klutch.sh accessible over HTTPS
  • Success Criteria: Web UI loads, you can create applications and tokens, send test notifications via API, and data persists across restarts

Key features:

  • Real-time push notifications via WebSocket
  • Simple REST API for sending messages
  • User and application management
  • Message history with persistent storage
  • Mobile app support (Android)

Getting Started: Understanding Gotify

Gotify consists of a web UI for managing applications and viewing notifications, and a REST API for sending messages. The server stores all data (users, applications, messages) in an SQLite database by default, making it lightweight and easy to manage.

Key Concepts

  1. Applications: Represent services that send notifications (e.g., monitoring system, CI/CD pipeline)
  2. Clients: Devices or browsers that receive notifications
  3. Messages: The actual notifications with title, content, and priority
  4. Tokens: API keys used to authenticate applications and clients

1. Prepare Your Repository

Create a new GitHub repository for your Gotify deployment. You have two deployment options:

Option A: Without Dockerfile (Nixpacks)

  • Use Klutch.sh’s automatic build detection
  • No Dockerfile needed
  • Ideal for quick deployments

Option B: With Dockerfile

  • More control over build process
  • Pinned versions for reproducibility
  • Custom configuration in Dockerfile

Minimal repository structure for either approach:

gotify-deploy/
├── Dockerfile (optional, for manual Docker deployments)
├── config.yml (optional)
└── README.md

For a quick start without Dockerfile, you only need a README and optionally a configuration file. Klutch.sh will automatically use the official Gotify Docker image via Nixpacks.


2. Deploying Without a Dockerfile (Using Nixpacks)

Klutch.sh uses Nixpacks to automatically detect and deploy Gotify. This method is perfect for getting started quickly without managing a custom Dockerfile.

Prepare Your Repository for Nixpacks

For Nixpacks to detect and deploy Gotify, your repository needs:

  1. A README.md file at the repository root
  2. Optionally, a config.yml file in the root directory for custom configuration

Example minimal repository structure:

gotify-deploy/
├── README.md
├── config.yml (optional)
└── .gitignore

Example README.md:

# Gotify Notification Server
Self-hosted notification server deployed on Klutch.sh.
## Configuration
Configure Gotify through environment variables in Klutch.sh dashboard:
- `GOTIFY_DEFAULTUSER_PASS` - Admin password
- `GOTIFY_REGISTRATION` - Enable/disable user registration
- `GOTIFY_MESSAGERETENTION` - Message retention in days
## Documentation
See the deployment guide for complete setup instructions.

Deploy via Nixpacks

  1. Push repository to GitHub
    • Ensure your repository has a README.md
    • Add any configuration files you want to track
    • Commit and push to your GitHub repository
  2. Log in to Klutch.sh
  3. Create a new project
    • Click Create Project
    • Give it a descriptive name (e.g., "Notification Server")
  4. Create a new app
    • Click Create App
    • Connect your GitHub repository
    • Select the branch to deploy (usually main or master)
  5. Configure the app settings
    • Traffic Type: Select HTTP
    • Internal Port: Set to 80 (Gotify's default port)
    • Region: Choose your preferred region
    • Compute: Start with a small instance (Gotify is lightweight)
    • Instances: 1 instance is sufficient
  6. Attach persistent volume
    • Add a volume with mount path /app/data
    • Set size to at least 1GB
  7. Add environment variables
    • Set the variables listed in section 4 of this guide
    • Mark sensitive values as secrets
    • Important: Change the default admin password from "admin" to a strong password
  8. Deploy
    • Click "Create" to start the deployment
    • Klutch.sh will build and deploy Gotify automatically
    • Monitor the build logs for any errors

Advantages of Nixpacks deployment:

  • No need to manage a Dockerfile
  • Automatic updates to the Gotify image
  • Simpler repository structure
  • Faster setup for new deployments

3. Deploying With a Dockerfile

Gotify provides an official Docker image that’s production-ready. Create a Dockerfile in your repository root:

# Use the official Gotify image
FROM gotify/server:latest
# The official image handles everything needed
# Data is stored in /app/data
# Configuration can be provided via environment variables or config.yml
# Expose the default Gotify port
EXPOSE 80
# The base image already sets the correct CMD
# It runs: ./gotify-app

This minimal Dockerfile uses the official Gotify image which includes:

  • The compiled Gotify server binary
  • Default configuration
  • Web UI assets
  • SQLite database support

Advanced Dockerfile with Specific Version

For production environments, it’s recommended to pin a specific version:

# Pin to a specific Gotify version for reproducible builds
FROM gotify/server:2.4.0
# Expose port 80 (Gotify default)
EXPOSE 80
# Optional: Set default environment variables
# These can be overridden in Klutch.sh
ENV GOTIFY_SERVER_PORT=80
ENV GOTIFY_SERVER_KEEPALIVEPERIODSECONDS=0
ENV GOTIFY_SERVER_LISTENADDR=""
ENV GOTIFY_SERVER_SSL_ENABLED=false
# The base image CMD is already set correctly

Note: Klutch.sh automatically detects the Dockerfile in your repository root and uses it for deployment.


4. Persistent Storage Configuration

Gotify stores all data in the /app/data directory inside the container, including:

  • SQLite database (gotify.db)
  • User accounts and passwords
  • Application tokens
  • Message history
  • Uploaded images

To prevent data loss when redeploying, you must attach a persistent volume.

Volume Configuration in Klutch.sh

When creating your app in Klutch.sh:

  1. Navigate to your app settings
  2. Go to the "Volumes" section
  3. Click "Add Volume"
  4. Configure the volume:
    • Mount Path: /app/data
    • Size: Start with 1GB (adjust based on message retention needs)
  5. Save the volume configuration

Important: The volume must be attached before first deployment to ensure the default admin user credentials are persisted.


5. Environment Variables and Configuration

Gotify can be configured through environment variables or a config.yml file. For Klutch.sh deployments, environment variables are the recommended approach.

Essential Environment Variables

Add these in the Klutch.sh dashboard under your app’s environment variables:

Terminal window
# Server Configuration
GOTIFY_SERVER_PORT=80
GOTIFY_SERVER_LISTENADDR=""
# Database (SQLite is default, stored in /app/data)
GOTIFY_DATABASE_DIALECT=sqlite3
GOTIFY_DATABASE_CONNECTION=/app/data/gotify.db
# Security - IMPORTANT: Replace with your actual domain in production
# Example: GOTIFY_SERVER_STREAM_ALLOWEDORIGINS="https://example-app.klutch.sh"
GOTIFY_SERVER_STREAM_ALLOWEDORIGINS="https://example-app.klutch.sh"

Optional Environment Variables

Terminal window
# Default admin credentials (set a strong password before deployment)
GOTIFY_DEFAULTUSER_NAME=admin
GOTIFY_DEFAULTUSER_PASS=your-secure-password-here
# Registration (disable in production)
GOTIFY_REGISTRATION=false
# Upload limits
GOTIFY_UPLOADEDIMAGESDIR=/app/data/images
GOTIFY_MAXMESSAGESIZE=2048
# WebSocket keepalive
GOTIFY_SERVER_KEEPALIVEPERIODSECONDS=45
# Message retention (in days, 0 = unlimited)
GOTIFY_MESSAGERETENTION=90

Security Note: Never commit secrets to your repository. Always use Klutch.sh’s environment variable management and mark sensitive values as secret.


6. Deploying to Klutch.sh

Follow these steps to deploy Gotify on Klutch.sh:

  1. Push your repository to GitHub
    • Ensure your Dockerfile is in the root directory
    • Commit and push all changes
  2. Log in to Klutch.sh
  3. Create a new project
    • Click Create Project
    • Give it a descriptive name (e.g., "Notification Server")
  4. Create a new app
    • Click Create App
    • Connect your GitHub repository
    • Select the branch to deploy (usually main or master)
  5. Configure the app settings
    • Traffic Type: Select HTTP
    • Internal Port: Set to 80 (Gotify's default port)
    • Region: Choose your preferred region
    • Compute: Start with a small instance (Gotify is lightweight)
    • Instances: 1 instance is sufficient for most use cases
  6. Attach persistent volume
    • Add a volume with mount path /app/data
    • Set size to at least 1GB
  7. Add environment variables
    • Add the essential environment variables listed in section 4
    • Mark sensitive values as secrets
    • Important: Change the default admin password from "admin" to a strong password
  8. Deploy
    • Click "Create" to start the deployment
    • Klutch.sh will build your Docker image and start the container
    • Monitor the build logs for any errors

Once deployment completes, your Gotify server will be available at example-app.klutch.sh (replace with your actual app URL).


7. Initial Setup and Configuration

After your first deployment:

  1. Access the Web UI
    • Navigate to your app URL (e.g., https://example-app.klutch.sh)
    • You'll see the Gotify login page
  2. Log in with your credentials
    • Username: admin (or the value you set in GOTIFY_DEFAULTUSER_NAME)
    • Password: The secure password you set in GOTIFY_DEFAULTUSER_PASS
  3. Change the admin password immediately
    • Click on "Users" in the sidebar
    • Click the edit icon for the admin user
    • Set a strong password
    • Save changes
  4. Create your first application
    • Click "Apps" in the sidebar
    • Click "Create Application"
    • Give it a name (e.g., "Test App")
    • Optionally set a description and upload an icon
    • Save the application
    • Important: Copy the generated token immediately (you won't be able to see it again)
  5. Send a test notification
    • Use curl or any HTTP client:
Terminal window
curl -X POST "https://example-app.klutch.sh/message" \
-H "X-Gotify-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Test Notification",
"message": "Hello from Klutch.sh!",
"priority": 5
}'

You should see the notification appear in the web UI immediately.


8. Using the Gotify API

Gotify provides a simple REST API for sending messages and managing resources.

Send a Message

Terminal window
# Basic message
curl -X POST "https://example-app.klutch.sh/message" \
-H "X-Gotify-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Alert", "message": "Server CPU is high", "priority": 8}'
# Message with markdown
curl -X POST "https://example-app.klutch.sh/message" \
-H "X-Gotify-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Deployment Status",
"message": "**Deployment Successful**\n\n- Environment: Production\n- Version: v2.1.0\n- Duration: 3m 45s",
"priority": 5,
"extras": {
"client::display": {
"contentType": "text/markdown"
}
}
}'

Priority Levels

Gotify supports priority levels from 0 to 10:

  • 0-3: Low priority (no sound/vibration)
  • 4-7: Normal priority (default notification)
  • 8-10: High priority (urgent, will notify even in do-not-disturb mode)

Get Messages

Terminal window
# Get all messages for your client
curl "https://example-app.klutch.sh/message" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"
# Get messages with pagination
curl "https://example-app.klutch.sh/message?limit=10&since=0" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"

Delete Messages

Terminal window
# Delete a specific message
curl -X DELETE "https://example-app.klutch.sh/message/123" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"
# Delete all messages for an app
curl -X DELETE "https://example-app.klutch.sh/application/1/message" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"

WebSocket Connection

Gotify supports real-time notifications via WebSocket:

// Connect to WebSocket endpoint
const ws = new WebSocket('wss://example-app.klutch.sh/stream?token=YOUR_CLIENT_TOKEN');
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
console.log('New notification:', message);
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};

9. Integration Examples

Shell Script Notifications

#!/bin/bash
# Send notification from a shell script
GOTIFY_URL="https://example-app.klutch.sh"
GOTIFY_TOKEN="YOUR_APP_TOKEN"
send_notification() {
local title="$1"
local message="$2"
local priority="${3:-5}"
curl -s -X POST "${GOTIFY_URL}/message" \
-H "X-Gotify-Key: ${GOTIFY_TOKEN}" \
-H "Content-Type: application/json" \
-d "{\"title\": \"${title}\", \"message\": \"${message}\", \"priority\": ${priority}}"
}
# Usage
send_notification "Backup Complete" "Database backup finished successfully" 5

Python Integration

import requests
import json
class GotifyClient:
def __init__(self, url, token):
self.url = url.rstrip('/')
self.token = token
def send_message(self, title, message, priority=5, extras=None):
payload = {
'title': title,
'message': message,
'priority': priority
}
if extras:
payload['extras'] = extras
headers = {
'X-Gotify-Key': self.token,
'Content-Type': 'application/json'
}
response = requests.post(
f'{self.url}/message',
headers=headers,
data=json.dumps(payload)
)
return response.json()
# Usage
client = GotifyClient('https://example-app.klutch.sh', 'YOUR_APP_TOKEN')
client.send_message(
'Deployment Alert',
'Application deployed to production',
priority=7
)

Node.js/JavaScript Integration

const axios = require('axios');
class GotifyClient {
constructor(url, token) {
this.url = url.replace(/\/$/, '');
this.token = token;
}
async sendMessage(title, message, priority = 5, extras = null) {
const payload = {
title,
message,
priority,
};
if (extras) {
payload.extras = extras;
}
try {
const response = await axios.post(
`${this.url}/message`,
payload,
{
headers: {
'X-Gotify-Key': this.token,
'Content-Type': 'application/json',
},
}
);
return response.data;
} catch (error) {
console.error('Failed to send notification:', error.message);
throw error;
}
}
}
// Usage
const client = new GotifyClient('https://example-app.klutch.sh', 'YOUR_APP_TOKEN');
client.sendMessage('Build Status', 'Build #142 completed successfully', 5);

Monitoring Integration

Integrate Gotify with monitoring systems:

# Prometheus Alertmanager webhook receiver
# Create a script that receives webhooks and forwards to Gotify
#!/bin/bash
GOTIFY_URL="https://example-app.klutch.sh"
GOTIFY_TOKEN="YOUR_APP_TOKEN"
# Read alert from stdin
ALERT=$(cat)
# Parse alert details (simplified example)
ALERT_NAME=$(echo "$ALERT" | jq -r '.alerts[0].labels.alertname')
ALERT_DESCRIPTION=$(echo "$ALERT" | jq -r '.alerts[0].annotations.description')
SEVERITY=$(echo "$ALERT" | jq -r '.alerts[0].labels.severity')
# Map severity to priority
case $SEVERITY in
critical)
PRIORITY=10
;;
warning)
PRIORITY=7
;;
*)
PRIORITY=5
;;
esac
# Send to Gotify
curl -X POST "${GOTIFY_URL}/message" \
-H "X-Gotify-Key: ${GOTIFY_TOKEN}" \
-H "Content-Type: application/json" \
-d "{
\"title\": \"Alert: ${ALERT_NAME}\",
\"message\": \"${ALERT_DESCRIPTION}\",
\"priority\": ${PRIORITY}
}"

10. Security Best Practices

Protect your Gotify instance with these security measures:

  1. Change default credentials immediately
    • Never use the default admin/admin credentials in production
    • Use a strong, unique password
  2. Disable user registration
    • Set GOTIFY_REGISTRATION=false to prevent unauthorized users from creating accounts
    • Create users manually through the admin interface
  3. Manage tokens securely
    • Store API tokens in environment variables or secrets managers
    • Never commit tokens to version control
    • Rotate tokens periodically
    • Delete unused application tokens
  4. Use HTTPS only
    • Klutch.sh provides automatic HTTPS
    • Never expose Gotify over plain HTTP in production
    • Ensure all API calls use HTTPS URLs
  5. Limit CORS origins (Critical)
    • Always specify exact origins for production:
    • GOTIFY_SERVER_STREAM_ALLOWEDORIGINS="https://example-app.klutch.sh"
    • Never use wildcard "*" in production as it allows any domain to access your WebSocket stream
    • For multiple domains, use comma-separated values: "https://domain1.com,https://domain2.com"
  6. Regular backups
    • Back up the /app/data volume regularly
    • Test restore procedures periodically
  7. Monitor access logs
    • Review Gotify logs in Klutch.sh dashboard
    • Watch for suspicious authentication attempts
    • Set up alerts for failed login attempts
  8. Keep Gotify updated
    • Pin specific versions in your Dockerfile for stability
    • Update regularly to get security patches
    • Test updates in a staging environment first

11. Custom Domain Configuration

To use your own domain with Gotify:

  1. Add domain in Klutch.sh
    • Navigate to your app settings
    • Go to the "Domains" section
    • Add your custom domain (e.g., notify.yourdomain.com)
    • See custom domains documentation for details
  2. Configure DNS
    • Add a CNAME record pointing to your Klutch.sh app URL
    • Or add an A record with the provided IP address
  3. Update environment variables
    • No need to change GOTIFY_SERVER_PORT or internal settings
    • Update any hardcoded URLs in your application code
  4. Wait for DNS propagation
    • DNS changes may take up to 48 hours to propagate
    • Klutch.sh will automatically provision SSL certificates

12. Monitoring and Maintenance

Monitor Your Gotify Instance

  1. Check application health
    • Use the health endpoint: curl https://example-app.klutch.sh/health
    • Expected response: {"health":"green","database":"green"}
  2. Monitor resource usage
    • Check CPU and memory usage in Klutch.sh dashboard
    • Gotify is lightweight; issues usually indicate configuration problems
  3. Review logs
    • Access logs through Klutch.sh dashboard
    • Look for error messages or failed authentication attempts
  4. Database maintenance
    • Set GOTIFY_MESSAGERETENTION to auto-delete old messages
    • Monitor volume usage to prevent disk space issues
    • Consider periodic database vacuuming for SQLite: VACUUM;

Scaling Considerations

Gotify is designed to be lightweight and efficient:

  • Single instance: Sufficient for most use cases (thousands of messages per day)
  • Database: SQLite is appropriate unless you need high concurrency
  • Volume size: Monitor message storage; increase volume size if needed
  • Connection limits: WebSocket connections are lightweight; one instance can handle hundreds of concurrent clients

If you need higher availability:

  • Use a staging environment to test changes
  • Implement backup/restore procedures
  • Consider PostgreSQL for high-concurrency scenarios (requires custom configuration)

13. Troubleshooting

Common Issues and Solutions

Issue: Cannot access the web UI (502/503 errors)

  • Solution: Check that:
    • The internal port is set to 80
    • Traffic type is HTTP
    • The app has finished deploying (check build logs)
    • Environment variables are set correctly

Issue: Data lost after redeployment

  • Solution: Ensure persistent volume is attached to /app/data before first deployment
  • If volume was added later, you'll need to reconfigure from scratch

Issue: Authentication fails with “invalid username or password”

  • Solution:
    • Verify you're using the correct credentials
    • Check if GOTIFY_DEFAULTUSER_NAME and GOTIFY_DEFAULTUSER_PASS are set correctly
    • If locked out, you may need to reset the database (this will lose all data)

Issue: API requests return 401 Unauthorized

  • Solution:
    • Verify your API token is correct
    • Check that the token hasn't been deleted or regenerated
    • Ensure the X-Gotify-Key header is properly set
    • Confirm you're using an application token for sending messages, not a client token

Issue: WebSocket connection fails

  • Solution:
    • Check CORS settings: GOTIFY_SERVER_STREAM_ALLOWEDORIGINS
    • Verify you're using wss:// (secure WebSocket) not ws://
    • Ensure client token is valid
    • Check browser console for error messages

Issue: High memory usage

  • Solution:
    • Check message retention settings
    • Delete old messages you no longer need
    • Consider setting GOTIFY_MESSAGERETENTION to auto-delete
    • Review the number of open WebSocket connections

Issue: Database is locked errors

  • Solution:
    • Ensure only one Gotify instance is accessing the database
    • Check for crashed processes holding database locks
    • Restart the application if necessary

Debug Commands

Access your container logs in Klutch.sh dashboard to diagnose issues:

Terminal window
# Test API connectivity
curl -I https://example-app.klutch.sh/health
# Test authentication
curl -X GET "https://example-app.klutch.sh/current/user" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"
# List all applications
curl -X GET "https://example-app.klutch.sh/application" \
-H "X-Gotify-Key: YOUR_CLIENT_TOKEN"

14. Backup and Disaster Recovery

Implement a backup strategy to protect your notification data:

Backup Strategy

  1. What to back up:
    • /app/data/gotify.db - SQLite database (users, apps, messages)
    • /app/data/images/ - Uploaded images and icons
    • Environment variables and configuration
  2. Backup frequency:
    • Daily backups for production systems
    • Keep 7-30 days of backups depending on retention needs
    • Back up before any major changes or updates
  3. Backup methods:
    • Volume snapshots through Klutch.sh (if available)
    • Database exports using SQLite tools
    • File-based backups of the entire /app/data directory

Manual Database Backup

Terminal window
# If you have access to the container, backup the database:
sqlite3 /app/data/gotify.db ".backup /app/data/gotify-backup-$(date +%Y%m%d).db"
# Export as SQL
sqlite3 /app/data/gotify.db .dump > gotify-backup-$(date +%Y%m%d).sql

Disaster Recovery Steps

  1. Create a new Gotify deployment following the deployment steps
  2. Stop the new instance before restoring data
  3. Restore the database to /app/data/gotify.db
  4. Restore images to /app/data/images/
  5. Start the instance and verify all data is present
  6. Test functionality:
    • Log in with existing credentials
    • Verify applications and tokens are present
    • Send a test message
    • Check message history

15. Production Deployment Checklist

Before deploying Gotify to production, verify:

  • Dockerfile is using a pinned version (e.g., gotify/server:2.4.0)
  • Persistent volume attached to /app/data with adequate size
  • Default admin password changed to a strong, unique password
  • User registration disabled (GOTIFY_REGISTRATION=false)
  • CORS origins restricted to specific domains
  • Message retention policy configured (GOTIFY_MESSAGERETENTION)
  • HTTPS enabled (automatic with Klutch.sh)
  • Custom domain configured (if applicable)
  • Environment variables properly set and secrets marked as such
  • Backup strategy implemented and tested
  • Monitoring configured for health checks
  • API tokens generated and securely stored
  • Test notifications sent successfully
  • WebSocket connections working
  • Mobile app connected (if using Android app)
  • Integration with monitoring/alerting systems tested
  • Documentation created for team members

16. Additional Resources

Official Documentation

Klutch.sh Resources

Mobile Apps

Community and Support


Conclusion

Deploying Gotify on Klutch.sh provides you with a powerful, self-hosted notification system with the reliability and scalability of a managed platform. With persistent storage, automatic HTTPS, and easy configuration through environment variables, you can have a production-ready notification server running in minutes.

Whether you’re sending alerts from monitoring systems, CI/CD pipelines, or custom applications, Gotify’s simple API and real-time WebSocket support make it an excellent choice for managing notifications across your infrastructure.

Start by deploying the basic setup, test with a few applications, and gradually expand your integration as you become familiar with the platform. Don’t forget to implement security best practices and regular backups to ensure your notification system remains reliable and secure.