A simple, self-hosted application dashboard for self-hosted applications. Minimal dependencies, single binary, easy configuration via YAML manifest.
- Single binary - Frontend embedded in Go binary, no external dependencies
- Edit from UI - Add/remove apps directly from the dashboard - changes saved to
apps.yaml - YAML manifest - Define your apps in a simple
apps.yamlfile - Auto-refresh - Dashboard updates automatically when manifest changes
- Health monitoring - HTTP and TCP health checks with configurable intervals
- System stats - CPU, RAM, and temperature monitoring
- Dark/Light theme - Toggle with localStorage persistence
- Command palette - Quick launch apps with
Cmd/Ctrl+K - Responsive - Works on desktop and mobile
curl -L -o homedash https://github.com/jlandersen/homedash/releases/latest/download/homedash-linux-amd64
chmod +x homedash
./homedashcurl -L -o homedash https://github.com/jlandersen/homedash/releases/latest/download/homedash-linux-arm64
chmod +x homedash
./homedashcurl -L -o homedash https://github.com/jlandersen/homedash/releases/latest/download/homedash-darwin-arm64
chmod +x homedash
./homedashOpen http://localhost:8080 in your browser.
services:
homedash:
image: ghcr.io/jlandersen/homedash:latest
user: "${PUID:-1000}:${PGID:-1000}"
ports:
- "8080:8080"
volumes:
- ./appdata:/appdata
environment:
- HOMEDASH_MANIFEST=/appdata/apps.yaml
restart: unless-stoppedThen run:
docker compose up -dIf you want to disable editing from the UI, add HOMEDASH_ALLOW_EDIT=false to the environment variables and mark the apps.yaml file as read-only:
services:
homedash:
image: ghcr.io/jlandersen/homedash:latest
ports:
- "8080:8080"
volumes:
- ./apps.yaml:/apps.yaml:ro
environment:
- HOMEDASH_MANIFEST=/apps.yaml
- HOMEDASH_ALLOW_EDIT=false
restart: unless-stoppeddocker pull ghcr.io/jlandersen/homedash:latest
docker run --user "$(id -u):$(id -g)" -p 8080:8080 \
-v $(pwd)/apps.yaml:/apps.yaml \
-e HOMEDASH_MANIFEST=/apps.yaml \
ghcr.io/jlandersen/homedash:latestThe image uses scratch (empty base) and is only ~10MB.
Note: When using Docker with a bind-mounted
apps.yaml, file change detection may not work reliably due to how Docker handles bind mounts. After editingapps.yaml, restart the container to apply changes:docker compose restart
| Variable | Default | Description |
|---|---|---|
HOMEDASH_PORT |
8080 |
Server port |
HOMEDASH_MANIFEST |
./apps.yaml |
Path to manifest file |
HOMEDASH_CHECK_INTERVAL |
30s |
Health check interval |
HOMEDASH_CHECK_TIMEOUT |
5s |
Timeout per health check |
HOMEDASH_TIME_24H |
false |
Use 24-hour time format |
HOMEDASH_SHOW_CPU |
true |
Show CPU usage stat |
HOMEDASH_SHOW_RAM |
true |
Show RAM usage stat |
HOMEDASH_SHOW_TEMP |
true |
Show temperature stat |
HOMEDASH_ALLOW_EDIT |
true |
Allow editing apps from the UI |
HOMEDASH_TLS_CERT |
- | Path to TLS certificate file |
HOMEDASH_TLS_KEY |
- | Path to TLS private key file |
HOMEDASH_TLS_REDIRECT |
- | Port for HTTP->HTTPS redirect |
Example:
HOMEDASH_PORT=3000 HOMEDASH_CHECK_INTERVAL=60s ./homedashTo enable HTTPS, provide both TLS certificate and key files:
HOMEDASH_TLS_CERT=/path/to/cert.pem HOMEDASH_TLS_KEY=/path/to/key.pem ./homedashTo automatically redirect HTTP traffic to HTTPS, set the redirect port:
# HTTPS on 443, HTTP redirect on 80
HOMEDASH_PORT=443 HOMEDASH_TLS_CERT=cert.pem HOMEDASH_TLS_KEY=key.pem HOMEDASH_TLS_REDIRECT=80 ./homedashYou can generate a self-signed certificate for testing:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodescategory_order:
- Smart Home
- Media
- Network
apps:
- name: Plex
url: http://192.168.1.100:32400
category: Media
icon: film
check_path: /web
- name: Pi-hole
url: http://192.168.1.1:80
category: Network
icon: shield
check_type: tcp
- name: Home Assistant
url: http://192.168.1.50:8123
category: Smart Home
icon: home
| Field | Required | Default | Description |
|---|---|---|---|
category_order |
No | - | Ordered list of category names; categories not listed are appended alphabetically |
apps |
Yes | - | List of apps shown on the dashboard |
| Field | Required | Default | Description |
|---|---|---|---|
name |
Yes | - | Display name |
url |
Yes | - | Full URL to the application |
category |
No | Uncategorized |
Group name for organizing |
icon |
No | box |
Icon name (see below) |
check_path |
No | / |
Path for HTTP health checks |
check_type |
No | http |
http or tcp |
skip_check |
No | false |
Skip health checks entirely |
| Icon | Description |
|---|---|
film |
Movie/video |
tv |
Television |
music |
Music note |
download |
Download arrow |
home |
House |
workflow |
Flow/nodes |
shield |
Shield |
network |
Network topology |
server |
Server rack |
database |
Database cylinder |
chart |
Line chart |
code |
Code brackets |
git |
Git icon |
terminal |
Terminal |
box |
Box (default) |
Sends an HTTP GET request to the app URL (with optional check_path).
Considers 2xx and 3xx status codes as healthy.
- name: Plex
url: http://192.168.1.100:32400
check_path: /web # Checks http://192.168.1.100:32400/webOpens a TCP connection to the host and port. Useful for non-HTTP services like databases, MQTT brokers, etc.
- name: PostgreSQL
url: http://192.168.1.100:5432
check_type: tcp # Just checks if port 5432 is open| Endpoint | Method | Description |
|---|---|---|
/ |
GET | Serves the dashboard UI |
/api/apps |
GET | Returns JSON array of apps with status |
/api/config |
GET | Returns UI configuration |
/api/stats |
GET | Returns system stats (CPU, RAM, Temp) |
/api/events |
GET | SSE stream for real-time updates |
[
{
"id": 1,
"name": "Plex",
"url": "http://192.168.1.100:32400",
"category": "Media",
"icon": "film",
"status": "UP",
"ping": "24ms"
}
]The /api/events endpoint streams three event types:
config- Sent once on connect with UI configurationapps- Sent when health check completes or manifest changesstats- Sent every 2 seconds with system statistics
homedash/
├── main.go # Entry point, embeds frontend
├── go.mod / go.sum # Go module files
├── apps.yaml # Your application manifest
├── example.apps.yaml # Example manifest with all options
├── internal/
│ ├── config/config.go # Environment configuration
│ ├── manifest/manifest.go # YAML parsing + file watcher
│ ├── health/checker.go # HTTP/TCP health checks
│ ├── stats/stats.go # System stats (CPU/RAM/Temp)
│ └── api/handlers.go # HTTP handlers + SSE
└── web/
├── index.html # Dashboard HTML
├── styles.css # Styling with dark/light themes
├── app.js # Frontend JavaScript
└── dist/ # Generated minified + gzipped assets
# Run in development
go generate ./...
go run .
# Build binary
./build.sh
# Build for different platforms
GOOS=linux GOARCH=amd64 ./build.sh -o homedash-linux-amd64
GOOS=linux GOARCH=arm64 ./build.sh -o homedash-linux-arm64| Shortcut | Action |
|---|---|
Cmd/Ctrl + K |
Open command palette |
Escape |
Close command palette |
↑ / ↓ |
Navigate results |
Enter |
Launch selected app |
Inspired by ddash - a Docker dashboard with Caddy integration.
HomeDash is a simplified alternative that:
- Doesn't require Docker or Caddy
- Uses a YAML manifest instead of Docker labels
- Has a vanilla JS frontend (no Node toolchain)
- Deploys as a single binary
MIT License - feel free to use, modify, and distribute.
