<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dashboard – Serverküche</title><link>https://serverkueche.de/tags/dashboard/</link><description>Dashboard – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>de-DE</language><managingEditor>feedback@serverkueche.de (Serverküche)</managingEditor><webMaster>feedback@serverkueche.de (Serverküche)</webMaster><copyright>2026 Serverküche</copyright><lastBuildDate>Tue, 01 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://serverkueche.de/tags/dashboard/index.xml" rel="self" type="application/rss+xml"/><item><title>Homepage: das Dashboard für alle deine selbstgehosteten Dienste</title><link>https://serverkueche.de/tutorials/homepage-dashboard/</link><pubDate>Tue, 01 Sep 2026 00:00:00 +0000</pubDate><author>feedback@serverkueche.de (Serverküche)</author><guid>https://serverkueche.de/tutorials/homepage-dashboard/</guid><description>Ein aufgeräumtes Start-Dashboard für deinen Server: Homepage verlinkt alle Dienste, zeigt Systemlast und live den Docker-Container-Status – hinter Traefik.</description><content:encoded><![CDATA[<p>Je mehr Dienste du selbst hostest, desto mehr Lesezeichen und IP-Adressen musst du dir merken. Ein Dashboard löst das: eine einzige Startseite, die alle deine Dienste verlinkt, die Systemlast zeigt und dir sogar sagt, welche Container gerade laufen. Homepage ist dafür das schönste und schnellste Werkzeug.</p>
<h2 id="was-bauen-wir">Was bauen wir?</h2>
<p>Ein zentrales Dashboard mit <strong>Homepage</strong> (v1.13.2) hinter <a href="/tutorials/reverse-proxy-traefik/">Traefik</a>, das du komplett über einfache YAML-Dateien konfigurierst. Am Ende hast du eine aufgeräumte Startseite mit Kacheln für alle Dienste, Widgets für CPU/RAM/Festplatte, ein Suchfeld – und die Killer-Funktion: Homepage liest den <strong>Docker-Socket</strong> und zeigt live an, ob ein Container läuft. Alles statisch generiert, ohne Datenbank, mit winzigem Ressourcenbedarf.</p>
<h2 id="voraussetzungen">Voraussetzungen</h2>
<ul>
<li>Ein Server mit laufendem <a href="/tutorials/reverse-proxy-traefik/">Traefik</a> und <a href="/tutorials/docker-compose-grundlagen/">Docker Compose</a></li>
<li>Eine <a href="/tutorials/domain-mit-server-verbinden/">Subdomain, die auf den Server zeigt</a> – im Folgenden <code>DEINE_DOMAIN</code> (z. B. <code>start.deinedomain.de</code>)</li>
<li>Ein paar bereits laufende Dienste, die du verlinken willst (macht mehr Spaß, ist aber nicht Pflicht)</li>
</ul>
<div class="not-prose my-6 overflow-hidden rounded-xl border border-paprika-200 bg-paprika-50 dark:border-paprika-800 dark:bg-paprika-900/20"
     data-track-content data-content-name="Affiliate-Box · /tutorials/homepage-dashboard/" data-content-piece="VPS 1000 G12">
  <div class="flex items-center justify-between border-b border-paprika-200 bg-paprika-100 px-4 py-1.5 text-xs font-semibold uppercase tracking-wide text-paprika-700 dark:border-paprika-800 dark:bg-paprika-900/40 dark:text-paprika-300">
    <span>🍳 Empfehlung</span>
    <span title="Mit * markierte Links sind Affiliate-Links.">Anzeige</span>
  </div>
  <div class="flex flex-col gap-4 p-4 sm:flex-row sm:items-center sm:justify-between">
    <div>
      <p class="text-lg font-bold text-slate-900 dark:text-white">VPS 1000 G12</p>
      <p class="mt-1 text-sm text-slate-600 dark:text-slate-300">4 vCore · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">ab 10,36 €/Monat</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">Homepage ist extrem genügsam – läuft problemlos neben deinem übrigen Stack.</p>
    </div>
    <a href="https://www.netcup.com/de/server/vps/vps-1000-g12-12m?ref=44083" rel="sponsored noopener" target="_blank"
   data-track-event="Affiliate|netcup: Affiliate-Box|VPS 1000 G12 · {page}"
   class="inline-flex shrink-0 items-center justify-center rounded-lg bg-paprika-600 px-5 py-2.5 font-semibold text-white transition-colors hover:bg-paprika-700">
  Zu netcup →
