Skip to content
Go back

Heimdall vs Homepage vs Homer: Status Dashboards

By SumGuy 10 min read
Heimdall vs Homepage vs Homer: Status Dashboards

You Have 25 Bookmarks and a Spouse Who Just Wants Jellyfin

It starts innocently. One bookmark for Nextcloud, one for Sonarr, one for the router. Then you add Radarr. Then Prowlarr. Then a second instance of Sonarr for anime because apparently that’s a thing you do now.

Somewhere around bookmark 18, your spouse — who only ever wanted to watch a movie — sends you a message that says “where is the movie thing again.” You have failed.

The fix is a dashboard. A single URL that maps your entire homelab into something a human being can navigate without a PhD in bookmark archaeology. The three main contenders in self-hosted dashboard land are Heimdall, Homepage, and Homer. They all solve the same problem. They solve it very differently.

Here’s the breakdown so you can stop reading GitHub READMEs at midnight and just pick one.


The Three Contenders at a Glance

HeimdallHomepageHomer
BackendPHP (LinuxServer.io)Next.jsPure static HTML
Config methodWeb UI + DBYAML filesYAML file
Active dev paceSlower (as of 2026)Very activeMaintenance mode
Docker auto-discoveryNoYes (labels)No
Live API widgetsYes (built-in)Yes (extensive)No
Page load weightMediumMediumLightest
Best forGUI config, familiar feelPower users, YAML fansMinimal, fast, no fuss

Heimdall: The Comfortable Old Friend

Heimdall is the dashboard your homelab grew up on. It’s a PHP app maintained by LinuxServer.io, and it gives you a web UI where you add apps by clicking around — no config files, no YAML, no restarting containers every time you want to move a tile.

It supports “enhanced apps” — think of them as live widgets that talk to services like Sonarr, Nextcloud, and Plex to pull in real data. Queue counts, storage used, currently playing. That stuff.

The downside in 2026: development has slowed noticeably. It still works. It still gets security patches. But if you’re hoping for a shiny new widget for the service you added last month, you might wait a while.

Running Heimdall

compose.yaml
services:
heimdall:
image: lscr.io/linuxserver/heimdall:latest
container_name: heimdall
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- ./heimdall/config:/config
ports:
- 7080:80
- 7443:443
restart: unless-stopped
Terminal window
docker compose up -d
# Open http://localhost:7080
# Click the + button. Add your services. Done.

That’s genuinely it. No config files. Your 60-year-old neighbor could set this up. The app data lives in a SQLite database inside /config, so back that up or you’ll be re-adding everything after the next disk failure.

Enhanced Apps (The Widget Layer)

In the Heimdall UI, when you add a supported app like Sonarr, you’ll see a toggle for “Enhanced” mode. Flip it, drop in your API key, and the tile shows live data — upcoming episodes, queue size, whatever that app exposes.

Supported enhanced apps include Sonarr, Radarr, Lidarr, Readarr, Plex, Nextcloud, Pi-hole, and a handful of others. The list hasn’t grown much lately, which is the honest limitation.


Homer: The Dashboard That Gets Out of Your Way

Homer is a static HTML single-page app. There’s no backend. There’s no database. There are no widgets that call your services. You give it a YAML file, it renders tiles, and that’s the whole product.

This sounds like a limitation. For a lot of homelab setups, it’s a feature.

Homer loads instantly on any device. It works fine behind the slowest reverse proxy. It runs on hardware you’d otherwise throw away. If your dashboard ever has a “wait, why is this slow?” moment — Homer won’t have that moment.

It’s also in maintenance mode upstream, which means it’s stable and won’t change much. For a static bookmark page, that’s perfectly acceptable.

Running Homer

compose.yaml
services:
homer:
image: b4bz/homer:latest
container_name: homer
volumes:
- ./homer/assets:/www/assets
ports:
- 8080:8080
restart: unless-stopped
user: "1000:1000"

Your entire config is one file: assets/config.yml.

