Building a Homelab Dashboard with Homepage and Homarr
Once your homelab grows past a handful of services, you need a single place to see and access everything. Typing IP addresses and port numbers from memory is not sustainable when you are running Jellyfin on port 8096, Grafana on 3000, Proxmox on 8006, Pi-hole on 80, and a dozen other services scattered across multiple hosts. A homelab dashboard gives you a clean start page with organized links, live status indicators, and at-a-glance metrics for your entire infrastructure.
Photo by unavailable parts on Unsplash

Two dashboards stand above the rest for homelabs in 2026: Homepage (gethomepage.dev) and Homarr. Both are actively maintained, Docker-friendly, and purpose-built for self-hosters. This guide walks you through setting up each one, configuring service tiles, pulling in live data from your services, and customizing the layout to match your workflow.
Homepage vs Homarr: Which to Choose
Before diving into setup, here is a quick comparison to help you pick:
| Feature | Homepage | Homarr |
|---|---|---|
| Configuration | YAML files | GUI drag-and-drop |
| Service integrations | 80+ (deep API integrations) | 50+ (growing) |
| Resource usage | Very low (~50 MB RAM) | Medium (~200 MB RAM) |
| Customization | YAML-driven, theme support | GUI editor, drag-and-drop |
| Health checks | Yes (HTTP, TCP, ping) | Yes |
| Search bar | Yes, with search providers | Yes |
| Authentication | None built-in (use reverse proxy) | Built-in user auth |
| Docker integration | Auto-discovers via labels | Auto-discovers via socket |
| Learning curve | Medium (YAML editing) | Low (everything in the UI) |
Choose Homepage if you prefer configuration-as-code, want the deepest service integrations (it can pull data from Radarr, Sonarr, Proxmox, Pi-hole, and dozens more), and care about minimal resource usage.
Choose Homarr if you want to configure everything through a visual editor, prefer drag-and-drop over editing YAML files, and want built-in authentication without setting up a reverse proxy.
Setting Up Homepage
Docker Compose Installation
Create a directory for Homepage and set up the Docker Compose file:
mkdir -p ~/docker/homepage
cd ~/docker/homepage
# docker-compose.yml
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
ports:
- "3000:3000"
volumes:
- ./config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- PUID=1000
- PGID=1000
restart: unless-stopped
docker compose up -d
Homepage is now accessible at http://your-server:3000. But it is empty -- you need to configure services and widgets.
Configuring Services
Homepage reads its configuration from YAML files in the config directory. The main files are:
services.yaml-- Your service tiles (links and integrations)widgets.yaml-- Top-bar widgets (system info, search, etc.)settings.yaml-- Global settings (theme, layout, title)bookmarks.yaml-- Quick links that are not full service tiles
Create your services file:
# config/services.yaml
---
- Infrastructure:
- Proxmox:
icon: proxmox
href: https://proxmox.local:8006
description: Hypervisor
widget:
type: proxmox
url: https://proxmox.local:8006
username: api@pam!homepage
password: your-api-token-here
node: pve
- OPNsense:
icon: opnsense
href: https://opnsense.local
description: Firewall & Router
widget:
type: opnsense
url: https://opnsense.local
username: your-api-key
password: your-api-secret
- Pi-hole:
icon: pi-hole
href: http://pihole.local/admin
description: DNS Ad Blocker
widget:
type: pihole
url: http://pihole.local
key: your-pihole-api-key
- Media:
- Jellyfin:
icon: jellyfin
href: http://jellyfin.local:8096
description: Media Server
widget:
type: jellyfin
url: http://jellyfin.local:8096
key: your-jellyfin-api-key
enableBlocks: true
- Radarr:
icon: radarr
href: http://radarr.local:7878
description: Movie Management
widget:
type: radarr
url: http://radarr.local:7878
key: your-radarr-api-key
- Sonarr:
icon: sonarr
href: http://sonarr.local:8989
description: TV Management
widget:
type: sonarr
url: http://sonarr.local:8989
key: your-sonarr-api-key
- Monitoring:
- Grafana:
icon: grafana
href: http://grafana.local:3000
description: Dashboards & Metrics
- Uptime Kuma:
icon: uptime-kuma
href: http://uptime.local:3001
description: Uptime Monitoring
widget:
type: uptimekuma
url: http://uptime.local:3001
slug: homelab
- Storage:
- TrueNAS:
icon: truenas
href: http://truenas.local
description: Network Storage
widget:
type: truenas
url: http://truenas.local
key: your-truenas-api-key
- Nextcloud:
icon: nextcloud
href: https://cloud.yourdomain.com
description: File Sync & Share
Each service entry has an icon (Homepage includes hundreds of built-in icons for popular self-hosted apps), a link, an optional description, and an optional widget that pulls live data from the service's API.
Adding Top-Bar Widgets
Widgets appear at the top of the dashboard and show system-level information:
# config/widgets.yaml
---
- search:
provider: duckduckgo
target: _blank
- resources:
cpu: true
memory: true
disk: /
- openmeteo:
label: Weather
latitude: 47.25
longitude: -122.44
timezone: America/Los_Angeles
units: imperial
- datetime:
text_size: xl
format:
dateStyle: long
timeStyle: short
hourCycle: h12
The resources widget shows CPU, RAM, and disk usage of the machine running Homepage. The openmeteo widget pulls weather data without needing an API key.
Global Settings and Theming
# config/settings.yaml
---
title: My Homelab
background:
image: https://images.unsplash.com/photo-server-room.jpg
blur: sm
opacity: 50
theme: dark
color: slate
layout:
Infrastructure:
style: row
columns: 3
Media:
style: row
columns: 3
Monitoring:
style: row
columns: 2
Storage:
style: row
columns: 2
headerStyle: clean
Docker Auto-Discovery
Homepage can automatically discover services from Docker containers using labels. Add labels to your existing Docker Compose services:
# Example: adding Homepage labels to a Jellyfin container
services:
jellyfin:
image: jellyfin/jellyfin:latest
labels:
- homepage.group=Media
- homepage.name=Jellyfin
- homepage.icon=jellyfin
- homepage.href=http://jellyfin.local:8096
- homepage.description=Media Server
- homepage.widget.type=jellyfin
- homepage.widget.url=http://jellyfin.local:8096
- homepage.widget.key=your-api-key
With Docker socket access (configured in the compose file), Homepage picks up these labels automatically. Services appear on the dashboard without editing services.yaml.
Setting Up Homarr
Docker Compose Installation
mkdir -p ~/docker/homarr
cd ~/docker/homarr
# docker-compose.yml
services:
homarr:
image: ghcr.io/homarr-labs/homarr:latest
container_name: homarr
ports:
- "7575:7575"
volumes:
- ./data:/appdata
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- SECRET_ENCRYPTION_KEY=your-random-32-char-string-here
restart: unless-stopped
# Generate a random encryption key
openssl rand -hex 16
docker compose up -d
Access Homarr at http://your-server:7575. You will be prompted to create an admin account on first launch.
Adding Services Through the GUI
Homarr's main advantage is its visual editor. After logging in:
- Click the "+" button to add a new app tile
- Fill in the app name, URL, and select an icon from the built-in library
- Optionally configure an integration (similar to Homepage widgets)
- Drag and drop the tile to position it on your dashboard
- Resize tiles by dragging their corners
You can organize tiles into sections, create multiple pages/tabs, and arrange everything visually without touching a config file.
Configuring Integrations
Homarr supports integrations that pull live data from your services. To add one:
- Go to Settings > Integrations
- Click "Add Integration"
- Select the service type (e.g., Radarr, Sonarr, Proxmox)
- Enter the URL and API key
- Assign the integration to a specific app tile
Supported integrations include Radarr, Sonarr, Lidarr, Overseerr, Jellyfin, Plex, Pi-hole, AdGuard Home, Proxmox, and many others. Each integration shows relevant data directly on the tile -- like the number of movies in Radarr, active streams in Jellyfin, or blocked queries in Pi-hole.
Docker Integration
Homarr can auto-discover Docker containers and show their status. Since you mounted the Docker socket in the compose file, Homarr already has access. In the dashboard editor, containers running on the same host appear with their status (running, stopped, etc.). You can start, stop, and restart containers directly from the dashboard.
Like what you're reading? Subscribe to HomeLab Starter — free weekly guides in your inbox.
Securing Your Dashboard
Your dashboard contains links (and potentially API keys) for every service in your lab. Do not expose it to the internet without authentication.
Option 1: Reverse Proxy with Authentication
Put your dashboard behind a reverse proxy (Caddy, Traefik, or Nginx Proxy Manager) with authentication:
# Caddyfile example with basic auth
dashboard.yourdomain.com {
basicauth {
admin $2a$14$hashed_password_here
}
reverse_proxy homepage:3000
}
Option 2: Cloudflare Tunnel with Access
If you use Cloudflare Tunnel for remote access, add a Cloudflare Access policy:
# In your Cloudflare Zero Trust dashboard:
# Applications > Add Application > Self-hosted
# Application domain: dashboard.yourdomain.com
# Policy: Allow - Emails ending in @yourdomain.com
Option 3: VPN-Only Access
The simplest secure approach: only access your dashboard from within your network or via VPN (WireGuard, Tailscale). No authentication needed because the network itself is the access control.
Advanced: Custom CSS and Widgets
Homepage Custom CSS
Homepage supports custom CSS for deeper styling. Create a custom.css file in the config directory:
/* config/custom.css */
/* Make service tiles slightly larger */
.service {
min-height: 80px;
}
/* Custom color for a specific group */
.group-Infrastructure {
border-left: 3px solid #3b82f6;
}
/* Hide the description on small screens */
@media (max-width: 768px) {
.service-description {
display: none;
}
}
Homepage Custom API Widget
If you have a service that Homepage does not natively support, use the customapi widget:
- My Custom Service:
icon: mdi-server
href: http://myservice.local:9090
widget:
type: customapi
url: http://myservice.local:9090/api/stats
mappings:
- field: active_users
label: Users
- field: requests_today
label: Requests
- field: uptime_hours
label: Uptime (hrs)
This fetches JSON from any API endpoint and displays specified fields on the tile.
Homarr Custom Widgets
Homarr supports several built-in widget types beyond app tiles:
- Calendar widget: Shows upcoming events from Sonarr, Radarr, Lidarr, and Readarr
- Weather widget: Current conditions and forecast
- Iframe widget: Embed any web page (useful for Grafana panels)
- Notebook widget: Markdown notes directly on your dashboard
- RSS widget: Show feed items from any RSS source
- Video stream widget: Embed camera feeds
Add these from the widget picker in the dashboard editor.
Tips for an Effective Dashboard
Organize by Function, Not by Host
Group services by what they do (Media, Infrastructure, Monitoring, Development) rather than by which server they run on. You care about accessing Grafana, not remembering which host it is on.
Use Status Indicators
Both Homepage and Homarr support health checks. Enable them for critical services so you can see at a glance if something is down:
# Homepage: status check is automatic if you define a widget
# For services without widgets, add a ping check:
- Gitea:
icon: gitea
href: http://gitea.local:3000
ping: http://gitea.local:3000
Set It as Your Browser Homepage
The dashboard is most useful when it is the first thing you see. Set it as the default new tab page in your browser:
- Firefox: Settings > Home > Custom URLs >
http://dashboard.local:3000 - Chrome: Settings > On startup > Open a specific page
Keep It Updated
When you add a new service to your lab, add it to the dashboard immediately. A dashboard that is missing half your services is worse than no dashboard at all because it gives you a false sense of completeness.
Bookmark Important Non-Self-Hosted Links
Both dashboards support a bookmarks section for external links. Add links to your domain registrar, cloud backup dashboard, hardware documentation, and any other resources you regularly access when managing your lab:
# Homepage bookmarks.yaml
---
- Management:
- Cloudflare:
- icon: cloudflare
href: https://dash.cloudflare.com
- GitHub:
- icon: github
href: https://github.com/your-username
- Documentation:
- Proxmox Docs:
- icon: proxmox
href: https://pve.proxmox.com/wiki
- Docker Hub:
- icon: docker
href: https://hub.docker.com
Migrating Between Dashboards
If you start with one dashboard and want to switch, there is no automatic migration tool. However, both use fairly simple configuration formats:
- Homepage to Homarr: Re-create your service tiles in Homarr's GUI. Your API keys and URLs can be copied directly.
- Homarr to Homepage: Export your Homarr config from the settings page, then create equivalent entries in Homepage's
services.yaml.
The effort is proportional to the number of services you have. For a lab with 15-20 services, expect to spend 30-45 minutes recreating the configuration.
Wrapping Up
A dashboard transforms your homelab from a collection of IP addresses and port numbers into something that actually feels like a cohesive system. Homepage and Homarr both deliver on this, just with different philosophies -- code-driven vs. GUI-driven.
Start with whichever approach matches how you like to work. If you enjoy editing YAML and want maximum integration depth, go with Homepage. If you want to drag tiles around and have everything working in 20 minutes, go with Homarr. Either way, once you have a dashboard, you will never go back to maintaining a bookmark folder.
