Overseer is a developer-friendly CLI process manager built on top of systemd. It wraps the complexity of writing systemd service files and running systemctl commands into a clean, simple interface.
Instead of writing a service file like this:
# /etc/systemd/system/api.service
[Unit]
Description=My API
[Service]
ExecStart=/home/user/api
Restart=always
User=user
[Install]
WantedBy=multi-user.targetYou use overseer:
overseer add api "./api --port 8080"
overseer start api
overseer logs apiUnder the hood, overseer generates the service file, installs it as a systemd user unit, and uses systemctl --user to manage it.
- A Linux system with systemd installed
- A user session with systemd support (standard on modern Linux distros)
To keep services running after you log out, enable lingering for your user:
loginctl enable-linger $USERDownload the latest release for your platform from GitHub Releases and install it globally.
# Determine platform (linux or darwin) and architecture (amd64 or arm64)
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
ARCH=$(uname -m)
case "$ARCH" in
x86_64) ARCH="amd64" ;;
aarch64|arm64) ARCH="arm64" ;;
esac
# Download and install
curl -sL "https://github.com/tacheraSasi/overseer/releases/latest/download/overseer-${OS}-${ARCH}.tar.gz" -o overseer.tar.gz
tar xzf overseer.tar.gz
sudo mv "overseer-${OS}-${ARCH}" /usr/local/bin/overseer
sudo chmod +x /usr/local/bin/overseer
rm overseer.tar.gzNot supported.
overseer --versionAdd and install a new managed service.
overseer add api "./api --port 8080"
overseer add worker "python3 worker.py --queue default"
overseer add nginx "nginx -g 'daemon off;'"This:
- Generates a systemd unit file at
~/.config/overseer/services/<name>.service - Copies it to
~/.config/systemd/user/<name>.service - Runs
systemctl --user daemon-reload - Enables the service (
systemctl --user enable <name>) - Registers the service in the overseer registry (
~/.config/overseer/registry.json)
Start a managed service.
overseer start apiStop a running service.
overseer stop apiRestart a service (stop then start).
overseer restart apiShow the current status and recent events for a service.
overseer status apiView the last 50 log lines for a service using journalctl.
overseer logs apiList all services managed by overseer, along with their current systemd status.
overseer listEnable a service to start automatically at login.
overseer enable apiDisable a service from starting at login.
overseer disable apiStop, disable, and completely remove a service from overseer and systemd.
overseer remove apiThis:
- Stops the service
- Disables the service (removes from auto-start)
- Removes the unit files
- Reloads systemd
- Unregisters the service from the overseer registry
Show overseer configuration paths and system info.
overseer infoShow the overseer version.
overseer --versionService names must:
- Start with a letter or digit
- Contain only letters, digits, hyphens (
-), and underscores (_)
Invalid names (e.g., names containing spaces, slashes, or special characters) are rejected to prevent command injection and ensure compatibility with systemd.
examples/overseer/
├── main.vint # CLI entry point - argument parsing and command dispatch
├── overseer_config.vint # Service registry management (package)
├── overseer_display.vint # Terminal output and formatting utilities (package)
├── overseer_service.vint # Systemd unit file generation and installation (package)
└── overseer_systemctl.vint # systemctl / journalctl wrappers (package)
| Feature | Where Used |
|---|---|
package |
All 4 sub-modules encapsulate their logic cleanly |
const |
Version, colors, config constants |
switch |
Clean command dispatch in main.vint |
import (built-in) |
cli, os, shell, json, term, time, path, regex, fmt |
import (user pkg) |
The 4 overseer packages imported by main.vint |
Package init |
Auto-run on import to set up config paths |
| Private members | _ prefix for internal-only package state |
path.join() |
Safe cross-platform path construction |
regex.match() |
Service name validation against injection |
fmt.padRight() |
Aligned key-value output in status display |
File I/O (os) |
Reading/writing service and registry files |
Shell (shell) |
Running systemctl and journalctl commands |
JSON (json) |
Persisting the service registry |
Terminal (term) |
Styled output, tables, banners, messages |
CLI (cli) |
Argument parsing |
| Dicts & arrays | Service registry, table rows, command routing |
| Dict methods | .has(), .keys(), .remove() for registry ops |
| Functions / closures | Command handlers, guards, validators |
| String methods | .trim(), .contains(), .split(), .substring() |
| Error handling | Guard functions with early exit |
Generated service files use the systemd user unit format:
[Unit]
Description=Overseer managed service: <name>
After=network.target
[Service]
Type=simple
ExecStart=<your command>
WorkingDirectory=/home/<user>
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/<user>/.local/bin
Restart=on-failure
RestartSec=5
StartLimitIntervalSec=60
StartLimitBurst=3
StandardOutput=journal
StandardError=journal
SyslogIdentifier=<name>
[Install]
WantedBy=default.targetService files are stored in:
- Overseer copy:
~/.config/overseer/services/<name>.service - Systemd unit:
~/.config/systemd/user/<name>.service
The service registry is stored as JSON at ~/.config/overseer/registry.json:
{
"services": {
"api": {
"name": "api",
"command": "./api --port 8080",
"created_at": "2024-01-15 10:30:00"
}
}
}# Navigate to the overseer directory
cd examples/overseer
# Add a service
overseer add api "./api --port 8080"
# Start it
overseer start api
# Check it's running
overseer status api
# View logs
overseer logs api
# Restart after a code update
overseer restart api
# Control auto-start
overseer enable api
overseer disable api
# List all services
overseer list
# Show config paths
overseer info
# Remove it
overseer remove api