HomeButler helps you answer the boring but painful questions every homelab eventually creates:
- What is running on my server right now?
- Which container owns this port?
- Why did this service restart at 3 AM?
- Is my backup actually restorable?
- Can I install this self-hosted app without hand-writing another compose file?
- Can I let an AI assistant inspect my server without handing it a full SSH shell?
No daemon required. No database. No always-on web service. Just one Go binary you can use from the terminal, scripts, a web dashboard, or AI tools.
The design goal is simple: give humans and agents a narrow, structured interface to the server. HomeButler returns readable summaries and JSON instead of asking you to trust a black-box shell session.
<p align="center"> <a href="https://www.youtube.com/watch?v=MFoDiYRH_nE"> <img src="assets/demo-thumbnail.png" alt="homebutler demo" width="800" /> </a> </p> <p align="center"><em>▶️ 34s demo — monitor, diagnose, and manage your homelab</em></p>Quick Start
# One-line install (auto-detects OS/arch)
curl -fsSL https://raw.githubusercontent.com/Higangssh/homebutler/main/install.sh | sh
# Or via Homebrew
brew install Higangssh/homebutler/homebutler
# Interactive setup — add your servers in seconds
homebutler initUse it right away:
homebutler status # CPU, memory, disk, uptime
homebutler docker list # running containers
homebutler inventory scan # containers + ports + topology
homebutler report # butler-style health report + change summary
homebutler install uptime-kuma # deploy a self-hosted app
homebutler backup drill uptime-kuma # verify a backup actually restores
homebutler watch tui # terminal dashboard
homebutler serve # web dashboard at http://localhost:8080Machine-readable output is available everywhere:
homebutler status --json
homebutler inventory scan --json
homebutler report --jsonWhat it does
- Install apps — deploy Uptime Kuma, Jellyfin, Pi-hole, Gitea, Portainer, and more with one command
- Map your server — see containers, exposed ports, system ports, and service topology
- Run a doctor check — diagnose resource pressure, stopped containers, public ports, backup hygiene, notifications, and report baseline readiness
- Catch crashes — save logs before/after Docker, systemd, or PM2 restarts and detect flapping loops
- Verify backups — boot backups in isolated containers before you trust them
- Use it anywhere — CLI, JSON, web dashboard, or MCP for AI agents without giving them SSH
Why homebutler?
Self-hosting is not hard because one docker compose up is hard. It is hard because the maintenance never ends: ports collide, containers restart silently, backups look fine until restore day, and every server becomes a slightly different snowflake.
HomeButler is a small operations toolkit for that messy middle.
Why not just use Portainer, Netdata, or CasaOS?
Those are great dashboards. HomeButler is CLI-first, scriptable, JSON-friendly, air-gap friendly, and safe to copy onto any server. Use it when you want commands you can run from a terminal, cron job, SSH session, CI script, or AI agent — especially when you care more about “what changed?” than another graph.
Core workflows
🧾 Butler Report
homebutler report
homebutler report --keep 7 # retain only the latest 7 snapshots
homebutler report --no-save # preview without writing a snapshotreport gives you a concise butler-style summary of your homelab: current health, warnings, notable changes since the previous snapshot, and suggested next commands. On the first run, HomeButler creates a baseline under ~/.homebutler/reports/snapshots/; later runs compare against the latest snapshot. Old snapshots are pruned automatically (--keep 30 by default) so reports do not grow forever.
🩺 Doctor Check
homebutler doctor
homebutler doctor --strict # non-zero exit if warnings/failures are found
homebutler doctor --json # automation / MCP friendlydoctor is a read-only preflight for the problems homelab users usually discover too late: high disk or memory usage, stopped containers, public bind ports, stale or missing backups, missing notifications, and whether report has a baseline for change detection.
📦 One-Command App Install
<p align="center"> <img src="assets/install-demo.gif" alt="homebutler install demo" width="900"> </p>
homebutler install uptime-kuma— Deploy self-hosted apps in seconds. Pre-checks Docker, ports, and duplicates. Generatesdocker-compose.ymlautomatically. See all available apps →
🗺️ Inventory & Topology
homebutler inventory scan
homebutler inventory export --format mermaid
homebutler --json inventory scaninventory scan gives you a quick map of what is running on a server: system health, Docker containers, app ports, and system ports. Docker-published ports are connected back to the container that owns them, so local forwarding details like Colima/Lima stay understandable.
🏠 Home Network
Server homelab (192.168.1.10)
Summary ✅ 1 running · ⚪ 1 stopped · 🌍 2 public ports · 🔒 4 local ports
📦 Containers (2)
├─ ⚪ vaultwarden · not started
│ └─ image vaultwarden/server:latest
└─ ✅ api-server · running
├─ image my-api:latest
└─ exposes :8080 → 8080/tcp
🌐 App Ports (1)
└─ 🌍 :8080/tcp · api-serverUse Mermaid export when you want a diagram for GitHub, Obsidian, docs, or an AI assistant:
graph TD
home["🏠 Home Network"] --> homelab["🖥 homelab<br/>192.168.1.10"]
homelab --> c1["📦 api-server<br/>running"]
homelab --> p1["🌍 :8080/tcp<br/>api-server"]
c1 -. exposes .-> p1Demo
🌐 Web Dashboard
<p align="center"> <img src="assets/web-dashboard.png" alt="homebutler web dashboard" width="900"> </p><details> <summary>✨ Web Dashboard Highlights</summary>
homebutler serve— A real-time web dashboard embedded in the single binary viago:embed. Monitor all your servers, Docker containers, open ports, alerts, and Wake-on-LAN devices from any browser. Dark theme, auto-refresh every 5 seconds, fully responsive.
- Server Overview — See all servers at a glance with color-coded status (green = online, red = offline)
- System Metrics — CPU, memory, disk usage with progress bars and color thresholds
- Docker Containers — Running/stopped status with friendly labels ("Running · 4d", "Stopped · 6h ago")
- Top Processes — Top processes sorted by CPU/memory with zombie detection
- Resource Warnings — Visual CPU, memory, and disk thresholds in the dashboard
- Network Ports — Open ports with process names and bind addresses
- Wake-on-LAN — One-click wake buttons for configured devices
- Server Switching — Dropdown to switch between local and remote servers
- Zero dependencies — No Node.js runtime needed. Frontend is compiled into the Go binary at build time
homebutler serve # Start on port 8080
homebutler serve --port 3000 # Custom port
homebutler serve --demo # Demo mode with realistic sample data🔄 Process Restart Watch
Your container crashed at 3 AM — but why? homebutler watch catches it the moment it happens, saves the dying logs, figures out the cause, and tells you if it's happening over and over.
Supported backends: Docker (real-time event stream) · systemd (polling) · PM2 (polling)
Step 1: Add targets to watch
homebutler watch add nginx # Interactive: choose Docker / systemd / PM2
homebutler watch add --kind docker nginx # or specify directly
homebutler watch add --kind systemd nginx.service
homebutler watch add --kind pm2 my-api
homebutler watch list # See what you're watchingStep 2: Start monitoring
homebutler watch start # Foreground, Ctrl+C to stop
homebutler watch start --interval 10s # Custom poll interval (default 30s)When a crash is detected, you'll see:
[03:14:22] INCIDENT: nginx (incident nginx-20260410-031422.581-7a2124)
Crash: OOM — process killed by SIGKILL (oom, confidence: high)
⚠ FLAPPING: acute (3 restarts in short window)Step 3: Investigate
homebutler watch history # List all incidents
homebutler watch show <incident-id> # Full detailswatch show output includes:
- Pre-death logs — what the process printed right before it died
- Post-restart logs — what happened after the restart
- Crash analysis — category (oom / panic / segfault / timeout / dependency / error), reason, confidence level, matched log patterns
- Flapping status — if the process is stuck in a crash loop
Crash Analysis
Every incident is automatically analyzed using exit codes and log patterns:
| Signal | Exit Code | Meaning |
|---|---|---|
| SIGKILL | 137 | OOM Killer or forced kill |
| SIGSEGV | 139 | Segmentation fault (memory corruption) |
| SIGTERM | 143 | Graceful shutdown request |
| — | 1 | Application error |
| — | 0 | Clean exit (may be intentional restart) |
Log patterns like panic:, Out of memory, Connection refused, FATAL, and timeout are matched automatically to help identify the root cause.
Flapping Detection
Detects when a process is stuck in a restart loop (e.g., crash → restart → crash again):
- Acute — 3+ restarts within 10 minutes (something is broken right now)
- Chronic — 5+ restarts within 24 hours (slow recurring issue)
Flapping incidents are tagged [FLAPPING] in history and highlighted in watch show.
Notifications (optional, off by default)
Notifications are disabled by default, which is useful for air-gapped or closed networks where everything runs locally.
A minimal example in ~/.config/homebutler/config.yaml:
notify:
telegram:
bot_token: "your-bot-token"
chat_id: "your-chat-id"
watch:
enabled: true
notify_on: flapping
cooldown: 5m
flapping:
short_window: 10m
short_threshold: 3
long_window: 24h
long_threshold: 5
alerts:
cpu: 90
memory: 85
disk: 90
rules:
- name: cpu-spike
metric: cpu
threshold: 90
action: notifyLegacy ~/.homebutler/watch/config.json is still read as a fallback for watch-specific settings, and legacy alerts.yaml notify/webhook provider settings are still accepted
…