Zum Hauptinhalt springen
S-EDV news
← Alle News
Server & Netzwerk 03.09.2026 · 7 min Lesezeit

Homepage Dashboard mit Docker Compose installieren und absichern

Diese Anleitung installiert Homepage mit Docker Compose unter /opt/homepage, bindet Dienste über YAML ein und erklärt Docker-Integration, Host-Prüfung, TLS, Authentifizierung sowie den sicheren Umgang mit dem Docker-Socket.

Illustration eines Homepage-Dashboards mit Server-, Container- und Netzwerk-Kacheln, das als selbst gehostete Startseite für Admin-Dienste per Docker Compose betrieben wird KI-generiert

Mit jedem zusätzlichen Self-Hosting-Dienst wächst dasselbe praktische Problem: Weboberflächen liegen auf verschiedenen Hosts und Ports, der Zustand einzelner Container ist nur über weitere Werkzeuge sichtbar, und wichtige Zugänge verteilen sich auf Lesezeichen und Notizen. Ein internes Dashboard löst diesen Katalog nicht allein, schafft aber einen festen Einstiegspunkt für Dienste, Statuskontrolle und Zugang.

Homepage ist dafür eine schlanke, statisch generierte Startseite. Laut Projekt unterstützt sie über 100 Dienste und Integrationen sowie mehr als 40 Sprachen und läuft auf amd64 und arm64. Einträge werden in YAML oder über Docker Labels gepflegt. API-Anfragen an konfigurierte Backends werden vom Homepage-Server weitergeleitet, sodass Zugangsdaten nicht im Browser landen, aber weiterhin auf dem Server geschützt werden müssen.

1. Architektur und Sicherheitsziel festlegen

Diese Installation legt Konfiguration und Daten unter /opt/homepage ab. Der Container veröffentlicht Port 3000 zunächst nur auf der Loopback-Adresse des Docker-Hosts, ist also nicht direkt aus LAN oder Internet erreichbar. Der Zugriff erfolgt später über VPN oder einen Reverse Proxy mit TLS und zusätzlicher Anmeldung.

BausteinAufgabeSicherheitsentscheidung
HomepageDashboard und Proxy für IntegrationsanfragenLäuft ohne Root-Rechte, nur auf 127.0.0.1
KonfigurationsverzeichnisYAML-Dateien, ggf. ZugangsdatenNur festgelegte UID/GID erhalten Schreibrechte
Reverse Proxy oder VPNKontrollierter ZugriffTLS, Authentifizierung, korrekter Host-Header
Docker-SocketContainerstatus, Auto-ErkennungOptional, bevorzugt über Socket-Proxy

Homepage ersetzt weder VPN noch Identity Provider. Wer Port 3000 direkt ins Internet veröffentlicht, macht aus einer internen Übersicht eine zusätzliche Angriffsfläche.

2. Verzeichnisse und nicht privilegierten Benutzer vorbereiten

Ermitteln Sie zuerst UID und GID des Kontos, das die Dateien besitzen soll.

id -u
id -g
sudo install -d -m 0750 -o "$(id -u)" -g "$(id -g)" /opt/homepage
sudo install -d -m 0750 -o "$(id -u)" -g "$(id -g)" /opt/homepage/config
cd /opt/homepage
printf 'PUID=%s\nPGID=%s\n' "$(id -u)" "$(id -g)" | sudo tee .env > /dev/null
sudo chown "$(id -u):$(id -g)" .env
sudo chmod 0600 .env

PUID und PGID sorgen dafür, dass der Prozess und neu geschriebene Dateien nicht Root gehören. Das reduziert Schäden bei einer kompromittierten Anwendung, ist aber keine vollständige Isolation vom Docker-Daemon und Kernel.

3. Vollständige Docker-Compose-Konfiguration erstellen

Speichern Sie diese Datei als /opt/homepage/compose.yaml. Ersetzen Sie dashboard.example.lan durch den tatsächlichen DNS-Namen. HOMEPAGE_ALLOWED_HOSTS akzeptiert eine kommagetrennte Liste, tragen Sie jeden genutzten Namen ein.

services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    restart: unless-stopped
    ports:
      - "127.0.0.1:3000:3000"
    environment:
      HOMEPAGE_ALLOWED_HOSTS: "dashboard.example.lan,localhost:3000,127.0.0.1:3000"
      PUID: "${PUID}"
      PGID: "${PGID}"
    volumes:
      - /opt/homepage/config:/app/config
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    read_only: true
    tmpfs:
      - /tmp:size=64m,mode=1777
    healthcheck:
      test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/ >/dev/null || exit 1"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 20s

