Homer Dashboard Installation and Configuration
Homer is a dead-simple static server dashboard that displays all your self-hosted services in a clean, organized homepage configured entirely through a single YAML file. With no database, no backend, and minimal resource usage, Homer is ideal for VPS environments where you want a visual overview of your services without adding operational overhead.
Prerequisites
- Docker and Docker Compose installed (or any web server for static files)
- Root or sudo access
- Basic YAML syntax knowledge
- Services already running that you want to link
Installing Homer with Docker
# Create Homer directory
sudo mkdir -p /opt/homer/assets/icons
# Create docker-compose.yml
sudo tee /opt/homer/docker-compose.yml <<'EOF'
version: '3.8'
services:
homer:
image: b4bz/homer:latest
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- /opt/homer/assets:/www/assets
environment:
- INIT_ASSETS=1 # Copy example assets on first run
user: "1000:1000"
EOF
# Start Homer
cd /opt/homer
sudo docker compose up -d
# Monitor startup
sudo docker compose logs homer
Access Homer at http://your-server:8080
On first run with INIT_ASSETS=1, Homer copies example assets including a sample config.yml to the assets directory.
Alternative: run without Docker using Nginx:
# Download Homer
curl -LO https://github.com/bastienwirtz/homer/releases/latest/download/homer.zip
sudo unzip homer.zip -d /var/www/homer/
# Configure Nginx to serve the static files
sudo tee /etc/nginx/sites-available/homer <<'EOF'
server {
listen 8080;
root /var/www/homer;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
EOF
sudo ln -s /etc/nginx/sites-available/homer /etc/nginx/sites-enabled/
sudo systemctl reload nginx
YAML Configuration Basics
The entire Homer configuration lives in /opt/homer/assets/config.yml:
# Edit the configuration file
sudo nano /opt/homer/assets/config.yml
Minimal config.yml:
# config.yml
title: "My Server Dashboard"
subtitle: "VPS Services"
logo: "assets/logo.png"
header: true
footer: '<p>My VPS - <a href="https://my-provider.com">Provider</a></p>'
# Optional: theme (default, dark)
theme: default
# Optional: color palette override
colors:
light:
highlight-primary: "#3367d6"
highlight-secondary: "#4285f4"
highlight-hover: "#5a95f5"
background: "#f5f5f5"
card-background: "#ffffff"
text: "#363636"
text-header: "#ffffff"
text-title: "#303030"
text-subtitle: "#424242"
card-shadow: rgba(0, 0, 0, 0.1)
link: "#3273dc"
link-hover: "#363636"
dark:
highlight-primary: "#3367d6"
highlight-secondary: "#4285f4"
highlight-hover: "#5a95f5"
background: "#131313"
card-background: "#2b2b2b"
text: "#eaeaea"
text-header: "#ffffff"
text-title: "#fafafa"
text-subtitle: "#f5f5f5"
card-shadow: rgba(0, 0, 0, 0.4)
link: "#3273dc"
link-hover: "#ffdd57"
Service Grouping
Organize services into logical groups:
# config.yml - services section
services:
- name: "Monitoring"
icon: "fas fa-heartbeat"
items:
- name: "Grafana"
logo: "assets/icons/grafana.png"
subtitle: "Metrics and dashboards"
tag: "monitoring"
url: "https://grafana.example.com"
target: "_blank"
- name: "Prometheus"
logo: "assets/icons/prometheus.png"
subtitle: "Metrics collection"
tag: "monitoring"
url: "https://prometheus.example.com"
- name: "Media"
icon: "fas fa-film"
items:
- name: "Jellyfin"
logo: "assets/icons/jellyfin.png"
subtitle: "Media streaming"
tag: "media"
keywords: "video music"
url: "https://jellyfin.example.com"
- name: "Navidrome"
logo: "assets/icons/navidrome.png"
subtitle: "Music server"
tag: "media"
url: "https://music.example.com"
- name: "Storage & Files"
icon: "fas fa-hdd"
items:
- name: "Nextcloud"
logo: "assets/icons/nextcloud.png"
subtitle: "File sync and share"
tag: "storage"
url: "https://cloud.example.com"
- name: "Seafile"
logo: "assets/icons/seafile.png"
subtitle: "Fast file sync"
tag: "storage"
url: "https://seafile.example.com"
- name: "DevOps"
icon: "fas fa-code"
items:
- name: "Gitea"
logo: "assets/icons/gitea.png"
subtitle: "Git hosting"
tag: "dev"
url: "https://git.example.com"
- name: "Portainer"
logo: "assets/icons/portainer.png"
subtitle: "Docker management"
tag: "infra"
url: "https://portainer.example.com"
Custom Icons
Use Font Awesome icons (included):
# Use any Font Awesome 5 Free icon
items:
- name: "My Service"
icon: "fas fa-server" # solid icons
- name: "Another Service"
icon: "far fa-file" # regular icons
- name: "Github"
icon: "fab fa-github" # brand icons
Use custom PNG/SVG icons:
# Place icons in the icons directory
sudo cp myservice.png /opt/homer/assets/icons/
# Reference in config.yml
# logo: "assets/icons/myservice.png"
Download a curated icon pack:
# Download Dashboard Icons (popular icon collection for home labs)
cd /opt/homer/assets/icons
# Download specific icons
curl -LO https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/grafana.png
curl -LO https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/jellyfin.png
curl -LO https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/portainer.png
curl -LO https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/nextcloud.png
Health Checks
Homer supports API-based health checks for services that implement a status endpoint:
# Enable status check for a service
items:
- name: "Grafana"
url: "https://grafana.example.com"
type: "Ping" # Simple HTTP check
- name: "Gitea"
url: "https://git.example.com"
type: "Gitea" # Built-in Gitea integration
- name: "Jellyfin"
url: "https://jellyfin.example.com"
type: "Emby" # Jellyfin uses Emby-compatible API
apikey: "your-jellyfin-api-key"
- name: "Sonarr"
url: "https://sonarr.example.com"
type: "Sonarr"
apikey: "your-sonarr-api-key"
Custom status check with Ping type:
# Ping type checks if the URL returns a 2xx status
# The status dot shows green (online) or red (offline)
- name: "My API"
url: "https://api.example.com/health"
type: "Ping"
Theme Customization
Apply a dark theme:
# In config.yml
theme: default # or: default, dark
# Optional: user can toggle in the UI, or force with:
# defaults:
# colorTheme: dark
Custom CSS in assets:
# Create a custom.css file
sudo tee /opt/homer/assets/custom.css <<'EOF'
/* Change font */
body {
font-family: "Inter", sans-serif;
}
/* Make cards slightly larger */
.card {
min-height: 70px;
}
/* Custom card hover effect */
.card:hover {
transform: translateY(-2px);
transition: transform 0.2s ease;
}
EOF
# Reference in config.yml
stylesheet:
- "assets/custom.css"
Reverse Proxy with Nginx
# /etc/nginx/sites-available/homer
server {
listen 80;
server_name home.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name home.example.com;
ssl_certificate /etc/letsencrypt/live/home.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/home.example.com/privkey.pem;
# Optional: restrict to specific IPs
# allow 1.2.3.4;
# deny all;
# Optional: basic auth
# auth_basic "Dashboard";
# auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
sudo ln -s /etc/nginx/sites-available/homer /etc/nginx/sites-enabled/
sudo certbot --nginx -d home.example.com
sudo systemctl reload nginx
Troubleshooting
Dashboard not loading after config change:
# Homer hot-reloads config automatically in the browser
# If the page breaks, check YAML syntax
# YAML linter:
python3 -c "import yaml; yaml.safe_load(open('/opt/homer/assets/config.yml'))"
# View Homer container logs for errors
sudo docker compose logs homer
# Check file permissions
ls -la /opt/homer/assets/config.yml
sudo chown 1000:1000 /opt/homer/assets/config.yml
Icons not showing:
# Verify files exist and are readable
ls -la /opt/homer/assets/icons/
# Check the path in config.yml matches exactly
# logo: "assets/icons/filename.png" (not absolute path)
# Test direct access to the icon
curl -I http://your-server:8080/assets/icons/grafana.png
Health checks not working:
# Ensure the service URL is accessible from the Homer container
sudo docker compose exec homer wget -q -O - http://grafana:3000/api/health
# For external services, ensure the Homer container has internet access
sudo docker compose exec homer wget -q -O - https://grafana.example.com
Conclusion
Homer provides the simplest possible server dashboard — a single YAML file that renders a fast, searchable service directory without databases, authentication overhead, or complex configuration. By combining Font Awesome icons, custom PNG logos, and API-based health checks, you get an informative at-a-glance view of your entire self-hosted infrastructure that loads instantly and requires virtually no maintenance.


