<?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/en/tags/dashboard/</link><description>Dashboard – Neueste Beiträge von Serverküche</description><generator>Hugo</generator><language>en-US</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/en/tags/dashboard/index.xml" rel="self" type="application/rss+xml"/><item><title>Homepage: The Dashboard for All Your Self-Hosted Services</title><link>https://serverkueche.de/en/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/en/tutorials/homepage-dashboard/</guid><description>A tidy start dashboard for your server: Homepage links every service, shows system load and the live Docker container status – behind Traefik.</description><content:encoded><![CDATA[<p>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.</p>
<h2 id="what-are-we-building">What are we building?</h2>
<p>A central dashboard with <strong>Homepage</strong> (v1.13.2) behind <a href="/en/tutorials/traefik-reverse-proxy/">Traefik</a>, configured entirely through simple YAML files. By the end you&rsquo;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 <strong>Docker socket</strong> and shows live whether a container is running. All statically generated, no database, with a tiny footprint.</p>
<h2 id="prerequisites">Prerequisites</h2>
<ul>
<li>A server with <a href="/en/tutorials/traefik-reverse-proxy/">Traefik</a> running and <a href="/en/tutorials/docker-compose-basics/">Docker Compose</a></li>
<li>A <a href="/en/tutorials/connect-domain-to-server/">subdomain pointing at the server</a> – <code>YOUR_DOMAIN</code> below (e.g. <code>start.yourdomain.com</code>)</li>
<li>A few already-running services to link (more fun, but not required)</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 · /en/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>🍳 Recommendation</span>
    <span title="Links marked with * are affiliate links.">Ad</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 vCores · 8 GB RAM · 256 GB NVMe</p>
      <p class="mt-1 text-sm font-semibold text-paprika-700 dark:text-paprika-400">from €10.36/month</p>
      <p class="mt-2 text-sm text-slate-600 dark:text-slate-400">Homepage is extremely frugal – runs happily alongside your other stack.</p>
    </div>
    <a href="https://www.netcup.com/en/server/vps/vps-1000-g12-iv-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">
  Go to 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 € voucher</strong> for new netcup customers:</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">(new customers only, no domains)</span>
</p></div>
</div>

<h2 id="step-by-step">Step by step</h2>
<h3 id="step-1-create-the-project-and-config-folder">Step 1: Create the project and config folder</h3>
<p>Homepage is driven entirely by YAML files in a <code>config</code> folder. Create the structure:</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="step-2-base-settings">Step 2: Base settings</h3>
<p><code>config/settings.yaml</code> controls appearance and layout. We define two groups as a row layout with three columns each:</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">My 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">Infrastructure</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">Media</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>The names under <code>layout:</code> (<code>Infrastructure</code>, <code>Media</code>) must later match the group names in the services file exactly – only then does the layout apply.</p>
<h3 id="step-3-link-your-services">Step 3: Link your services</h3>
<p><code>config/services.yaml</code> 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 <code>name.png</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">Infrastructure</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.YOUR_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">Your own 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.YOUR_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">Password manager</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">Media</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://photos.YOUR_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">Photos</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.YOUR_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">Media server</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>This is how you link your already-installed services like <a href="/en/tutorials/self-host-nextcloud/">Nextcloud</a>, <a href="/en/tutorials/self-host-immich-photos/">Immich</a>, <a href="/en/tutorials/jellyfin-media-server/">Jellyfin</a> or <a href="/en/tutorials/vaultwarden-password-manager/">Vaultwarden</a> in one central place.</p>
<h3 id="step-4-widgets-for-system-load-and-search">Step 4: Widgets for system load and search</h3>
<p><code>config/widgets.yaml</code> controls the info bar at the top. Resource display, a search box and date/time:</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>The <code>resources</code> widget shows the host&rsquo;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 <em>container status</em>.</p>
<h3 id="step-5-connect-traefik--and-the-crucial-host-protection">Step 5: Connect Traefik – and the crucial host protection</h3>
<p>Now the <code>compose.yaml</code>. Replace <code>YOUR_DOMAIN</code> with your real 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">YOUR_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(`YOUR_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 is mandatory
  </p>
  <div class="prose-kitchen text-sm">Since version 1.x, Homepage refuses to answer requests under an unknown hostname for security reasons (protection against DNS rebinding). Without the environment variable <code>HOMEPAGE_ALLOWED_HOSTS</code> set to your domain you&rsquo;ll only see an error page (&ldquo;Host validation failed&rdquo;). Enter your domain there <strong>exactly</strong> – multiple ones separated by commas.</div>
</div>
<p>Start the 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>Verify from outside that it responds with valid HTTPS:</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://YOUR_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>In the browser you now see your dashboard with tiles and the info bar:</p>
<p><figure class="my-6"><img src="/en/tutorials/homepage-dashboard/homepage-dashboard_hu_1aa3e429bbc89df7.webp" srcset="/en/tutorials/homepage-dashboard/homepage-dashboard_hu_f55bdd2c61ce010f.webp 480w, /en/tutorials/homepage-dashboard/homepage-dashboard_hu_1aa3e429bbc89df7.webp 768w, /en/tutorials/homepage-dashboard/homepage-dashboard_hu_32abfaa29b5f81f7.webp 1200w, /en/tutorials/homepage-dashboard/homepage-dashboard_hu_553f1d13ba71063a.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/homepage-dashboard/homepage-dashboard_hu_264bd3d64284b351.webp"
    alt="The Homepage dashboard with groups for infrastructure and media, resource widgets and a search box" title="The finished dashboard – service tiles, CPU/RAM/disk and search on one page"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">The finished dashboard – service tiles, CPU/RAM/disk and search on one page</figcaption></figure></p>