</a>

  </div><div class="px-4 pb-4"><p class="not-prose my-3 flex flex-wrap items-center gap-x-2 gap-y-1 rounded-lg border border-herb-500/40 bg-herb-50 px-3 py-2 text-sm text-slate-700 dark:bg-herb-900/20 dark:text-slate-200">
  <span>💶 <strong>5 € Gutschein</strong> für netcup-Neukunden:</span><code data-track-voucher="36nc17844976032"
        class="rounded bg-white px-2 py-0.5 font-mono text-sm font-semibold text-herb-800 dark:bg-slate-800 dark:text-herb-400">36nc17844976032</code>
  <span class="text-xs text-slate-500 dark:text-slate-400">(nur Neukunden, keine Domains)</span>
</p></div>
</div>

<h2 id="schritt-für-schritt">Schritt für Schritt</h2>
<h3 id="schritt-1-projekt-und-konfigurationsordner-anlegen">Schritt 1: Projekt und Konfigurationsordner anlegen</h3>
<p>Homepage wird ausschließlich über YAML-Dateien in einem <code>config</code>-Ordner gesteuert. Lege die Struktur an:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p /opt/homepage/config /opt/homepage/icons <span class="o">&amp;&amp;</span> <span class="nb">cd</span> /opt/homepage</span></span></code></pre></div>
</div>
<h3 id="schritt-2-grundeinstellungen">Schritt 2: Grundeinstellungen</h3>
<p>Die <code>config/settings.yaml</code> bestimmt Aussehen und Layout. Wir definieren zwei Gruppen als Zeilen-Layout mit je drei Spalten:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="l">Meine Serverküche</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">theme</span><span class="p">:</span><span class="w"> </span><span class="l">dark</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">color</span><span class="p">:</span><span class="w"> </span><span class="l">slate</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">headerStyle</span><span class="p">:</span><span class="w"> </span><span class="l">boxed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">layout</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">Infrastruktur</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">style</span><span class="p">:</span><span class="w"> </span><span class="l">row</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">columns</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">Medien</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">style</span><span class="p">:</span><span class="w"> </span><span class="l">row</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">columns</span><span class="p">:</span><span class="w"> </span><span class="m">3</span></span></span></code></pre></div>
</div>
<p>Die Namen unter <code>layout:</code> (<code>Infrastruktur</code>, <code>Medien</code>) müssen später exakt mit den Gruppennamen in der Dienste-Datei übereinstimmen – nur dann greift das Layout.</p>
<h3 id="schritt-3-dienste-verlinken">Schritt 3: Dienste verlinken</h3>
<p>Die <code>config/services.yaml</code> ist das Herzstück – deine Kacheln. Jeder Dienst bekommt einen Namen, eine URL, eine Beschreibung und ein Icon (Homepage lädt passende Icons automatisch aus einem großen Katalog, wenn du <code>name.png</code> angibst):</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">Infrastruktur</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Nextcloud</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">href</span><span class="p">:</span><span class="w"> </span><span class="l">https://cloud.DEINE_DOMAIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l">Eigene Cloud</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">icon</span><span class="p">:</span><span class="w"> </span><span class="l">nextcloud.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Vaultwarden</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">href</span><span class="p">:</span><span class="w"> </span><span class="l">https://vault.DEINE_DOMAIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l">Passwortmanager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">icon</span><span class="p">:</span><span class="w"> </span><span class="l">vaultwarden.png</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">Medien</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Immich</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">href</span><span class="p">:</span><span class="w"> </span><span class="l">https://fotos.DEINE_DOMAIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l">Fotos</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">icon</span><span class="p">:</span><span class="w"> </span><span class="l">immich.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Jellyfin</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">href</span><span class="p">:</span><span class="w"> </span><span class="l">https://media.DEINE_DOMAIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l">Medienserver</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">icon</span><span class="p">:</span><span class="w"> </span><span class="l">jellyfin.png</span></span></span></code></pre></div>
</div>
<p>So verlinkst du deine bereits installierten Dienste wie <a href="/tutorials/nextcloud-eigene-cloud/">Nextcloud</a>, <a href="/tutorials/immich-fotos-selbst-hosten/">Immich</a>, <a href="/tutorials/jellyfin-medienserver/">Jellyfin</a> oder <a href="/tutorials/vaultwarden-passwortmanager/">Vaultwarden</a> an einer zentralen Stelle.</p>
<h3 id="schritt-4-widgets-für-systemlast-und-suche">Schritt 4: Widgets für Systemlast und Suche</h3>
<p>Die <code>config/widgets.yaml</code> steuert die Info-Leiste oben. Ressourcen-Anzeige, ein Suchfeld und Datum/Uhrzeit:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">cpu</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">memory</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">disk</span><span class="p">:</span><span class="w"> </span><span class="l">/</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">search</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">provider</span><span class="p">:</span><span class="w"> </span><span class="l">duckduckgo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">target</span><span class="p">:</span><span class="w"> </span><span class="l">_blank</span><span class="w">
</span></span></span><span class="line"><span class="cl">- <span class="nt">datetime</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">text_size</span><span class="p">:</span><span class="w"> </span><span class="l">xl</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">dateStyle</span><span class="p">:</span><span class="w"> </span><span class="l">full</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">timeStyle</span><span class="p">:</span><span class="w"> </span><span class="l">short</span></span></span></code></pre></div>
</div>
<p>Das <code>resources</code>-Widget zeigt die Auslastung des Hosts. CPU und RAM liest Homepage direkt aus dem Container heraus (kein Docker-Socket nötig); den Socket binden wir erst im nächsten Schritt für den <em>Container-Status</em> ein.</p>
<h3 id="schritt-5-mit-traefik-verbinden--und-der-entscheidende-host-schutz">Schritt 5: Mit Traefik verbinden – und der entscheidende Host-Schutz</h3>
<p>Jetzt die <code>compose.yaml</code>. Ersetze <code>DEINE_DOMAIN</code> durch deine echte Subdomain:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">homepage</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">ghcr.io/gethomepage/homepage:v1.13.2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">restart</span><span class="p">:</span><span class="w"> </span><span class="l">unless-stopped</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">environment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">HOMEPAGE_ALLOWED_HOSTS</span><span class="p">:</span><span class="w"> </span><span class="l">DEINE_DOMAIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./config:/app/config</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">./icons:/app/public/icons</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">networks</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">proxy]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.enable=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.homepage.rule=Host(`DEINE_DOMAIN`)&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.homepage.entrypoints=websecure&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.routers.homepage.tls.certresolver=le&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;traefik.http.services.homepage.loadbalancer.server.port=3000&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">networks</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">proxy</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">external</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></div>
</div>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>HOMEPAGE_ALLOWED_HOSTS ist Pflicht
  </p>
  <div class="prose-kitchen text-sm">Seit Version 1.x weigert sich Homepage aus Sicherheitsgründen (Schutz vor DNS-Rebinding), Anfragen unter einem unbekannten Hostnamen zu beantworten. Ohne die Umgebungsvariable <code>HOMEPAGE_ALLOWED_HOSTS</code> mit deiner Domain siehst du nur eine Fehlerseite („Host validation failed“). Trage dort <strong>exakt</strong> deine Domain ein – mehrere durch Komma getrennt.</div>