Die feste Bindung 127.0.0.1:3000:3000 ist strenger als eine Veröffentlichung auf allen Interfaces. Liegt der Reverse Proxy auf einem anderen Host, nutzen Sie ein VPN zwischen den Hosts. Veröffentlichen Sie nicht gedankenlos 3000:3000. read_only, cap_drop und no-new-privileges begrenzen Schreibrechte und Linux-Capabilities auf das Nötige.

4. Grundkonfiguration und Dienste in YAML anlegen

Homepage liest die Konfiguration aus /app/config. Legen Sie mindestens settings.yaml, services.yaml, bookmarks.yaml und widgets.yaml an.

cd /opt/homepage/config
printf '%s\n' 'title: Infrastruktur' 'language: de' 'target: _self' > settings.yaml
printf '%s\n' '[]' > bookmarks.yaml
printf '%s\n' '[]' > widgets.yaml
chmod 0640 settings.yaml bookmarks.yaml widgets.yaml

Die Datei services.yaml gruppiert Links und optionale Widgets:

- Infrastruktur:
    - Traefik:
        icon: traefik.svg
        href: https://proxy.example.lan
        description: Reverse Proxy und Zertifikate
    - Beszel:
        icon: beszel.svg
        href: https://monitoring.example.lan
        description: Serverstatus und Ressourcen
- Speicher:
    - Dateidienst:
        icon: mdi-folder-network
        href: https://files.example.lan
        description: Zentraler interner Dateizugriff

Schreiben Sie API-Schlüssel nicht in href oder Beschreibungen. Widgets benötigen je nach Integration Benutzername, Passwort oder Token, diese Werte liegen als YAML auf dem Host und benötigen restriktive Rechte:

sudo chown -R "$(id -u):$(id -g)" /opt/homepage/config
find /opt/homepage/config -type d -exec chmod 0750 {} \;
find /opt/homepage/config -type f -exec chmod 0640 {} \;

5. Konfiguration prüfen und Container starten

cd /opt/homepage
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --no-log-prefix --tail=100 homepage

Testen Sie danach mit erlaubtem und mit fremdem Host-Header. Der erste Aufruf prüft die Anwendung, der zweite die Schutzwirkung der Host-Liste:

curl -I -H 'Host: localhost:3000' http://127.0.0.1:3000/
curl -I -H 'Host: unerlaubt.example' http://127.0.0.1:3000/

Bleibt der Container unhealthy, prüfen Sie zuerst das Log. Entfernen Sie den Healthcheck nicht nur wegen eines roten Status, sondern klären Sie Ursache und Startzeit.

6. Docker-Integration bewusst aktivieren

Homepage kann Container erkennen und deren Zustand anzeigen. Dafür benötigt es Zugriff auf eine Docker-Instanz über docker.yaml sowie server und container in services.yaml. Eine direkte Einbindung von /var/run/docker.sock ist funktional einfach, sicherheitstechnisch aber kritisch: Der Docker-Socket ist keine harmlose Statusdatei. Wer darüber Docker-Befehle ausführen kann, kann üblicherweise privilegierte Container starten, Host-Verzeichnisse einbinden und damit faktisch Root-Rechte auf dem Host erlangen. Ein nur lesbar eingebundener Socket verhindert nicht automatisch schreibende API-Aufrufe.

    volumes:
      - /opt/homepage/config:/app/config
      - /var/run/docker.sock:/var/run/docker.sock:ro
local-docker:
  socket: /var/run/docker.sock
- Infrastruktur:
    - Traefik:
        icon: traefik.svg
        href: https://proxy.example.lan
        description: Reverse Proxy und Zertifikate
        server: local-docker
        container: traefik

Für produktive Systeme ist ein Docker-Socket-Proxy die bessere Grenze. Er stellt nur benötigte, möglichst lesende API-Bereiche bereit, behält aber selbst den mächtigen Socket-Zugriff und muss isoliert und ausschließlich über ein internes Docker-Netz erreichbar sein. Aktivieren Sie keine Endpunkte für Container-Erstellung, Exec, Images, Volumes oder Schreiboperationen. Noch sicherer ist Verzicht auf Auto-Erkennung und rein manuelle Pflege in services.yaml.

7. Zugriff mit TLS, VPN und Anmeldung absichern

