{
    "version": "https://jsonfeed.org/version/1",
    "title": "AMUD Dashboard Blog",
    "home_page_url": "https://boubli.github.io/AMUD-Dashboard/de/blog",
    "description": "AMUD Dashboard Blog",
    "items": [
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/v1-6-4-branding-pwa",
            "content_html": "<p>Custom logos uploaded in <strong>Settings → Dashboard Logo</strong> now show for <strong>everyone</strong> — guests, the login page, browser favicon, and installed PWA icons. This release also tightens mobile layout across all themes.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"branding-logo-fix\">Branding logo fix<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/v1-6-4-branding-pwa#branding-logo-fix\" class=\"hash-link\" aria-label=\"Direkter Link zur Branding logo fix\" title=\"Direkter Link zur Branding logo fix\" translate=\"no\">​</a></h2>\n<p>Before v1.6.4, <code>/uploads/…</code> required an admin session. Logged-in users saw your custom gamepad (or PNG); guests and the login page got an empty box and a broken favicon.</p>\n<p><strong>Now:</strong></p>\n<ul>\n<li class=\"\"><code>GET /uploads/{file}</code> is publicly readable (upload stays admin-only)</li>\n<li class=\"\">Dashboard, login, and settings render <code>&lt;img&gt;</code> when a logo is set</li>\n<li class=\"\">Favicon, Apple touch icon, and <code>/manifest.webmanifest</code> use the same URL</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pwa-mobile-polish\">PWA mobile polish<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/v1-6-4-branding-pwa#pwa-mobile-polish\" class=\"hash-link\" aria-label=\"Direkter Link zur PWA mobile polish\" title=\"Direkter Link zur PWA mobile polish\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Hamburger menu uses a <strong>fixed panel</strong> below the topbar — no more covering the greeting</li>\n<li class=\"\">Tap <strong>outside</strong> the menu to close it</li>\n<li class=\"\">Centered logo/title, telemetry 2-per-row, expandable search icon</li>\n<li class=\"\">Service worker cache <strong>v26</strong> — hard-refresh or clear PWA cache after upgrade</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"upgrade\">Upgrade<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/v1-6-4-branding-pwa#upgrade\" class=\"hash-link\" aria-label=\"Direkter Link zur Upgrade\" title=\"Direkter Link zur Upgrade\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">curl -sSL https://github.com/boubli/AMUD-Dashboard/releases/download/v1.6.4/update-amud.sh | bash</span><br></div></code></pre></div></div>\n<p>Docker: <code>docker compose pull &amp;&amp; docker compose up -d --force-recreate</code></p>\n<p>Full notes: <a href=\"https://github.com/boubli/AMUD-Dashboard/releases/tag/v1.6.4\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Release v1.6.4</a> · <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/changelog\">Changelog</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/v1-6-4-branding-pwa",
            "title": "v1.6.4 — Branding logo fix & PWA mobile polish",
            "summary": "Custom logos uploaded in Settings → Dashboard Logo now show for everyone — guests, the login page, browser favicon, and installed PWA icons. This release also tightens mobile layout across all themes.",
            "date_modified": "2026-06-28T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "release",
                "pwa"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes",
            "content_html": "<p>AMUD now ships <strong>37 themes</strong> total — 18 brand-new palettes plus a visual <strong>Theme Gallery</strong> built into Settings → Appearance.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"visual-theme-picker\">Visual theme picker<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#visual-theme-picker\" class=\"hash-link\" aria-label=\"Direkter Link zur Visual theme picker\" title=\"Direkter Link zur Visual theme picker\" translate=\"no\">​</a></h2>\n<p>No more dropdown + \"Load into editor\". The Appearance tab now shows a <strong>grid of theme cards</strong> with preview images. Click any theme to instantly preview its CSS and matching wallpaper in the live mini-dashboard. Click <strong>Save Changes</strong> when you're happy.</p>\n<ul>\n<li class=\"\"><strong>AMUD Default</strong> resets to the built-in orange glass look and <code>/static/wallpaper.png</code></li>\n<li class=\"\">Every other theme loads its bundled CSS and sets a <strong>matching wallpaper</strong> automatically</li>\n<li class=\"\">Terminal themes (phosphor, amber, matrix) use CSS-only CRT backgrounds</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-theme-packs\">New theme packs<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#new-theme-packs\" class=\"hash-link\" aria-label=\"Direkter Link zur New theme packs\" title=\"Direkter Link zur New theme packs\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"nature-5\">Nature (5)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#nature-5\" class=\"hash-link\" aria-label=\"Direkter Link zur Nature (5)\" title=\"Direkter Link zur Nature (5)\" translate=\"no\">​</a></h3>\n<p>Aurora Borealis, Desert Dusk, Ocean Depths, Rainforest Mist, Volcanic Ember — totally different moods from the classic developer palettes.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"terminal-2-new\">Terminal (2 new)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#terminal-2-new\" class=\"hash-link\" aria-label=\"Direkter Link zur Terminal (2 new)\" title=\"Direkter Link zur Terminal (2 new)\" translate=\"no\">​</a></h3>\n<p>Terminal Amber and Terminal Matrix join Terminal Phosphor for CRT lovers.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"feminine-5\">Feminine (5)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#feminine-5\" class=\"hash-link\" aria-label=\"Direkter Link zur Feminine (5)\" title=\"Direkter Link zur Feminine (5)\" translate=\"no\">​</a></h3>\n<p>Sakura Dream, Lavender Mist, Rose Gold Blush, Cotton Candy, Peach Blossom — soft pastels and blossom tones.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"variety-6\">Variety (6)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#variety-6\" class=\"hash-link\" aria-label=\"Direkter Link zur Variety (6)\" title=\"Direkter Link zur Variety (6)\" translate=\"no\">​</a></h3>\n<p>Nebula Void, Arctic Frost, Steampunk Brass, Zen Garden, Retro Arcade, Midnight City.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"offline-first\">Offline-first<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#offline-first\" class=\"hash-link\" aria-label=\"Direkter Link zur Offline-first\" title=\"Direkter Link zur Offline-first\" translate=\"no\">​</a></h2>\n<p>All theme CSS, preview thumbnails, and wallpapers ship inside <code>ui/static/themes/</code> on your server. No GitHub Pages required for daily use — the online <a href=\"https://boubli.github.io/AMUD-Dashboard/themes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Theme Gallery</a> is there when you want to browse from a browser.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"try-it\">Try it<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes#try-it\" class=\"hash-link\" aria-label=\"Direkter Link zur Try it\" title=\"Direkter Link zur Try it\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">Update to the latest AMUD build</li>\n<li class=\"\">Open <strong>Settings → Appearance</strong></li>\n<li class=\"\">Scroll to <strong>Theme Gallery</strong></li>\n<li class=\"\">Click a theme, then <strong>Save Changes</strong></li>\n</ol>\n<p>Happy theming!</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/eighteen-new-themes",
            "title": "18 New Themes + Visual Theme Gallery",
            "summary": "AMUD now ships 37 themes total — 18 brand-new palettes plus a visual Theme Gallery built into Settings → Appearance.",
            "date_modified": "2026-06-25T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Themes"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/encrypted-secrets-at-rest",
            "content_html": "<p>Storing <code>X-Plex-Token=abc123</code> in plain text in a yaml file on disk always felt wrong. Storing it in plain text in SQLite felt equally wrong.</p>\n<p>AMUD Dashboard encrypts integration secrets <strong>at rest</strong> with AES-GCM. Plex, Jellyfin, Proxmox API tokens, Home Assistant tokens — encrypted blob in the database, not readable if someone copies <code>amud.db</code> without the key.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-keyfile\">The keyfile<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/encrypted-secrets-at-rest#the-keyfile\" class=\"hash-link\" aria-label=\"Direkter Link zur The keyfile\" title=\"Direkter Link zur The keyfile\" translate=\"no\">​</a></h2>\n<p><code>.amud-secrets-key</code> on the host. Derived key material for encryption/decryption at runtime.</p>\n<p><strong>Back it up with your database.</strong> Restore DB without key = your tokens are toast. You'll re-enter them in settings. Annoying but not catastrophic.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"whats-not-encrypted\">What's not encrypted<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/encrypted-secrets-at-rest#whats-not-encrypted\" class=\"hash-link\" aria-label=\"Direkter Link zur What's not encrypted\" title=\"Direkter Link zur What's not encrypted\" translate=\"no\">​</a></h2>\n<p>App URLs, card names, layout stuff — none of that's secret. Your Jellyfin URL being <code>http://10.0.0.5:8096</code> isn't the sensitive part. The API key is.</p>\n<p>Password <strong>hashes</strong> use Argon2id separately. Different layer. Same philosophy: don't store usable secrets in recoverable form.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"threat-model-realistic\">Threat model (realistic)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/encrypted-secrets-at-rest#threat-model-realistic\" class=\"hash-link\" aria-label=\"Direkter Link zur Threat model (realistic)\" title=\"Direkter Link zur Threat model (realistic)\" translate=\"no\">​</a></h2>\n<p>This stops \"someone copied my backup drive\" from leaking your Proxmox token. It doesn't stop someone with root on your running server — they own the box anyway.</p>\n<p>Homelab threat model. Not banking.</p>\n<p>Full security writeup: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/security\">/docs/security</a></p>\n<p>Rotate tokens in integrations settings if you think the DB leaked. Same as any other dashboard.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/encrypted-secrets-at-rest",
            "title": "Where Your Plex Token Actually Lives in AMUD Dashboard",
            "summary": "AES-GCM encrypted integration creds in SQLite, .amud-secrets-key on disk. What gets encrypted and what doesn't.",
            "date_modified": "2026-02-25T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Security",
                "Rust"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/sqlite-wal-not-postgres",
            "content_html": "<p>\"Why not Postgres?\"</p>\n<p>Because then I'd need to run Postgres.</p>\n<p>AMUD Dashboard is a dashboard. Config storage is a few hundred KB of apps, settings, and encrypted tokens. Running a whole separate database server for that is like buying a warehouse to store a shoebox.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"sqlite-with-wal\">SQLite with WAL<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/sqlite-wal-not-postgres#sqlite-with-wal\" class=\"hash-link\" aria-label=\"Direkter Link zur SQLite with WAL\" title=\"Direkter Link zur SQLite with WAL\" translate=\"no\">​</a></h2>\n<p>Write-Ahead Logging lets readers (the web UI loading settings) coexist with writers (you saving a new app card) without the lock contention that makes people hate SQLite in web apps from 2010.</p>\n<p>For a single-tenant homelab dashboard with one admin clicking settings occasionally? Perfect fit.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"operational-wins\">Operational wins<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/sqlite-wal-not-postgres#operational-wins\" class=\"hash-link\" aria-label=\"Direkter Link zur Operational wins\" title=\"Direkter Link zur Operational wins\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>Zero extra container</strong> — <code>amud.db</code> sits next to the binary</li>\n<li class=\"\"><strong>Backup</strong> — <code>cp amud.db backup.db</code></li>\n<li class=\"\"><strong>Restore</strong> — swap file, restart</li>\n<li class=\"\"><strong>Inspect</strong> — <code>sqlite3 amud.db</code> when debugging</li>\n</ul>\n<p>I've done all of these at 1am. Postgres would add connection strings, another service to monitor, another thing to backup separately.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"when-id-reach-for-postgres\">When I'd reach for Postgres<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/sqlite-wal-not-postgres#when-id-reach-for-postgres\" class=\"hash-link\" aria-label=\"Direkter Link zur When I'd reach for Postgres\" title=\"Direkter Link zur When I'd reach for Postgres\" translate=\"no\">​</a></h2>\n<p>Multi-tenant SaaS. Hundreds of concurrent writers. Horizontal scaling. AMUD Dashboard is explicitly none of those — see roadmap \"won't do SaaS.\"</p>\n<p>Homelab tool. Homelab database. Match the complexity to the problem.</p>\n<p><a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/intro\">/docs/intro</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/sqlite-wal-not-postgres",
            "title": "Why AMUD Dashboard Uses SQLite Instead of Postgres (Yes, Really)",
            "summary": "Embedded DB for embedded dashboard. WAL mode, single-file backup, no extra container for config storage.",
            "date_modified": "2026-02-23T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Rust",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage",
            "content_html": "<p>I ran Homepage for a year. Liked it. Still recommend it for the right person.</p>\n<p>Switching to AMUD Dashboard wasn't \"Homepage bad, AMUD Dashboard good.\" It was \"I'm tired of this specific workflow.\"</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-i-lost\">What I lost<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage#what-i-lost\" class=\"hash-link\" aria-label=\"Direkter Link zur What I lost\" title=\"Direkter Link zur What I lost\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>Git-tracked config</strong> — every service change was a commit. That's gone. AMUD Dashboard lives in SQLite, not <code>services.yaml</code> in a repo.</li>\n<li class=\"\"><strong>Community widget YAML</strong> — Homepage's widget library is huge. AMUD Dashboard has built-in Plex/Jellyfin/HA/Proxmox stuff but not the long tail of community widgets.</li>\n<li class=\"\"><strong>Docker-only mental model</strong> — Homepage fits the \"everything in compose\" crowd perfectly.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-i-gained\">What I gained<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage#what-i-gained\" class=\"hash-link\" aria-label=\"Direkter Link zur What I gained\" title=\"Direkter Link zur What I gained\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>UI edits at midnight</strong> — add a card from my phone browser. No SSH, no git pull on the host.</li>\n<li class=\"\"><strong>Native Proxmox LXC control</strong> — not a widget bolted on. First-class CTID binding and power actions.</li>\n<li class=\"\"><strong>RAM</strong> — meaningful on a crowded Proxmox node.</li>\n<li class=\"\"><strong>One-file backup</strong> — <code>amud.db</code> instead of yaml + env + secrets scattered around.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"who-should-stay-on-homepage\">Who should stay on Homepage<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage#who-should-stay-on-homepage\" class=\"hash-link\" aria-label=\"Direkter Link zur Who should stay on Homepage\" title=\"Direkter Link zur Who should stay on Homepage\" translate=\"no\">​</a></h2>\n<p>You like GitOps. You generate configs from Ansible. You want fifty community widgets. YAML doesn't make you twitch.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"who-should-try-amud-dashboard\">Who should try AMUD Dashboard<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage#who-should-try-amud-dashboard\" class=\"hash-link\" aria-label=\"Direkter Link zur Who should try AMUD Dashboard\" title=\"Direkter Link zur Who should try AMUD Dashboard\" translate=\"no\">​</a></h2>\n<p>Proxmox primary. YAML fatigue. Want live LXC status without shell scripts. Okay with \"config in a database\" as the trade.</p>\n<p>Migration tip: screenshot your Homepage layout, recreate cards in AMUD Dashboard while watching TV. Took me about forty minutes for ~25 services. Your mileage varies.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">curl -sSL https://raw.githubusercontent.com/boubli/AMUD-Dashboard/main/setup-amud.sh | bash</span><br></div></code></pre></div></div>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/migrated-from-homepage",
            "title": "I Migrated From Homepage to AMUD Dashboard — What I Lost and Gained",
            "summary": "Honest post-Homepage review. GitOps YAML vs browser config. No sugarcoating.",
            "date_modified": "2026-02-21T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries",
            "content_html": "<p>\"Why not one binary?\"</p>\n<p>Because on Proxmox the dashboard server lives in an <strong>unprivileged LXC</strong> and the thing that talks to <code>/proc</code>, the Docker socket, and the PVE API on port 8006 needs to live on the <strong>host</strong>.</p>\n<p>Different trust boundaries. Different privilege levels.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"amud-server\">amud-server<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries#amud-server\" class=\"hash-link\" aria-label=\"Direkter Link zur amud-server\" title=\"Direkter Link zur amud-server\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Serves HTTP/WebSockets</li>\n<li class=\"\">Owns SQLite</li>\n<li class=\"\">Runs as unprivileged <code>amud</code> user in the LXC</li>\n<li class=\"\">Never needs root</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"amud-agent\">amud-agent<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries#amud-agent\" class=\"hash-link\" aria-label=\"Direkter Link zur amud-agent\" title=\"Direkter Link zur amud-agent\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Reads host hardware</li>\n<li class=\"\">Queries Proxmox API</li>\n<li class=\"\">Optionally reads Docker socket</li>\n<li class=\"\">Runs on hypervisor host with the permissions that requires</li>\n</ul>\n<p>They talk over <code>/opt/amud/run/amud.sock</code>. Bind-mounted into the LXC on Proxmox installs. Shared Docker volume in container deployments.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"challenge-response-auth\">Challenge-response auth<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries#challenge-response-auth\" class=\"hash-link\" aria-label=\"Direkter Link zur Challenge-response auth\" title=\"Direkter Link zur Challenge-response auth\" translate=\"no\">​</a></h2>\n<p>The socket isn't world-writable chaos. Agent proves it knows <code>AMUD_AGENT_SECRET</code> before the server accepts telemetry. Stops random local processes from feeding fake metrics.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"could-i-merge-them\">Could I merge them?<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries#could-i-merge-them\" class=\"hash-link\" aria-label=\"Direkter Link zur Could I merge them?\" title=\"Direkter Link zur Could I merge them?\" translate=\"no\">​</a></h2>\n<p>On single-box Docker or bare-metal where server and agent share a host, they're still separate processes for isolation. Server crash doesn't take down polling. Agent restart doesn't drop active web sessions.</p>\n<p>Might be over-engineered for a homelab. I'd rather over-engineer the security boundary than under-engineer it.</p>\n<p><a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/ARCHITECTURE\">/docs/ARCHITECTURE</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/why-two-binaries",
            "title": "Why AMUD Dashboard Is Two Binaries Instead of One Blob",
            "summary": "Server in LXC, agent on the hypervisor host. Separation of privileges and why the Unix socket exists.",
            "date_modified": "2026-02-19T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Rust",
                "Proxmox",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud",
            "content_html": "<p>AMUD Dashboard isn't a startup. It's a homelab tool I built because I wanted it. But it gets better when other people break it in ways I didn't imagine.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"fastest-help-star-the-repo\">Fastest help: star the repo<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud#fastest-help-star-the-repo\" class=\"hash-link\" aria-label=\"Direkter Link zur Fastest help: star the repo\" title=\"Direkter Link zur Fastest help: star the repo\" translate=\"no\">​</a></h2>\n<p><a href=\"https://github.com/boubli/AMUD-Dashboard\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">github.com/boubli/AMUD-Dashboard</a></p>\n<p>Stars help GitHub discovery and lists like awesome-selfhosted. Sounds shallow. Matters anyway.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"try-it-and-tell-me-your-stack\">Try it and tell me your stack<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud#try-it-and-tell-me-your-stack\" class=\"hash-link\" aria-label=\"Direkter Link zur Try it and tell me your stack\" title=\"Direkter Link zur Try it and tell me your stack\" translate=\"no\">​</a></h2>\n<p>Proxmox version, RAM numbers, screenshot of your dashboard. <a href=\"https://github.com/boubli/AMUD-Dashboard/discussions\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Discussions</a> is the place. \"Works on my weird ARM NAS\" posts are gold.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"bug-reports-that-get-fixed-fast\">Bug reports that get fixed fast<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud#bug-reports-that-get-fixed-fast\" class=\"hash-link\" aria-label=\"Direkter Link zur Bug reports that get fixed fast\" title=\"Direkter Link zur Bug reports that get fixed fast\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Steps to reproduce</li>\n<li class=\"\"><code>journalctl -u amud-agent -n 50</code> output</li>\n<li class=\"\">Whether you're Docker or native LXC</li>\n</ul>\n<p>Vague \"doesn't work\" issues sit longer. Fair warning.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pr-areas\">PR areas<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud#pr-areas\" class=\"hash-link\" aria-label=\"Direkter Link zur PR areas\" title=\"Direkter Link zur PR areas\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>Area</th><th>Stack</th></tr></thead><tbody><tr><td>amud-server</td><td>Rust, Axum</td></tr><tr><td>amud-agent</td><td>Rust, Tokio</td></tr><tr><td>UI</td><td>HTML, Alpine.js, CSS</td></tr><tr><td>Docs</td><td>Docusaurus, Markdown</td></tr><tr><td>Themes</td><td>CSS variables</td></tr></tbody></table>\n<p>Roadmap: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/roadmap\">/docs/roadmap</a> — ARM64 CI, webhooks, multi-node agents on the list.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"submit-a-theme\">Submit a theme<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud#submit-a-theme\" class=\"hash-link\" aria-label=\"Direkter Link zur Submit a theme\" title=\"Direkter Link zur Submit a theme\" translate=\"no\">​</a></h2>\n<p>CSS file + preview screenshot → PR to <code>docs/static/themes/</code> → shows up in <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/themes\">/themes</a>.</p>\n<p>That's a contribution normies can do without touching Rust. Please do.</p>\n<p>Thanks for reading this series. Go break something and file an issue.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/contribute-to-amud",
            "title": "AMUD Dashboard Is Open Source — Here's How to Actually Help",
            "summary": "Stars, issues, PRs, themes, docs. Homelab projects grow from real users reporting real weird setups.",
            "date_modified": "2026-02-17T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon",
            "content_html": "<p>A homelab dashboard is a weird workload. It idles 99% of the time but still needs to poll metrics every few seconds, hold WebSocket connections, encrypt secrets, and never leak memory over months of uptime.</p>\n<p>That's systems programming territory. Not \"spin up Express and call it a day\" territory.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"why-not-node\">Why not Node<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon#why-not-node\" class=\"hash-link\" aria-label=\"Direkter Link zur Why not Node\" title=\"Direkter Link zur Why not Node\" translate=\"no\">​</a></h2>\n<p>I've run plenty of Node homelab tools. V8 heap sitting at 80–150MB for a bookmark page hurts when that box also runs Jellyfin and Sonarr. GC pauses during telemetry polling are rare but annoying when you're staring at a graph that stutters.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"why-not-go\">Why not Go<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon#why-not-go\" class=\"hash-link\" aria-label=\"Direkter Link zur Why not Go\" title=\"Direkter Link zur Why not Go\" translate=\"no\">​</a></h2>\n<p>Go would've been fine honestly. I picked Rust because I wanted memory safety without a GC, static binaries with embedded assets (<code>include_str!</code> for UI templates), and Tokio's async model for concurrent integration polls.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-stack-that-stuck\">The stack that stuck<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon#the-stack-that-stuck\" class=\"hash-link\" aria-label=\"Direkter Link zur The stack that stuck\" title=\"Direkter Link zur The stack that stuck\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>Axum</strong> — HTTP + WebSockets</li>\n<li class=\"\"><strong>rusqlite</strong> — embedded config, WAL mode</li>\n<li class=\"\"><strong>hyper + rustls</strong> — Proxmox HTTPS</li>\n<li class=\"\"><strong>hyperlocal</strong> — Docker socket</li>\n<li class=\"\"><strong>Argon2id</strong> — passwords</li>\n</ul>\n<p>Compile once, drop binary on host, run. No runtime install step.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"trade-offs-ill-admit\">Trade-offs I'll admit<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon#trade-offs-ill-admit\" class=\"hash-link\" aria-label=\"Direkter Link zur Trade-offs I'll admit\" title=\"Direkter Link zur Trade-offs I'll admit\" translate=\"no\">​</a></h2>\n<p>Rust compile times are slow. Contributor pool is smaller than JS. I occasionally fight the borrow checker at 2am.</p>\n<p>For a long-running daemon on a 256MB LXC though? I'd make the same call again.</p>\n<p>Architecture: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/ARCHITECTURE\">/docs/ARCHITECTURE</a></p>\n<p>Want to hack on it: <a href=\"https://github.com/boubli/AMUD-Dashboard\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">github.com/boubli/AMUD-Dashboard</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/why-rust-for-homelab-daemon",
            "title": "Why I Picked Rust for a Dashboard That Sits Idle All Day",
            "summary": "GC pauses, static binaries, Tokio concurrency. Developer brain dump on language choice for AMUD.",
            "date_modified": "2026-02-15T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Rust",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/portainer-deploy",
            "content_html": "<p>I live in SSH. Some of you live in Portainer. Both are valid.</p>\n<p>AMUD Dashboard deploys as a stack: <code>amud_app</code> + <code>amud_agent</code> + <code>amud_run</code> volume.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"portainer-steps\">Portainer steps<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/portainer-deploy#portainer-steps\" class=\"hash-link\" aria-label=\"Direkter Link zur Portainer steps\" title=\"Direkter Link zur Portainer steps\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\"><strong>Stacks → Add stack</strong> → name it <code>amud</code></li>\n<li class=\"\">Paste the compose from <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/installation/docker\">/docs/installation/docker</a></li>\n<li class=\"\">Set <code>AMUD_AGENT_SECRET</code> to something long and random</li>\n<li class=\"\"><strong>Same secret in both services</strong> — write it down</li>\n<li class=\"\">Deploy</li>\n</ol>\n<p>Agent needs <code>/var/run/docker.sock:ro</code> and <code>AMUD_DOCKER=1</code>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"after-deploy\">After deploy<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/portainer-deploy#after-deploy\" class=\"hash-link\" aria-label=\"Direkter Link zur After deploy\" title=\"Direkter Link zur After deploy\" translate=\"no\">​</a></h2>\n<p><code>http://your-host:8000</code> → login → change password → add cards in UI.</p>\n<p>Bind <code>./data</code> to a host path you snapshot. That's your backup.</p>\n<p>Portainer-specific notes: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/installation/portainer\">/docs/installation/portainer</a></p>\n<p>Docker path uses a bit more RAM than native Proxmox LXC. Trade-off for convenience.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/portainer-deploy",
            "title": "Deploying AMUD Dashboard Through Portainer (For Clickers Not SSHers)",
            "summary": "Stack template, matching AMUD_AGENT_SECRET, Docker socket mount. GUI homelab crowd deserves dashboards too.",
            "date_modified": "2026-02-13T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Docker",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/wall-mounted-dashboard",
            "content_html": "<p>I've got an old iPad on a desk mount running AMUD Dashboard in guest mode. Shows CPU, which lights are on, if Plex is streaming, whether the *arr stack is actually running. Wife approves because it doesn't look like a terminal.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"appearance-settings-that-matter\">Appearance settings that matter<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/wall-mounted-dashboard#appearance-settings-that-matter\" class=\"hash-link\" aria-label=\"Direkter Link zur Appearance settings that matter\" title=\"Direkter Link zur Appearance settings that matter\" translate=\"no\">​</a></h2>\n<p><strong>Settings → Appearance</strong></p>\n<ul>\n<li class=\"\"><strong>Grid columns:</strong> 4–5 on a landscape tablet</li>\n<li class=\"\"><strong>Glass opacity:</strong> lower = cleaner in bright rooms</li>\n<li class=\"\"><strong>Background:</strong> grab a 2K wallpaper from <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/themes\">/themes</a></li>\n<li class=\"\"><strong>Custom CSS:</strong> Nord or Everforest for low glare</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-to-put-on-the-board\">What to put on the board<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/wall-mounted-dashboard#what-to-put-on-the-board\" class=\"hash-link\" aria-label=\"Direkter Link zur What to put on the board\" title=\"Direkter Link zur What to put on the board\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Home Assistant card (lights + temp)</li>\n<li class=\"\">Plex/Jellyfin with live stream badge</li>\n<li class=\"\">Host CPU/RAM bars</li>\n<li class=\"\">Key services with RUNNING status</li>\n</ul>\n<p>Skip the admin controls on a shared display. Guest account.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"kiosk-browsers\">Kiosk browsers<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/wall-mounted-dashboard#kiosk-browsers\" class=\"hash-link\" aria-label=\"Direkter Link zur Kiosk browsers\" title=\"Direkter Link zur Kiosk browsers\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\"><strong>Android:</strong> Fully Kiosk Browser</li>\n<li class=\"\"><strong>iPad:</strong> Guided Access</li>\n<li class=\"\"><strong>Linux SBC:</strong> Chromium <code>--kiosk</code></li>\n</ul>\n<p>Point at your HTTPS URL (see the reverse proxy post). WebSockets need to work or the graphs lie.</p>\n<p>That's it. Old hardware, new purpose, zero YAML.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/wall-mounted-dashboard",
            "title": "Turning an Old Tablet Into a Homelab Status Board",
            "summary": "Grid density, guest mode, theme gallery wallpapers, kiosk browser tips. AMUD Dashboard was basically made for wall mounts.",
            "date_modified": "2026-02-11T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Themes"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/admin-vs-guest",
            "content_html": "<p>Put a dashboard on a kitchen wall tablet. Someone will eventually tap the wrong button.</p>\n<p>AMUD Dashboard has <strong>Admin</strong> and <strong>Guest</strong> roles. Guests get links. Admins get the keys to the kingdom.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-guests-can-do\">What guests can do<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/admin-vs-guest#what-guests-can-do\" class=\"hash-link\" aria-label=\"Direkter Link zur What guests can do\" title=\"Direkter Link zur What guests can do\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Open app URLs</li>\n<li class=\"\">See the layout you configured</li>\n<li class=\"\">Optionally see host CPU/RAM if you enable <strong>Guest system telemetry visibility</strong> under <strong>Settings → Privacy &amp; Access</strong></li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-guests-cant-do\">What guests can't do<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/admin-vs-guest#what-guests-cant-do\" class=\"hash-link\" aria-label=\"Direkter Link zur What guests can't do\" title=\"Direkter Link zur What guests can't do\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Edit cards or settings</li>\n<li class=\"\">Start/stop containers</li>\n<li class=\"\">See container names/VMIDs on sensitive telemetry</li>\n<li class=\"\">Mess with integrations</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"wall-tablet-setup\">Wall tablet setup<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/admin-vs-guest#wall-tablet-setup\" class=\"hash-link\" aria-label=\"Direkter Link zur Wall tablet setup\" title=\"Direkter Link zur Wall tablet setup\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">Create a Guest user</li>\n<li class=\"\">Enable public telemetry if you want the pretty graphs</li>\n<li class=\"\">Log the tablet into Guest</li>\n<li class=\"\">Stop worrying</li>\n</ol>\n<p>Admins keep full power controls on linked LXCs. Guests just see whether stuff is running without the big red stop button.</p>\n<p><a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/configuration\">/docs/configuration</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/admin-vs-guest",
            "title": "Guest Mode So Your Family Doesn't Stop the Plex Container",
            "summary": "Admin sees power controls. Guest sees links and optional telemetry. Kitchen tablet stays safe.",
            "date_modified": "2026-02-09T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Security"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge",
            "content_html": "<p>Top bar shows live CPU. App cards say <strong>CHECKING...</strong> forever.</p>\n<p>Welcome to the most common AMUD Dashboard support question. Good news: it's usually one of like four things.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"read-the-agent-logs-first\">Read the agent logs first<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge#read-the-agent-logs-first\" class=\"hash-link\" aria-label=\"Direkter Link zur Read the agent logs first\" title=\"Direkter Link zur Read the agent logs first\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">journalctl -u amud-agent --no-pager -n 20</span><br></div></code></pre></div></div>\n<p>Look for <code>[LXC]</code> lines:</p>\n<table><thead><tr><th>Log</th><th>Meaning</th></tr></thead><tbody><tr><td><code>PVE_API_TOKEN not set</code></td><td>Token missing from systemd env</td></tr><tr><td><code>Successfully fetched 0 containers</code></td><td>Privilege Separation still on</td></tr><tr><td><code>HTTP 401</code></td><td>Wrong token secret</td></tr><tr><td><code>HTTP 500/595</code></td><td>Bad node hostname in config</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"fix-the-token-in-systemd\">Fix the token in systemd<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge#fix-the-token-in-systemd\" class=\"hash-link\" aria-label=\"Direkter Link zur Fix the token in systemd\" title=\"Direkter Link zur Fix the token in systemd\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">nano /etc/systemd/system/amud-agent.service</span><br></div></code></pre></div></div>\n<p>Under <code>[Service]</code>:</p>\n<div class=\"language-ini codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-ini codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Environment=\"PVE_API_TOKEN=PVEAPIToken=amud@pve!amud-token=YOUR-SECRET\"</span><br></div></code></pre></div></div>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">systemctl daemon-reload &amp;&amp; systemctl restart amud-agent</span><br></div></code></pre></div></div>\n<p>Also paste the same token in the UI under <strong>Settings → Proxmox VE</strong>. Both places. Yes, redundant. Yes, necessary.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"privilege-separation\">Privilege Separation<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge#privilege-separation\" class=\"hash-link\" aria-label=\"Direkter Link zur Privilege Separation\" title=\"Direkter Link zur Privilege Separation\" translate=\"no\">​</a></h2>\n<p>When creating the API token in Proxmox, <strong>uncheck Privilege Separation</strong>. I cannot stress this enough. Spent two hours on this once. Not proud.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ctid-wrong\">CTID wrong<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge#ctid-wrong\" class=\"hash-link\" aria-label=\"Direkter Link zur CTID wrong\" title=\"Direkter Link zur CTID wrong\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">pct list</span><br></div></code></pre></div></div>\n<p>Make sure the app card ID matches reality.</p>\n<p>Full troubleshooting bible: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/troubleshooting\">/docs/troubleshooting</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/fix-checking-badge",
            "title": "Why Your App Cards Are Stuck on CHECKING...",
            "summary": "CPU bars work but LXC badges don't? It's almost always the Proxmox API token. Here's how to read agent logs and fix it.",
            "date_modified": "2026-02-07T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Proxmox",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/backup-amud-db",
            "content_html": "<p>I've seen people maintain elaborate backup scripts for YAML dashboards — git repos, env files, secret sidecars, three different paths.</p>\n<p>AMUD Dashboard backup:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">cp /opt/amud/data/amud.db ~/backups/amud-$(date +%F).db</span><br></div></code></pre></div></div>\n<p>Done. Apps, tabs, settings, users, encrypted creds (encrypted blob in DB).</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"restore\">Restore<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/backup-amud-db#restore\" class=\"hash-link\" aria-label=\"Direkter Link zur Restore\" title=\"Direkter Link zur Restore\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">Stop <code>amud-server</code></li>\n<li class=\"\">Replace <code>amud.db</code></li>\n<li class=\"\">Start <code>amud-server</code></li>\n</ol>\n<p>Your dashboard is exactly as it was. I've used this to clone a test setup to prod. Worked first try.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"dont-forget-the-keyfile\">Don't forget the keyfile<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/backup-amud-db#dont-forget-the-keyfile\" class=\"hash-link\" aria-label=\"Direkter Link zur Don't forget the keyfile\" title=\"Direkter Link zur Don't forget the keyfile\" translate=\"no\">​</a></h2>\n<p>Integrations use <code>.amud-secrets-key</code> for AES-GCM. Backup it <strong>with</strong> the database. Restore DB without key = encrypted tokens become useless noise.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"cron-it-and-forget-it\">Cron it and forget it<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/backup-amud-db#cron-it-and-forget-it\" class=\"hash-link\" aria-label=\"Direkter Link zur Cron it and forget it\" title=\"Direkter Link zur Cron it and forget it\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">0 3 * * * cp /opt/amud/data/amud.db /mnt/nas/backups/amud-$(date +\\%F).db</span><br></div></code></pre></div></div>\n<p>Keep a week of dailies. Homelab disasters always happen on the day you skipped backups.</p>\n<p>More: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/troubleshooting\">/docs/troubleshooting</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/backup-amud-db",
            "title": "Back Up Your Entire Dashboard in One File",
            "summary": "amud.db is your whole config. Copy it. Don't forget .amud-secrets-key if you use encrypted integrations.",
            "date_modified": "2026-02-05T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/bare-metal-linux-install",
            "content_html": "<p>Sometimes you have a spare NUC or mini PC that does one job: show the dashboard on a wall and nothing else.</p>\n<p>Docker on that box is overhead you don't need.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"directory-layout\">Directory layout<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/bare-metal-linux-install#directory-layout\" class=\"hash-link\" aria-label=\"Direkter Link zur Directory layout\" title=\"Direkter Link zur Directory layout\" translate=\"no\">​</a></h2>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">/opt/amud/run   → Unix socket</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">/opt/amud/data  → amud.db</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">/opt/amud/ui    → templates</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"dont-run-as-root\">Don't run as root<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/bare-metal-linux-install#dont-run-as-root\" class=\"hash-link\" aria-label=\"Direkter Link zur Don't run as root\" title=\"Direkter Link zur Don't run as root\" translate=\"no\">​</a></h2>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">sudo groupadd --system amud</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">sudo useradd --system -g amud -s /sbin/nologin amud</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">sudo mkdir -p /opt/amud/run /opt/amud/data /opt/amud/ui</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">sudo chown -R amud:amud /opt/amud</span><br></div></code></pre></div></div>\n<p>Server runs as <code>amud</code>. Agent typically needs more privileges for host metrics — see the full guide for the permission model.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"binaries\">Binaries<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/bare-metal-linux-install#binaries\" class=\"hash-link\" aria-label=\"Direkter Link zur Binaries\" title=\"Direkter Link zur Binaries\" translate=\"no\">​</a></h2>\n<p>Grab latest from <a href=\"https://github.com/boubli/AMUD-Dashboard/releases\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Releases</a>. Drop <code>amud-server</code> and <code>amud-agent</code> in <code>/usr/local/bin/</code>, set up systemd units, go.</p>\n<p>Works on Debian, Ubuntu, Fedora, Arch — anything with systemd.</p>\n<p>Full walkthrough: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/installation/linux\">/docs/installation/linux</a></p>\n<p>When I'd pick this over Proxmox LXC: dedicated dashboard hardware, no hypervisor, absolute minimum RAM.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/bare-metal-linux-install",
            "title": "Running AMUD Dashboard on Bare Metal (No Docker, No LXC)",
            "summary": "Dedicated amud system user, /opt/amud layout, systemd units. Lowest overhead if you have a spare NUC.",
            "date_modified": "2026-02-03T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr",
            "content_html": "<p>I built AMUD. I'm biased. Here's the honest comparison anyway.</p>\n<table><thead><tr><th></th><th style=\"text-align:center\">AMUD</th><th style=\"text-align:center\">Heimdall</th><th style=\"text-align:center\">Homepage</th><th style=\"text-align:center\">Homarr</th></tr></thead><tbody><tr><td>Runtime</td><td style=\"text-align:center\">Rust binary</td><td style=\"text-align:center\">PHP/Laravel</td><td style=\"text-align:center\">Node/React</td><td style=\"text-align:center\">Next.js</td></tr><tr><td>Config</td><td style=\"text-align:center\">SQLite + UI</td><td style=\"text-align:center\">DB + UI</td><td style=\"text-align:center\">YAML</td><td style=\"text-align:center\">UI + files</td></tr><tr><td>Idle RAM</td><td style=\"text-align:center\">~26–35MB (PVE native)</td><td style=\"text-align:center\">~150MB</td><td style=\"text-align:center\">varies</td><td style=\"text-align:center\">200MB+</td></tr><tr><td>Proxmox LXC control</td><td style=\"text-align:center\">native</td><td style=\"text-align:center\">no</td><td style=\"text-align:center\">widgets</td><td style=\"text-align:center\">limited</td></tr><tr><td>YAML required</td><td style=\"text-align:center\">never</td><td style=\"text-align:center\">no</td><td style=\"text-align:center\">yes</td><td style=\"text-align:center\">partial</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pick-heimdall-if\">Pick Heimdall if<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr#pick-heimdall-if\" class=\"hash-link\" aria-label=\"Direkter Link zur Pick Heimdall if\" title=\"Direkter Link zur Pick Heimdall if\" translate=\"no\">​</a></h2>\n<p>You want simple bookmarks and PHP on your server doesn't bother you. No live telemetry needed.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pick-homepage-if\">Pick Homepage if<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr#pick-homepage-if\" class=\"hash-link\" aria-label=\"Direkter Link zur Pick Homepage if\" title=\"Direkter Link zur Pick Homepage if\" translate=\"no\">​</a></h2>\n<p>You live in Git, love YAML, want the widget ecosystem. You're good at debugging indent errors. Respect.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pick-homarr-if\">Pick Homarr if<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr#pick-homarr-if\" class=\"hash-link\" aria-label=\"Direkter Link zur Pick Homarr if\" title=\"Direkter Link zur Pick Homarr if\" translate=\"no\">​</a></h2>\n<p>You want the polished drag-drop UI and don't care about RAM. *arr integration out of the box matters to you.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pick-amud-dashboard-if\">Pick AMUD Dashboard if<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr#pick-amud-dashboard-if\" class=\"hash-link\" aria-label=\"Direkter Link zur Pick AMUD Dashboard if\" title=\"Direkter Link zur Pick AMUD Dashboard if\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Proxmox is your hypervisor and you want native LXC status + power controls</li>\n<li class=\"\">You refuse to maintain YAML for a link portal</li>\n<li class=\"\">You want Plex/Jellyfin/HA/host metrics without gluing shell scripts</li>\n<li class=\"\">~26MB idle on Proxmox sounds nice</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-amud-dashboard-wont-become\">What AMUD Dashboard won't become<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr#what-amud-dashboard-wont-become\" class=\"hash-link\" aria-label=\"Direkter Link zur What AMUD Dashboard won't become\" title=\"Direkter Link zur What AMUD Dashboard won't become\" translate=\"no\">​</a></h2>\n<p>SaaS. YAML-first config. Node/PHP dependency. It's a homelab tool. Stays that way.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">curl -sSL https://raw.githubusercontent.com/boubli/AMUD-Dashboard/main/setup-amud.sh | bash</span><br></div></code></pre></div></div>\n<p><a href=\"https://github.com/boubli/AMUD-Dashboard\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub</a> · <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/themes\">Themes</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/amud-vs-heimdall-homepage-homarr",
            "title": "AMUD Dashboard vs Heimdall vs Homepage vs Homarr (I'll Be Honest)",
            "summary": "I built AMUD Dashboard so I'm biased. Here's when you'd still pick something else.",
            "date_modified": "2026-02-01T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/reverse-proxy-websockets",
            "content_html": "<p>Deployed AMUD Dashboard behind Nginx, opened the page, everything looked fine except the CPU bar was stuck at 0% like the server was dead. Server wasn't dead. Nginx just ate the WebSocket upgrade.</p>\n<p>AMUD Dashboard streams telemetry over WebSockets. Your reverse proxy <strong>must</strong> forward upgrade headers or you get a pretty but useless dashboard.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"nginx-snippet-that-actually-works\">Nginx snippet that actually works<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/reverse-proxy-websockets#nginx-snippet-that-actually-works\" class=\"hash-link\" aria-label=\"Direkter Link zur Nginx snippet that actually works\" title=\"Direkter Link zur Nginx snippet that actually works\" translate=\"no\">​</a></h2>\n<div class=\"language-nginx codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-nginx codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">location / {</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_pass http://127.0.0.1:8000;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header Host $host;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header X-Real-IP $remote_addr;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header X-Forwarded-Proto $scheme;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_http_version 1.1;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header Upgrade $http_upgrade;</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    proxy_set_header Connection \"upgrade\";</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">}</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"https-cookies\">HTTPS cookies<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/reverse-proxy-websockets#https-cookies\" class=\"hash-link\" aria-label=\"Direkter Link zur HTTPS cookies\" title=\"Direkter Link zur HTTPS cookies\" translate=\"no\">​</a></h2>\n<p>Once you're on HTTPS:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">AMUD_SECURE_COOKIES=1</span><br></div></code></pre></div></div>\n<p>Restart the server. Forget this and you'll chase phantom login bugs.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"caddy\">Caddy<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/reverse-proxy-websockets#caddy\" class=\"hash-link\" aria-label=\"Direkter Link zur Caddy\" title=\"Direkter Link zur Caddy\" translate=\"no\">​</a></h2>\n<div class=\"language-caddy codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-caddy codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">amud.homelab.local {</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    reverse_proxy localhost:8000</span><br></div><div class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">}</span><br></div></code></pre></div></div>\n<p>Usually just works. Caddy's the easy mode.</p>\n<p>Full configs: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/installation/reverse-proxy\">/docs/installation/reverse-proxy</a></p>\n<p>After setup: login works, graphs move, LXC badges update. If not, browser console first. Always browser console first.</p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/reverse-proxy-websockets",
            "title": "Putting AMUD Dashboard Behind Nginx Without Breaking Live Metrics",
            "summary": "If your CPU graphs freeze at 0%, your reverse proxy probably isn't forwarding WebSocket upgrades. Fix inside.",
            "date_modified": "2026-01-30T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Homelab",
                "Security"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard",
            "content_html": "<p>Your dashboard is a map to your entire homelab. Treat it like one.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"passwords\">Passwords<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#passwords\" class=\"hash-link\" aria-label=\"Direkter Link zur Passwords\" title=\"Direkter Link zur Passwords\" translate=\"no\">​</a></h2>\n<p><strong>Argon2id</strong> hashes in SQLite. Not SHA-256 alone, not md5 (please). Older installs with legacy SHA-256 get transparently re-hashed on next login.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"sessions\">Sessions<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#sessions\" class=\"hash-link\" aria-label=\"Direkter Link zur Sessions\" title=\"Direkter Link zur Sessions\" translate=\"no\">​</a></h2>\n<p>32-byte random tokens, 24h lifetime, <code>HttpOnly</code>, <code>SameSite=Strict</code>. Behind HTTPS set <code>AMUD_SECURE_COOKIES=1</code> or you're leaving cookies exposed on misconfigured proxies.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"brute-force\">Brute force<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#brute-force\" class=\"hash-link\" aria-label=\"Direkter Link zur Brute force\" title=\"Direkter Link zur Brute force\" translate=\"no\">​</a></h2>\n<p>5 failed logins per username in 5 minutes. Enough to stop dumb scripts, not enough to lock you out forever if you typo once.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"integration-secrets\">Integration secrets<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#integration-secrets\" class=\"hash-link\" aria-label=\"Direkter Link zur Integration secrets\" title=\"Direkter Link zur Integration secrets\" translate=\"no\">​</a></h2>\n<p>Plex tokens, Jellyfin keys, Proxmox API tokens, HA tokens — <strong>AES-GCM encrypted at rest</strong> with a host keyfile (<code>.amud-secrets-key</code>). Backup that file with your database or restores get awkward.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"csrf--csp\">CSRF + CSP<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#csrf--csp\" class=\"hash-link\" aria-label=\"Direkter Link zur CSRF + CSP\" title=\"Direkter Link zur CSRF + CSP\" translate=\"no\">​</a></h2>\n<p>State-changing requests need CSRF tokens. CSP with per-request nonces on scripts. Boring security stuff that matters when your dashboard is internet-facing behind a reverse proxy.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"production-checklist\">Production checklist<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard#production-checklist\" class=\"hash-link\" aria-label=\"Direkter Link zur Production checklist\" title=\"Direkter Link zur Production checklist\" translate=\"no\">​</a></h2>\n<ul>\n<li class=\"\">Change <code>admin</code> / <code>password</code> (seriously)</li>\n<li class=\"\">HTTPS + <code>AMUD_SECURE_COOKIES=1</code></li>\n<li class=\"\">Restricted Proxmox API user, not root</li>\n<li class=\"\">Backup <code>amud.db</code> and <code>.amud-secrets-key</code></li>\n</ul>\n<p>Full doc: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/security\">/docs/security</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/securing-homelab-dashboard",
            "title": "Securing a Dashboard That Knows Where Everything Lives",
            "summary": "Argon2id passwords, encrypted integration secrets, CSRF, rate limiting — what AMUD Dashboard actually ships with.",
            "date_modified": "2026-01-28T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Security",
                "Self-Hosted"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/twelve-free-themes",
            "content_html": "<p>The default AMUD Dashboard look is orange glass. I like it. My partner said it looked like a Cheetos-themed spaceship cockpit. Fair.</p>\n<p>So I built a <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/themes\">theme gallery</a> with twelve ready-made CSS themes and actual dashboard preview screenshots so you can pick before you paste.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"included-themes\">Included themes<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/twelve-free-themes#included-themes\" class=\"hash-link\" aria-label=\"Direkter Link zur Included themes\" title=\"Direkter Link zur Included themes\" translate=\"no\">​</a></h2>\n<p>Dracula, Nord, Catppuccin Mocha, Tokyo Night, Gruvbox Dark, Cyberpunk Neon, Solarized Dark, Rose Pine, Everforest, Monokai, One Dark, Sunset Warm.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"apply-one-in-three-clicks\">Apply one in three clicks<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/twelve-free-themes#apply-one-in-three-clicks\" class=\"hash-link\" aria-label=\"Direkter Link zur Apply one in three clicks\" title=\"Direkter Link zur Apply one in three clicks\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">Open <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/themes\">/themes</a></li>\n<li class=\"\">Hit <strong>Copy CSS</strong></li>\n<li class=\"\"><strong>Settings → Appearance → Custom CSS</strong> → paste → save</li>\n</ol>\n<p>Instant. No restart. No import-from-URL (that feature got cut on purpose — copy-paste is safer and works offline).</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"wallpapers-too\">Wallpapers too<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/twelve-free-themes#wallpapers-too\" class=\"hash-link\" aria-label=\"Direkter Link zur Wallpapers too\" title=\"Direkter Link zur Wallpapers too\" translate=\"no\">​</a></h2>\n<p>Each theme has a bundled 2K wallpaper. <strong>Copy wallpaper URL</strong> → paste into background image setting. Makes wall tablets look intentional instead of \"sysadmin panel accidentally left on.\"</p>\n<p>Broke the layout with bad CSS? Been there. Recovery guide: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/troubleshooting\">/docs/troubleshooting</a></p>\n<p>Want to roll your own? CSS variable reference: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/themes\">/docs/themes</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/twelve-free-themes",
            "title": "12 Free Themes Because Orange Glass Isn't for Everyone",
            "summary": "Copy-paste CSS from the theme gallery. Dracula, Nord, Catppuccin, Cyberpunk Neon, and eight more with preview screenshots.",
            "date_modified": "2026-01-26T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Themes",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/home-assistant-dashboard-card",
            "content_html": "<p>I had a Home Assistant card that was literally just a URL. Useful, but my wall tablet deserved better.</p>\n<p>AMUD Dashboard can show on that card:</p>\n<ul>\n<li class=\"\">How many <strong>lights</strong> are on</li>\n<li class=\"\">How many <strong>switches</strong> are on</li>\n<li class=\"\">Average home <strong>temperature</strong></li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-one-naming-rule-that-trips-people-up\">The one naming rule that trips people up<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/home-assistant-dashboard-card#the-one-naming-rule-that-trips-people-up\" class=\"hash-link\" aria-label=\"Direkter Link zur The one naming rule that trips people up\" title=\"Direkter Link zur The one naming rule that trips people up\" translate=\"no\">​</a></h2>\n<p>Your app card has to be named exactly <strong><code>Home Assistant</code></strong>. Not \"HA\" or \"homeassistant\" or \"the smart house thing.\" Exactly that string. Yes, I should make that more flexible someday. For now, that's the deal.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"setup\">Setup<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/home-assistant-dashboard-card#setup\" class=\"hash-link\" aria-label=\"Direkter Link zur Setup\" title=\"Direkter Link zur Setup\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\">HA → Profile → Long-Lived Access Tokens → create one</li>\n<li class=\"\">AMUD → <strong>Settings → Smart Home</strong> → URL + token → save</li>\n</ol>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"how-it-polls-without-being-rude-to-ha\">How it polls without being rude to HA<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/home-assistant-dashboard-card#how-it-polls-without-being-rude-to-ha\" class=\"hash-link\" aria-label=\"Direkter Link zur How it polls without being rude to HA\" title=\"Direkter Link zur How it polls without being rude to HA\" translate=\"no\">​</a></h2>\n<p>Prefers the <strong>Template API</strong> (<code>POST /api/template</code>) so HA computes counts server-side. Falls back to <code>/api/states</code> if templates aren't available. Heavier, but works.</p>\n<p>Runs on the same Tokio runtime as everything else — won't block your CPU graphs.</p>\n<p>Pair with LXC status: see the HA container is up <em>and</em> you've got four lights on at 2am. Investigate that later.</p>\n<p><a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/configuration\">/docs/configuration</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/home-assistant-dashboard-card",
            "title": "Home Assistant Stats on Your Dashboard (Not Just a Link to :8123)",
            "summary": "Name your app card Home Assistant, drop in a long-lived token, get lights/switches/temp on the card.",
            "date_modified": "2026-01-24T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Integrations",
                "Homelab"
            ]
        },
        {
            "id": "https://boubli.github.io/AMUD-Dashboard/de/blog/plex-jellyfin-live-badges",
            "content_html": "<p>\"Is anyone watching something right now or can I restart the container?\"</p>\n<p>That's the question I wanted answered from the dashboard, not from opening Plex on my phone.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"setup-boring-but-fast\">Setup (boring but fast)<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/plex-jellyfin-live-badges#setup-boring-but-fast\" class=\"hash-link\" aria-label=\"Direkter Link zur Setup (boring but fast)\" title=\"Direkter Link zur Setup (boring but fast)\" translate=\"no\">​</a></h2>\n<p><strong>Settings → Integrations</strong></p>\n<p><strong>Jellyfin:</strong> base URL + API key from Dashboard → Advanced → API Keys.</p>\n<p><strong>Plex:</strong> base URL + <code>X-Plex-Token</code>. If you've never extracted a Plex token before, welcome to the club — there's a few documented ways and they're all mildly annoying.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-the-badge-does\">What the badge does<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/plex-jellyfin-live-badges#what-the-badge-does\" class=\"hash-link\" aria-label=\"Direkter Link zur What the badge does\" title=\"Direkter Link zur What the badge does\" translate=\"no\">​</a></h2>\n<p>Starts as <strong>CHECKING...</strong>, then shows the active stream title. Multiple clients? You'll see something like <code>Dune (+2 more)</code>.</p>\n<p>Missing creds → <strong>NOT CONFIGURED</strong>. Fixable in thirty seconds once you stop procrastinating.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"why-this-pairs-well-with-lxc-status\">Why this pairs well with LXC status<a href=\"https://boubli.github.io/AMUD-Dashboard/de/blog/plex-jellyfin-live-badges#why-this-pairs-well-with-lxc-status\" class=\"hash-link\" aria-label=\"Direkter Link zur Why this pairs well with LXC status\" title=\"Direkter Link zur Why this pairs well with LXC status\" translate=\"no\">​</a></h2>\n<p>Card shows Jellyfin is <strong>RUNNING</strong> <em>and</em> someone's watching <em>Blade Runner</em>. Now you know restarting would make someone mad. That's operational awareness, not just bookmarks.</p>\n<p>API keys get <strong>AES-GCM encrypted</strong> in SQLite at rest. Not sitting in plain text in a yaml file on disk.</p>\n<p>Details: <a class=\"\" href=\"https://boubli.github.io/AMUD-Dashboard/de/docs/configuration\">/docs/configuration</a></p>",
            "url": "https://boubli.github.io/AMUD-Dashboard/de/blog/plex-jellyfin-live-badges",
            "title": "See What's Playing on Plex and Jellyfin Without Opening the App",
            "summary": "AMUD Dashboard polls /Sessions and /status/sessions in the background. Your media cards show live stream titles.",
            "date_modified": "2026-01-22T00:00:00.000Z",
            "author": {
                "name": "Youssef Boubli",
                "url": "https://github.com/boubli"
            },
            "tags": [
                "Integrations",
                "Homelab"
            ]
        }
    ]
}