</div>
<p>Starte das Dashboard:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose up -d</span></span></code></pre></div>
</div>
<p>Prüfe von außen, dass es mit gültigem HTTPS antwortet:</p>
<div class="sk-code">
  <span class="sk-code-head">Terminal</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sI https://DEINE_DOMAIN/ <span class="p">|</span> head -1</span></span></code></pre></div>
</div>
<div class="sk-code">
  <span class="sk-code-head">Ausgabe</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">HTTP/2 200</span></span></code></pre></div>
</div>
<p>Im Browser siehst du jetzt dein Dashboard mit den Kacheln und der Info-Leiste:</p>
<p><figure class="my-6"><img src="/tutorials/homepage-dashboard/homepage-dashboard_hu_1aa3e429bbc89df7.webp" srcset="/tutorials/homepage-dashboard/homepage-dashboard_hu_f55bdd2c61ce010f.webp 480w, /tutorials/homepage-dashboard/homepage-dashboard_hu_1aa3e429bbc89df7.webp 768w, /tutorials/homepage-dashboard/homepage-dashboard_hu_32abfaa29b5f81f7.webp 1200w, /tutorials/homepage-dashboard/homepage-dashboard_hu_553f1d13ba71063a.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/homepage-dashboard/homepage-dashboard_hu_264bd3d64284b351.webp"
    alt="Das Homepage-Dashboard mit Gruppen für Infrastruktur und Medien, Ressourcen-Widgets und Suchfeld" title="Das fertige Dashboard – Dienste-Kacheln, CPU/RAM/Disk und Suche auf einer Seite"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Das fertige Dashboard – Dienste-Kacheln, CPU/RAM/Disk und Suche auf einer Seite</figcaption></figure></p>