assets/config.yml
---
title: "Home Lab"
subtitle: "The Art of Wasting Time"
logo: "logo.png"
header: true
footer: false
theme: default
colors:
light:
highlight-primary: "#3367d6"
highlight-secondary: "#4f52ff"
highlight-hover: "#5a5fff"
background: "#f5f5f5"
card-background: "#ffffff"
text: "#363636"
dark:
highlight-primary: "#3367d6"
highlight-secondary: "#4f52ff"
highlight-hover: "#5a5fff"
background: "#131313"
card-background: "#2b2b2b"
text: "#eaeaea"
services:
- name: "Media"
icon: "fas fa-film"
items:
- name: "Jellyfin"
logo: "assets/tools/jellyfin.png"
subtitle: "The movie thing"
url: "https://jellyfin.yourdomain.com"
target: "_blank"
- name: "Plex"
logo: "assets/tools/plex.png"
subtitle: "For the other half of the library"
url: "https://plex.yourdomain.com"
target: "_blank"
- name: "Downloads"
icon: "fas fa-download"
items:
- name: "Sonarr"
logo: "assets/tools/sonarr.png"
subtitle: "TV automation"
url: "https://sonarr.yourdomain.com"
target: "_blank"
- name: "Radarr"
logo: "assets/tools/radarr.png"
subtitle: "Movie automation"
url: "https://radarr.yourdomain.com"
target: "_blank"
- name: "Prowlarr"
logo: "assets/tools/prowlarr.png"
subtitle: "Indexers"
url: "https://prowlarr.yourdomain.com"
target: "_blank"

Edit the file, refresh the browser. No container restart required. Homer watches for config changes and hot-reloads.

The lack of live widgets isn’t a problem if you just want bookmarks with icons. It absolutely is a problem if you want to see your Sonarr queue size without clicking through to Sonarr.


Homepage: The Current Champion

Homepage is what happens when someone looks at Homer and Heimdall and says “what if it did more, and the config was still just YAML.” It’s a Next.js app, actively developed, and it has widgets for basically everything you run in a homelab.

The killer feature is Docker label auto-discovery. Homepage can watch your Docker socket and automatically add services to the dashboard based on labels on your containers. You deploy a new service, stick some labels on it, and it appears in Homepage. No editing config files. No clicking around a UI. It just shows up.

Running Homepage

compose.yaml
services:
homepage:
image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
ports:
- 3000:3000
volumes:
- ./homepage/config:/app/config
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
PUID: 1000
PGID: 1000
restart: unless-stopped

The Docker socket mount is what enables auto-discovery. Read-only is fine — Homepage doesn’t need to control containers, just see them.

Config lives in ./homepage/config/ as a set of YAML files: services.yaml, widgets.yaml, settings.yaml, bookmarks.yaml, docker.yaml.

services.yaml — Your Service Grid

config/services.yaml
- Media:
- Jellyfin:
icon: jellyfin.png
href: https://jellyfin.yourdomain.com
description: Media server
widget:
type: jellyfin
url: http://jellyfin:8096
key: YOUR_JELLYFIN_API_KEY
enableBlocks: true
enableNowPlaying: true
- Plex:
icon: plex.png
href: https://plex.yourdomain.com
description: The other media server
widget:
type: plex
url: http://plex:32400
key: YOUR_PLEX_TOKEN
- Downloads:
- Sonarr:
icon: sonarr.png
href: https://sonarr.yourdomain.com
description: TV automation
widget:
type: sonarr
url: http://sonarr:8989
key: YOUR_SONARR_API_KEY
enableQueue: true
- Radarr:
icon: radarr.png
href: https://radarr.yourdomain.com
description: Movie automation
widget:
type: radarr
url: http://radarr:7878
key: YOUR_RADARR_API_KEY
enableQueue: true
- Prowlarr:
icon: prowlarr.png
href: https://prowlarr.yourdomain.com
description: Indexer aggregator
widget:
type: prowlarr
url: http://prowlarr:9696
key: YOUR_PROWLARR_API_KEY

Those widgets pull real data. Sonarr shows missing episodes and queue size. Radarr shows monitored movies and what’s downloading. Jellyfin shows active streams. This is the part that makes Homepage feel like a proper ops dashboard rather than a fancy bookmark page.

Docker Auto-Discovery with Labels

This is where Homepage earns its reputation. Drop these labels on any container:

