The missing piece
Self-hosters love Gotify. 12,000+ GitHub stars. Push notifications from every service, straight to your phone. You always know what's happening.
But knowing isn't the same as doing.
You're on a walk. Your phone buzzes — a service needs a restart. With any other setup, you'd need a laptop, a terminal, and an SSH session. The walk is over.
Tap restart nginx, get ✅ nginx restarted, keep walking.
Every Gotify plugin out there does the same thing: forward notifications somewhere else. Telegram. Slack. Email. Discord. ~20 plugins, all one-directional. Gotify talks to you. Nothing lets you talk back.
gotify-commander
It's a Gotify plugin (.so) that listens for commands and executes them. Type restart nginx on your phone. Get back ✅ nginx restarted on VPS (:80).
Phone → "restart nginx" → Gotify → Commander → systemctl restart nginx → "✅ restarted" → Phone
That's the entire flow. No app to install (beyond the Gotify app you already have). No bot to configure. No separate server to run. The plugin loads inside Gotify itself.
23 commands, one YAML config
Everything is driven by a single YAML file. Define your services, the plugin does the rest:
services:
nginx:
description: "Web Server"
machine: vps
port: 80
domain: "mysite.com"
aliases: [ng, web]
systemd: nginx
Add a service → it appears in the help, the status checks, the service list. Remove it → gone. No code changes.
The commands cover what you actually reach for at 2am:
Service management: restart, stop, start, status, logs — for any service in your config. Aliases work too: restart app can be shorthand for restart myapp.
System health: free, df (with duf for pretty output), uptime, who, top, ports, ip, connections — all with VPS/Mac target selection.
Analytics: traffic analysis via rhit (across 2 years of nginx logs), goaccess web analytics, SSL certificate expiry checks, pending system updates.
GPS locate: Tap a button, your phone sends its coordinates, the server reverse-geocodes them via OpenStreetMap. Full address, postal code, country, and a map tile. Useful when you need to confirm where a device is or just want your server to know where you are.
The web control panel
The plugin serves a web UI directly from the Gotify webhook endpoint. No separate app, no separate port. Just a URL.
Dark mode. Light mode. System mode. Pico CSS for clean typography. Dynamic tabs that load from your YAML config:
- Machine — one-tap buttons for system commands, with VPS/Mac target selection
- Sites — service chips with favicons from your domains, tap to restart/stop/start
- Monitoring — global status, analytics, certificate checks
- Location — GPS locate with reverse geocoding
Command history persists in localStorage. Each result shows in monospace with the actual output. Delete individual entries or clear all. Auto-scroll to results. Back-to-top button. The whole thing is a single HTML file embedded in the Go binary — zero external dependencies beyond a Pico CSS CDN link.
Multi-machine
One config manages services across multiple machines. Local services use systemctl. Remote services connect via SSH and use whatever init system the target runs (launchctl on macOS, systemctl on Linux). The plugin resolves the target from your config and picks the right executor automatically.
Security
The plugin runs inside Gotify, behind whatever auth and network security you already have in front of Gotify. The control panel URL contains a random token that's impossible to guess without accessing the Gotify WebUI first.
Commands are whitelisted — only services defined in your YAML are valid targets. Input is sanitized (regex validation). No shell execution — ever. Every command uses exec.CommandContext with explicit argument arrays. Timeouts on everything. All executions logged.
Dangerous commands (reboot, shutdown) show a confirmation dialog in the web UI.
Why this matters
Self-hosting is about control. But that control usually means "I need my laptop and an SSH session." gotify-commander removes that friction.
Your server sends you a notification that something is down. You tap restart. You get a confirmation. You go back to sleep. From your phone, from anywhere, with no tools beyond a Gotify app or a web browser.
No Telegram bot (not self-hosted). No Uptime Kuma (monitor only, can't act). No custom scripts on your phone. Just Gotify — the notification server you already run — with a plugin that closes the loop.
Get it
GitHub — MIT license.
Pre-built binaries available for linux/amd64, linux/arm64, and linux/arm-7. Download the .so matching your architecture, drop it in Gotify's plugin directory, configure your services in YAML, restart Gotify. Send help to see what's available.
Building from source requires matching the exact Go version used by your Gotify binary (Go plugins are version-locked). The repo includes a Makefile with Docker-based builds that handle this automatically.
Built with Go. Works with Gotify 2.6.x.