<h3 id="schritt-6-live-container-status-über-den-docker-socket">Schritt 6: Live-Container-Status über den Docker-Socket</h3>
<p>Die stärkste Funktion: Homepage kann direkt aus Docker lesen, ob ein Container läuft, und CPU/RAM je Container anzeigen. Dafür legst du <code>config/docker.yaml</code> an:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">my-docker</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">socket</span><span class="p">:</span><span class="w"> </span><span class="l">/var/run/docker.sock</span></span></span></code></pre></div>
</div>
<p>Dann bindest du den Socket <strong>schreibgeschützt</strong> in den Container ein – ergänze in der <code>compose.yaml</code> unter <code>volumes:</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">/var/run/docker.sock:/var/run/docker.sock:ro</span></span></span></code></pre></div>
</div>
<p>Und verknüpfst eine Kachel mit ihrem Container (<code>server</code> verweist auf den Namen aus <code>docker.yaml</code>, <code>container</code> auf den echten Container-Namen):</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">Infrastruktur</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Traefik</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l">Reverse Proxy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">icon</span><span class="p">:</span><span class="w"> </span><span class="l">traefik.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l">my-docker</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">container</span><span class="p">:</span><span class="w"> </span><span class="l">traefik-traefik-1</span></span></span></code></pre></div>
</div>
<p>Nach <code>docker compose up -d</code> zeigt die Kachel ein grünes Status-Abzeichen, sobald der Container läuft:</p>
<p><figure class="my-6"><img src="/tutorials/homepage-dashboard/homepage-docker_hu_3142ee91c6bb329d.webp" srcset="/tutorials/homepage-dashboard/homepage-docker_hu_6d153217cef3404f.webp 480w, /tutorials/homepage-dashboard/homepage-docker_hu_3142ee91c6bb329d.webp 768w, /tutorials/homepage-dashboard/homepage-docker_hu_b65c4e135c0be19c.webp 1200w, /tutorials/homepage-dashboard/homepage-docker_hu_75a0d483db14a4cb.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/tutorials/homepage-dashboard/homepage-docker_hu_89f49f28e68001c7.webp"
    alt="Das Dashboard mit einer Traefik-Kachel, die live den Status RUNNING aus Docker anzeigt" title="Live-Status: die Traefik-Kachel meldet direkt aus dem Docker-Socket „RUNNING“"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Live-Status: die Traefik-Kachel meldet direkt aus dem Docker-Socket „RUNNING“</figcaption></figure></p>
<div class="not-prose my-6 rounded-lg border-l-4 p-4 border-amber-400 bg-amber-50 dark:border-amber-700 dark:bg-amber-900/20">
  <p class="mb-1 flex items-center gap-2 font-semibold text-slate-900 dark:text-white">
    <span aria-hidden="true">⚠️</span>Der Docker-Socket ist mächtig – nur lesend einbinden
  </p>
  <div class="prose-kitchen text-sm">Zugriff auf <code>/var/run/docker.sock</code> ist faktisch Root-Zugriff auf den Host (siehe <a href="/tutorials/linux-benutzer-und-rechte/">Benutzer &amp; Rechte</a>). Binde ihn deshalb <strong>immer mit <code>:ro</code></strong> (read only) ein und veröffentliche Homepage nicht ungeschützt im Internet. Für echten Schutz gehört vor ein solches Dashboard eine Authentifizierung – etwa eine Traefik-BasicAuth-Middleware oder später ein Single-Sign-On.</div>
