A lightweight, self-hosted personal dashboard for monitoring and accessing your home lab services. Built with Go and vanilla JavaScript — no framework dependencies, no bloat.
| Dark | Light |
|---|---|
![]() |
![]() |
- Service Dashboard — Centralized hub for all your self-hosted applications organized into sections
- Real-time Health Checks — Background HTTP/HTTPS status monitoring pushed to the UI over WebSocket
- Search & Filter — Full-text search across service titles, descriptions, and tags (
/orCtrl+K) - Keyboard Shortcuts —
/orCtrl+Kto search,Rto refresh,Escto close - Light / Dark Theme — Automatic or explicit theme selection with custom accent colors per card
- Live Config Reload — Reload configuration without restarting via
POST /api/reload - Minimal Footprint — Single binary, ~1,000 lines of code, two external Go dependencies
git clone https://github.com/haydenk/homestead.git
cd homestead
go build -o homestead .
./homestead -config config.tomldocker build -t homestead .
docker run -d \
--name homestead \
-p 8080:8080 \
-v $(pwd)/config.toml:/app/config/config.toml \
homesteadBuild packages with nfpm:
nfpm packageThe package:
- Installs the binary to
/usr/bin/homestead - Places the config at
/etc/homestead/config.toml - Registers and enables a hardened systemd service running as a non-root
homesteaduser
systemctl enable --now homesteadHomestead is configured via a TOML file. Copy the included config.toml and edit to suit your setup.
title = "Homestead"
subtitle = "My self-hosted dashboard"
logo = "🏠"
columns = 4 # cards per row (1–6)
check_interval = 30 # seconds between health checks
footer = "Running on Proxmox"
theme = "dark" # "dark" | "light" | omit for system default
[[sections]]
name = "Media"
icon = "🎬"
[[sections.items]]
title = "Jellyfin"
url = "https://jellyfin.lan"
description = "Media server"
icon = "🎞️" # emoji or image URL
tags = ["media", "streaming"]
status_check = true # enable health monitoring
color = "#00a4dc" # accent color (hex)
target = "_blank" # "_blank" | "_self"
[[sections.items]]
title = "Sonarr"
url = "https://sonarr.lan"
description = "TV show management"
icon = "📺"
tags = ["media", "automation"]
status_check = true- Uses a
HEADrequest first; falls back toGETif the server returns405 Method Not Allowed - Any response with
statusCode < 500is considered up (including auth-protected endpoints) - Self-signed certificates are accepted
- Request timeout: 10 seconds
Configuration can be overridden via flags or environment variables:
| Flag | Env var | Default | Description |
|---|---|---|---|
-config |
HOMESTEAD_CONFIG |
config.toml |
Path to config file |
-host |
HOMESTEAD_HOST |
(all interfaces) | Bind address |
-port |
HOMESTEAD_PORT |
8080 |
Listen port |
By default Homestead listens on all IPv4 and IPv6 interfaces. Pass -host to restrict to a specific address.
# Default: all interfaces, IPv4 + IPv6
./homestead -config /etc/homestead/config.toml
# Loopback only
./homestead -host 127.0.0.1 -port 9000| Method | Path | Description |
|---|---|---|
GET |
/ |
Web UI |
WS |
/ws |
Real-time status updates (WebSocket) |
POST |
/api/reload |
Reload config from disk and restart checks |
GET |
/api/health |
Health probe ({"status":"ok","time":"..."}) |
The WebSocket endpoint (/ws) pushes the full status snapshot immediately on connect, then again after each check round. See docs/api.md for the full reference.
Requirements: Go 1.22+. Tool versions are managed via mise (.mise.toml).
# Install tools
mise install
# Run locally
go run . -config config.toml
# Format
go fmt ./...A VS Code dev container is included (.devcontainer/) with Go, mise, and the TOML formatter pre-configured.
.
├── main.go # Entry point, flag parsing, graceful shutdown
├── config.toml # Example configuration
├── Dockerfile # Multi-stage build (golang:1.22-alpine → alpine:3.19)
├── homestead.service # systemd unit file
├── nfpm.yaml # Package build config (deb, rpm, apk)
├── internal/
│ ├── config/config.go # TOML config structs and loader
│ ├── checker/checker.go # Background health check engine
│ └── server/
│ ├── server.go # HTTP server setup, routing, dual-stack listener
│ ├── hub.go # WebSocket connection hub and broadcaster
│ └── handlers.go # HTTP and WebSocket handler implementations
└── web/
├── index.html # UI template
├── app.js # Frontend logic (vanilla JS)
└── style.css # Styles with light/dark theme support
- Backend: Go standard library +
BurntSushi/toml+gorilla/websocket - Frontend: HTML5, vanilla JavaScript (ES2020+), CSS3 custom properties
- Packaging: Docker (Alpine), systemd, nfpm (deb/rpm/apk)
GPL-3.0. See LICENSE.

