Homepage: The Dashboard for All Your Self-Hosted Services
A tidy start dashboard for your server: Homepage links every service, shows system load and the live Docker container status – behind Traefik.
Table of contents
The more services you self-host, the more bookmarks and IP addresses you have to remember. A dashboard solves that: a single start page that links all your services, shows system load and even tells you which containers are running right now. Homepage is the nicest and fastest tool for it.
What are we building?
A central dashboard with Homepage (v1.13.2) behind Traefik, configured entirely through simple YAML files. By the end you’ll have a tidy start page with tiles for all services, widgets for CPU/RAM/disk, a search box – and the killer feature: Homepage reads the Docker socket and shows live whether a container is running. All statically generated, no database, with a tiny footprint.
Prerequisites
- A server with Traefik running and Docker Compose
- A subdomain pointing at the server –
YOUR_DOMAINbelow (e.g.start.yourdomain.com) - A few already-running services to link (more fun, but not required)
VPS 1000 G12
4 vCores · 8 GB RAM · 256 GB NVMe
from €10.36/month
Homepage is extremely frugal – runs happily alongside your other stack.
💶 5 € voucher for new netcup customers:36nc17844976032
(new customers only, no domains)
Step by step
Step 1: Create the project and config folder
Homepage is driven entirely by YAML files in a config folder. Create the structure:
mkdir -p /opt/homepage/config /opt/homepage/icons && cd /opt/homepageStep 2: Base settings
config/settings.yaml controls appearance and layout. We define two groups as a row layout with three columns each:
title: My Serverküche
theme: dark
color: slate
headerStyle: boxed
layout:
Infrastructure:
style: row
columns: 3
Media:
style: row
columns: 3The names under layout: (Infrastructure, Media) must later match the group names in the services file exactly – only then does the layout apply.
Step 3: Link your services
config/services.yaml is the heart – your tiles. Each service gets a name, a URL, a description and an icon (Homepage automatically pulls matching icons from a large catalog when you specify name.png):
- Infrastructure:
- Nextcloud:
href: https://cloud.YOUR_DOMAIN
description: Your own cloud
icon: nextcloud.png
- Vaultwarden:
href: https://vault.YOUR_DOMAIN
description: Password manager
icon: vaultwarden.png
- Media:
- Immich:
href: https://photos.YOUR_DOMAIN
description: Photos
icon: immich.png
- Jellyfin:
href: https://media.YOUR_DOMAIN
description: Media server
icon: jellyfin.pngThis is how you link your already-installed services like Nextcloud, Immich, Jellyfin or Vaultwarden in one central place.
Step 4: Widgets for system load and search
config/widgets.yaml controls the info bar at the top. Resource display, a search box and date/time:
- resources:
cpu: true
memory: true
disk: /
- search:
provider: duckduckgo
target: _blank
- datetime:
text_size: xl
format:
dateStyle: full
timeStyle: shortThe resources widget shows the host’s utilization. Homepage reads CPU and RAM straight from within the container (no Docker socket needed); we only wire up the socket in the next step for the container status.
Step 5: Connect Traefik – and the crucial host protection
Now the compose.yaml. Replace YOUR_DOMAIN with your real subdomain:
services:
homepage:
image: ghcr.io/gethomepage/homepage:v1.13.2
restart: unless-stopped
environment:
HOMEPAGE_ALLOWED_HOSTS: YOUR_DOMAIN
volumes:
- ./config:/app/config
- ./icons:/app/public/icons
networks: [proxy]
labels:
- "traefik.enable=true"
- "traefik.http.routers.homepage.rule=Host(`YOUR_DOMAIN`)"
- "traefik.http.routers.homepage.entrypoints=websecure"
- "traefik.http.routers.homepage.tls.certresolver=le"
- "traefik.http.services.homepage.loadbalancer.server.port=3000"
networks:
proxy:
external: trueHOMEPAGE_ALLOWED_HOSTS is mandatory
HOMEPAGE_ALLOWED_HOSTS set to your domain you’ll only see an error page (“Host validation failed”). Enter your domain there exactly – multiple ones separated by commas.Start the dashboard:
docker compose up -dVerify from outside that it responds with valid HTTPS:
curl -sI https://YOUR_DOMAIN/ | head -1HTTP/2 200In the browser you now see your dashboard with tiles and the info bar:

Step 6: Live container status via the Docker socket
The strongest feature: Homepage can read directly from Docker whether a container is running, and show CPU/RAM per container. For that create config/docker.yaml:
my-docker:
socket: /var/run/docker.sockThen mount the socket read-only into the container – add under volumes: in compose.yaml:
- /var/run/docker.sock:/var/run/docker.sock:roAnd link a tile to its container (server refers to the name from docker.yaml, container to the real container name):
- Infrastructure:
- Traefik:
description: Reverse proxy
icon: traefik.png
server: my-docker
container: traefik-traefik-1After docker compose up -d the tile shows a green status badge as soon as the container is running:

The Docker socket is powerful – mount it read-only
/var/run/docker.sock is effectively root access to the host (see Users & permissions). Always mount it with :ro (read only) and don’t expose Homepage unprotected on the internet. For real protection a dashboard like this belongs behind authentication – e.g. a Traefik BasicAuth middleware or, later, single sign-on.Step 7: Add bookmarks (optional)
Besides services, Homepage can show plain bookmarks – via config/bookmarks.yaml:
- Development:
- Serverküche:
- abbr: SK
href: https://serverkueche.deNow you have services, system load, search and bookmarks in one place. Homepage picks up changes to the YAML files automatically – a browser reload is usually enough, no restart needed.
When things go wrong
“Host validation failed” instead of the dashboard. The most common trap: HOMEPAGE_ALLOWED_HOSTS is missing or has the wrong domain. Enter exactly the domain you access it under, then docker compose up -d.
The resource widgets show no or wrong values. Homepage reads CPU and RAM from within the container (no socket needed). If disk: / shows the container filesystem instead of the host disk, mount the desired path as an additional volume (e.g. - /:/host:ro and disk: /host).
An icon doesn’t load. The name doesn’t match the icon catalog. Write the service name lowercase and without spaces (nextcloud.png), or place a custom image in the icons folder (mounted to /app/public/icons) and reference it as /icons/name.png.
The container tile shows no status. The value at container: must be the exact container name. Find it with docker ps --format '{{.Names}}' – with Compose it’s usually folder-service-1 (e.g. traefik-traefik-1).
Changes to the YAML files don’t take effect. A syntax error aborts the parsing. YAML is indentation-sensitive – check the logs with docker compose logs homepage for error lines and use consistent spaces (no tabs).
Maintenance & backups
- Updates are low-risk. Homepage has no persistent state except your config files. Occasionally bump the image tag (
ghcr.io/gethomepage/homepage:v1.13.2) to the new version anddocker compose up -d; otherwise your normal update process handles it. After larger jumps check the release notes, as config options can change. - The backup is tiny. Back up only the
configfolder (and any customicons) – that’s your entire configuration. It belongs in your Restic backup; the application itself is recreated from the image any time. - Don’t forget security. A dashboard with Docker insight is a worthwhile target. Run it only behind HTTPS (Traefik handles that) and additionally protect it with authentication before it’s reachable publicly.
Send feedback: feedback@serverkueche.de
You might also like

Installing Uptime Kuma: server monitoring behind Traefik
Set up Uptime Kuma behind Traefik and monitor your services: monitors, notifications and a status page – the first real …

Monitoring with Grafana & Prometheus: your server in live dashboards
A complete monitoring stack of Prometheus, node-exporter, cAdvisor and Grafana behind Traefik – with live metrics for …

Host Your Own Website with Hugo – Like Serverküche Itself
Build a static website with Hugo and serve it from a Docker container behind Traefik – fast, secure, no database. …