Für Zugriff aus mehreren Netzen empfiehlt sich ein VPN, dann bleibt Port 3000 intern. Wird Homepage über einen Reverse Proxy bereitgestellt, muss dieser HTTPS erzwingen, einen gültigen Host-Header weitergeben und eine zusätzliche Zugriffskontrolle umsetzen. Eine passende Schrittfolge zeigt Traefik als Docker Reverse Proxy mit HTTPS einrichten. Der externe Name muss exakt in HOMEPAGE_ALLOWED_HOSTS stehen, und der Proxy darf den ursprünglichen Host nicht durch einen internen Namen ersetzen.

  • Port 3000 nur an Loopback oder ein ausdrücklich freigegebenes internes Interface binden.
  • HTTPS am Reverse Proxy erzwingen und HTTP auf HTTPS umleiten.
  • Ein internes Dashboard nicht öffentlich indexieren lassen.
  • OIDC bevorzugen, wenn bereits ein Identity Provider mit Mehrfaktor-Authentifizierung vorhanden ist.
  • Die einfache Anmeldung nur als Zusatzschutz mit starken, einzigartigen Zugangsdaten einsetzen.
  • Admin-Oberflächen der verlinkten Dienste weiterhin separat authentifizieren.
  • Proxy und Homepage regelmäßig aktualisieren und Änderungen kontrolliert testen.

Homepage bietet optional OIDC und eine einfache Anmeldung. Welche Methode passt, hängt von der vorhandenen Identitätsinfrastruktur ab. Vermeiden Sie widersprüchliche Ketten, in denen Weiterleitungen oder Header zwischen mehreren Authentifizierungsschichten unklar sind.

8. Updates, Backups und laufende Kontrolle

Das Tag latest ermöglicht einfache Aktualisierung, aber Updates sollten trotzdem kontrolliert erfolgen: Image in einem Wartungsfenster ziehen, Release-Hinweise lesen, vorher sichern, danach Logs, Healthcheck, Widgets und Anmeldung prüfen.

cd /opt/homepage
tar -C /opt -czf "/var/backups/homepage-config-$(date +%F).tar.gz" homepage/config
docker compose pull
docker compose up -d
docker compose ps

Eine Sicherung der Konfiguration kann Geheimnisse enthalten und gehört verschlüsselt mit begrenztem Zugriff gespeichert. Für Container-Härtung, Secrets und Healthchecks ergänzt Docker Compose mit Secrets, Healthchecks und Non-Root absichern diese Maßnahmen.

  • Monatlich prüfen, ob ein neues Image oder sicherheitsrelevante Release-Hinweise vorliegen.
  • Nach Updates alle Widgets auf Authentifizierungsfehler und Zeitüberschreitungen kontrollieren.
  • Konfigurationssicherungen regelmäßig durch eine Wiederherstellung in einer Testumgebung prüfen.
  • Nicht mehr benötigte API-Token widerrufen und Widget-Rechte auf reine Leserechte begrenzen.
  • Firewall-Regeln und erlaubte Hostnamen nach DNS- oder Proxy-Änderungen erneut testen.

Homepage zeigt Zustände übersichtlich an, ist aber kein vollwertiges Monitoring mit Alarmierung und Historie. Dafür eignet sich eine getrennte Lösung wie Beszel Server Monitoring mit Docker installieren.

9. Abnahmecheck für den produktiven Betrieb

Die Installation ist erst abgeschlossen, wenn auch die Grenzen überprüft wurden. Arbeiten Sie diese Punkte nach Änderungen an Compose, DNS, Proxy oder Authentifizierung erneut ab:

  1. docker compose config --quiet endet ohne Fehler.
  2. Der Container läuft mit vorgesehener UID und GID statt als Root.
  3. Port 3000 lauscht nur auf der geplanten Adresse.
  4. Ein erlaubter Host-Header funktioniert, ein fremder wird abgewiesen.
  5. Der externe Zugriff nutzt ein gültiges TLS-Zertifikat.
  6. VPN oder Authentifizierung blockieren nicht angemeldete Nutzer.
  7. Konfigurationsdateien sind nicht für andere lokale Benutzer lesbar.
  8. API-Token der Widgets besitzen nur erforderliche Leserechte.
  9. Der Docker-Socket fehlt vollständig oder ist über einen eingeschränkten Proxy vermittelt.
  10. Backup und Wiederherstellung der YAML-Konfiguration wurden getestet.

Passende Anleitungen auf S-EDV

Quellen

HomepageDocker ComposeSelf-HostingDashboardReverse ProxyDocker-SicherheitOIDC