<h3 id="step-6-live-container-status-via-the-docker-socket">Step 6: Live container status via the Docker socket</h3>
<p>The strongest feature: Homepage can read directly from Docker whether a container is running, and show CPU/RAM per container. For that create <code>config/docker.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">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>Then mount the socket <strong>read-only</strong> into the container – add under <code>volumes:</code> in <code>compose.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="w">      </span>- <span class="l">/var/run/docker.sock:/var/run/docker.sock:ro</span></span></span></code></pre></div>
</div>
<p>And link a tile to its container (<code>server</code> refers to the name from <code>docker.yaml</code>, <code>container</code> to the real container name):</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">Infrastructure</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>After <code>docker compose up -d</code> the tile shows a green status badge as soon as the container is running:</p>
<p><figure class="my-6"><img src="/en/tutorials/homepage-dashboard/homepage-docker_hu_3142ee91c6bb329d.webp" srcset="/en/tutorials/homepage-dashboard/homepage-docker_hu_6d153217cef3404f.webp 480w, /en/tutorials/homepage-dashboard/homepage-docker_hu_3142ee91c6bb329d.webp 768w, /en/tutorials/homepage-dashboard/homepage-docker_hu_b65c4e135c0be19c.webp 1200w, /en/tutorials/homepage-dashboard/homepage-docker_hu_75a0d483db14a4cb.webp 1920w" sizes="(min-width: 768px) 768px, 100vw"
    width="768" height="432"
    data-full="/en/tutorials/homepage-dashboard/homepage-docker_hu_89f49f28e68001c7.webp"
    alt="The dashboard with a Traefik tile that shows the status RUNNING live from Docker" title="Live status: the Traefik tile reports RUNNING straight from the Docker socket"
    loading="lazy" decoding="async" class="rounded-lg"><figcaption class="mt-2 text-sm text-center text-slate-500 italic">Live status: the Traefik tile reports RUNNING straight from the Docker socket</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>The Docker socket is powerful – mount it read-only
  </p>
  <div class="prose-kitchen text-sm">Access to <code>/var/run/docker.sock</code> is effectively root access to the host (see <a href="/en/tutorials/linux-users-and-permissions/">Users &amp; permissions</a>). Always mount it with <strong><code>:ro</code></strong> (read only) and don&rsquo;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.</div>
</div>
<h3 id="step-7-add-bookmarks-optional">Step 7: Add bookmarks (optional)</h3>
<p>Besides services, Homepage can show plain bookmarks – via <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">Development</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>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.</p>
<h2 id="when-things-go-wrong">When things go wrong</h2>
<div class="troubleshoot not-prose">
<p><strong>&ldquo;Host validation failed&rdquo; instead of the dashboard.</strong> The most common trap: <code>HOMEPAGE_ALLOWED_HOSTS</code> is missing or has the wrong domain. Enter exactly the domain you access it under, then <code>docker compose up -d</code>.</p>
<p><strong>The resource widgets show no or wrong values.</strong> Homepage reads CPU and RAM from within the container (no socket needed). If <code>disk: /</code> shows the container filesystem instead of the host disk, mount the desired path as an additional volume (e.g. <code>- /:/host:ro</code> and <code>disk: /host</code>).</p>
<p><strong>An icon doesn&rsquo;t load.</strong> The name doesn&rsquo;t match the icon catalog. Write the service name lowercase and without spaces (<code>nextcloud.png</code>), or place a custom image in the <code>icons</code> folder (mounted to <code>/app/public/icons</code>) and reference it as <code>/icons/name.png</code>.</p>
<p><strong>The container tile shows no status.</strong> The value at <code>container:</code> must be the <strong>exact</strong> container name. Find it with <code>docker ps --format '{{.Names}}'</code> – with Compose it&rsquo;s usually <code>folder-service-1</code> (e.g. <code>traefik-traefik-1</code>).</p>
<p><strong>Changes to the YAML files don&rsquo;t take effect.</strong> A syntax error aborts the parsing. YAML is indentation-sensitive – check the logs with <code>docker compose logs homepage</code> for <code>error</code> lines and use consistent spaces (no tabs).</p>

</div>

<h2 id="maintenance--backups">Maintenance &amp; backups</h2>
<ul>
<li><strong>Updates are low-risk.</strong> Homepage has no persistent state except your config files. Occasionally bump the image tag (<code>ghcr.io/gethomepage/homepage:v1.13.2</code>) to the new version and <code>docker compose up -d</code>; otherwise your normal <a href="/en/tutorials/keep-docker-stack-updated/">update process</a> handles it. After larger jumps check the release notes, as config options can change.</li>
<li><strong>The backup is tiny.</strong> Back up only the <code>config</code> folder (and any custom <code>icons</code>) – that&rsquo;s your entire configuration. It belongs in your <a href="/en/tutorials/restic-backups/">Restic backup</a>; the application itself is recreated from the image any time.</li>
<li><strong>Don&rsquo;t forget security.</strong> 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&rsquo;s reachable publicly.
</content></li>
</ul>
]]></content:encoded></item></channel></rss>