</div>
<h3 id="schritt-7-lesezeichen-ergänzen-optional">Schritt 7: Lesezeichen ergänzen (optional)</h3>
<p>Neben Diensten kann Homepage auch reine Lesezeichen anzeigen – über <code>config/bookmarks.yaml</code>:</p>
<div class="sk-code">
  <span class="sk-code-head">YAML</span>
  <div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl">- <span class="nt">Entwicklung</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">Serverküche</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">abbr</span><span class="p">:</span><span class="w"> </span><span class="l">SK</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">href</span><span class="p">:</span><span class="w"> </span><span class="l">https://serverkueche.de</span></span></span></code></pre></div>
</div>
<p>Damit hast du Dienste, Systemlast, Suche und Lesezeichen an einem Ort. Änderungen an den YAML-Dateien übernimmt Homepage automatisch – ein Neuladen im Browser genügt meist, kein Neustart nötig.</p>
<h2 id="wenn-es-nicht-funktioniert">Wenn es nicht funktioniert</h2>
<div class="troubleshoot not-prose">
<p><strong>„Host validation failed&quot; statt Dashboard.</strong> Die häufigste Stolperfalle: <code>HOMEPAGE_ALLOWED_HOSTS</code> fehlt oder enthält die falsche Domain. Genau die Domain eintragen, unter der du zugreifst, dann <code>docker compose up -d</code>.</p>
<p><strong>Die Ressourcen-Widgets zeigen keine oder falsche Werte.</strong> CPU und RAM liest Homepage aus dem Container heraus (kein Socket nötig). Zeigt <code>disk: /</code> das Container-Dateisystem statt der Host-Platte, binde den gewünschten Pfad zusätzlich als Volume ein (z. B. <code>- /:/host:ro</code> und <code>disk: /host</code>).</p>
<p><strong>Ein Icon wird nicht geladen.</strong> Der Name passt nicht zum Icon-Katalog. Schreibe den Dienstnamen klein und ohne Leerzeichen (<code>nextcloud.png</code>), oder lege ein eigenes Bild in den <code>icons</code>-Ordner (gemountet nach <code>/app/public/icons</code>) und referenziere es als <code>/icons/name.png</code>.</p>
<p><strong>Die Container-Kachel zeigt keinen Status.</strong> Der Wert bei <code>container:</code> muss der <strong>exakte</strong> Container-Name sein. Finde ihn mit <code>docker ps --format '{{.Names}}'</code> – bei Compose ist das meist <code>ordner-dienst-1</code> (z. B. <code>traefik-traefik-1</code>).</p>
<p><strong>Änderungen an den YAML-Dateien greifen nicht.</strong> Ein Syntaxfehler bricht das Einlesen ab. YAML ist einrückungsempfindlich – prüfe die Logs mit <code>docker compose logs homepage</code> auf <code>error</code>-Zeilen und achte auf konsequente Leerzeichen (keine Tabs).</p>

</div>

<h2 id="wartung--backups">Wartung &amp; Backups</h2>
<ul>
<li><strong>Updates sind unkritisch.</strong> Homepage hat keinen persistenten Zustand außer deinen Config-Dateien. Bump den Image-Tag (<code>ghcr.io/gethomepage/homepage:v1.13.2</code>) gelegentlich auf die neue Version und <code>docker compose up -d</code>; das übernimmt sonst dein normaler <a href="/tutorials/docker-stack-aktuell-halten/">Update-Prozess</a>. Prüfe nach größeren Sprüngen die Release-Notes, da sich Config-Optionen ändern können.</li>
<li><strong>Das Backup ist winzig.</strong> Sichere nur den <code>config</code>-Ordner (und ggf. eigene <code>icons</code>) – das ist deine gesamte Konfiguration. Er gehört ins <a href="/tutorials/backups-mit-restic/">Restic-Backup</a>; die Anwendung selbst wird jederzeit aus dem Image neu erzeugt.</li>
<li><strong>Sicherheit nicht vergessen.</strong> Ein Dashboard mit Docker-Einblick ist ein lohnendes Ziel. Betreibe es nur hinter HTTPS (erledigt Traefik) und schütze es zusätzlich mit einer Authentifizierung, bevor es öffentlich erreichbar ist.
</content></li>
</ul>
]]></content:encoded></item></channel></rss>