Skip to content
Serverküche
Search

Loading search … (only available on the published site).

Applications Difficulty: Intermediate

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.

· 6 min read ·Duration: approx. 45 minutes
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

🍳 Recommendation Ad

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.

Go to netcup →

💶 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:

Terminal
mkdir -p /opt/homepage/config /opt/homepage/icons && cd /opt/homepage

Step 2: Base settings

config/settings.yaml controls appearance and layout. We define two groups as a row layout with three columns each:

YAML
title: My Serverküche
theme: dark
color: slate
headerStyle: boxed
layout:
  Infrastructure:
    style: row
    columns: 3
  Media:
    style: row
    columns: 3

The names under layout: (Infrastructure, Media) must later match the group names in the services file exactly – only then does the layout apply.

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):

YAML
- 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.png

This is how you link your already-installed services like Nextcloud, Immich, Jellyfin or Vaultwarden in one central place.

config/widgets.yaml controls the info bar at the top. Resource display, a search box and date/time:

YAML
- resources:
    cpu: true
    memory: true
    disk: /
- search:
    provider: duckduckgo
    target: _blank
- datetime:
    text_size: xl
    format:
      dateStyle: full
      timeStyle: short

The 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:

YAML
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: true

HOMEPAGE_ALLOWED_HOSTS is mandatory

Since version 1.x, Homepage refuses to answer requests under an unknown hostname for security reasons (protection against DNS rebinding). Without the environment variable 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:

Terminal
docker compose up -d

Verify from outside that it responds with valid HTTPS:

Terminal
curl -sI https://YOUR_DOMAIN/ | head -1
Ausgabe
HTTP/2 200

In the browser you now see your dashboard with tiles and the info bar:

The Homepage dashboard with groups for infrastructure and media, resource widgets and a search box
The finished dashboard – service tiles, CPU/RAM/disk and search on one page

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:

YAML
my-docker:
  socket: /var/run/docker.sock

Then mount the socket read-only into the container – add under volumes: in compose.yaml:

YAML
      - /var/run/docker.sock:/var/run/docker.sock:ro

And link a tile to its container (server refers to the name from docker.yaml, container to the real container name):

YAML
- Infrastructure:
    - Traefik:
        description: Reverse proxy
        icon: traefik.png
        server: my-docker
        container: traefik-traefik-1

After docker compose up -d the tile shows a green status badge as soon as the container is running:

The dashboard with a Traefik tile that shows the status RUNNING live from Docker
Live status: the Traefik tile reports RUNNING straight from the Docker socket

The Docker socket is powerful – mount it read-only

Access to /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:

YAML
- Development:
    - Serverküche:
        - abbr: SK
          href: https://serverkueche.de

Now 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 and docker 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 config folder (and any custom icons) – 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.

You might also like