compose.yaml (your other services)
services:
sonarr:
image: lscr.io/linuxserver/sonarr:latest
labels:
- homepage.group=Downloads
- homepage.name=Sonarr
- homepage.icon=sonarr.png
- homepage.href=https://sonarr.yourdomain.com
- homepage.description=TV automation
- homepage.widget.type=sonarr
- homepage.widget.url=http://sonarr:8989
- homepage.widget.key=YOUR_SONARR_API_KEY

Homepage picks this up automatically — no services.yaml entry needed. Deploy a new service, add the labels, it’s on the dashboard. Delete the container, it disappears. This is the feature that makes maintaining a large homelab actually tolerable.

widgets.yaml — System Info and More

config/widgets.yaml
- resources:
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
- datetime:
text_size: xl
format:
dateStyle: long
timeStyle: short
hourCycle: h23

docker.yaml — Point at Your Docker Socket

config/docker.yaml
my-docker:
socket: /var/run/docker.sock

If you run multiple Docker hosts, you can point Homepage at remote Docker sockets or Portainer instances too.


The X-Frame-Options Gotcha

All three of these dashboards link out to your services. None of them embed your services as iframes by default — and if you try, you’ll hit a wall.

Most self-hosted apps set X-Frame-Options: SAMEORIGIN or X-Frame-Options: DENY, which tells browsers “do not render me inside an iframe from a different origin.” Your dashboard is a different origin. Your iframe will be a blank box.

The fix, if you actually want iframe embedding, is to override the header at your reverse proxy layer. With Caddy:

respond /embed/* {
header X-Frame-Options ""
header Content-Security-Policy "frame-ancestors 'self' https://dashboard.yourdomain.com"
}

With Nginx:

location / {
proxy_pass http://sonarr:8989;
proxy_hide_header X-Frame-Options;
add_header X-Frame-Options "ALLOWALL";
}

Honestly though — don’t do this. Iframes in dashboards are a 2015 idea. The widgets in Homepage and Heimdall show you the data you actually care about. You don’t need to see the full Sonarr UI embedded in a tiny box to know your queue has 3 items.


Theme and Branding Tips

Homer: Drop a custom CSS file at assets/custom.css. Homer loads it automatically if it exists. Full control, no config option needed.

Heimdall: Settings > Custom CSS in the web UI. Or mount a custom CSS file into /config/www/. The tile colors are per-app in the UI.

Homepage: settings.yaml handles theme, color scheme, and layout. You can set color: slate or any Tailwind color name, choose light or dark base, and control column counts per breakpoint:

config/settings.yaml
title: Home Lab
theme: dark
color: slate
headerStyle: clean
layout:
Media:
style: row
columns: 4
Downloads:
style: row
columns: 3

Homepage also supports custom CSS via a custom.css file in the config directory. The default dark theme is legitimately good out of the box, which is more than you can say for most self-hosted tools.


The Bottom Line

Pick Homer if: You want bookmarks with icons and you never want to think about the dashboard again. It loads fast, it’s dead simple, and it does exactly what it says. If your household just needs links and you don’t care about seeing live queue counts, Homer is fine. It’s been fine for years.

Pick Heimdall if: You hate editing YAML and want to manage everything through a UI. It’s the most accessible option for anyone who isn’t comfortable with config files, and the enhanced app widgets cover the popular services well. Understand that development has slowed and the widget library won’t grow much — but what’s there works.

Pick Homepage if: You have more than 10 services, you want live data from those services, and you’re willing to write some YAML to get it. The Docker label auto-discovery alone is worth the setup cost once your homelab grows past a certain size. When you can deploy a new container and have it appear on the dashboard automatically, that’s when you realize manual bookmark management was genuinely a waste of your time.

The honest answer for most homelabs in 2026: Homepage. The widget ecosystem is mature, auto-discovery is genuinely useful, and the development pace means you’re not going to hit a wall because your preferred service isn’t supported. Your spouse will be able to find Jellyfin. That’s the whole point.


Share this post on:

Send a Webmention

Written about this post on your own site? Send a webmention and it'll show up above once verified.


Previous Post
Docker Bake vs Compose Build
Next Post
WASM Containers in 2026

Discussion

Powered by Garrul . Sign in with GitHub or Google, or post anonymously.

Related Posts