Dashy Reorg — Lessons Learned

Lessons Learned — Dashy Reorganization

What Failed and the Fix

WebFetch returns a summary, not raw YAML

Problem: WebFetch against http://home.cossaboon.net/conf.yml returned a prose
summary of the config rather than the raw YAML. Claude’s content policy prevents verbatim
reproduction of large files fetched from URLs.

Fix: Use curl via Bash instead:

curl -s http://10.10.15.11:8080/conf.yml

This bypasses WebFetch entirely and returns the raw file. Always use the internal IP to
avoid any reverse proxy / auth complications.

Catch-all sections silently accumulate cruft

Observation: Two sections — “Only @ Home” (19 items) and “Other Stuff” (12 items) —
had become dumping grounds. Neither had a clear theme. Services get added to whatever
section seems “close enough” and are never moved. After a year, the dashboard becomes
unusable.

Fix going forward: Don’t create catch-all sections. If a new service doesn’t fit an
existing section cleanly, create a new purpose-built section for it. It’s cheaper to have
more sections than to untangle a catch-all later.

Duplicate entries accumulate silently

Found duplicates:
– Prowlarr: in “Only @ Home” AND “Arr” (as “Prowlaar” — different typo)
– Komodo: in “Other Stuff” AND “Git and Docker” (as “Komogo”)
– NAS 2 SyncThing: in “TailScale items” AND “Brandon NAS”
– NAS 4 SyncThing: in “TailScale items” AND “Brandon NAS”
– Bedroom Audio: same IP as RoPieee Bedroom entry

Why it happens: When a section is added for a new theme (e.g., “TailScale items”),
old entries in other sections aren’t cleaned up. Items get added to new sections without
checking if they already exist.

Fix going forward: Before adding an item, grep the conf.yml for the IP or URL:

grep "10.10.40.2" /mnt/user/appdata/dashy/conf.yml

Wrong icons are invisible until you look

Found: DirSyncPro using a TubeSync icon, NAS units using a UGREEN icon instead of
Synology, Splunk using favicon-allesedv (meant to auto-fetch but usually shows a generic
icon), Console entries using a Google Search Console icon.

Root cause: Icon URLs were copy-pasted from similar items without checking, and icons
that “look OK” in the small icon size are hard to distinguish as wrong without zooming in.

Fix: Always source icons from https://dashboardicons.com — search by service name.
Fallback to FontAwesome (fas fa-*) for anything not in the library.

“An error occurred saving config” from the web UI (2026-07-07)

Symptom: Editing and saving via the Dashy web editor failed with the generic
An error occurred saving config. Saving via scp still worked fine.

Root cause: On save, Dashy first writes a timestamped backup to
/app/user-data/config-backups/ before overwriting conf.yml. That directory was owned
by root with mode 0755, but the container runs as non-root user node (uid 1000).
The backup write was denied, which aborts the entire save. scp deploys skipped this backup
step, so the failure stayed invisible until the editor was used. Tell-tale sign: the newest
file in config-backups/ was months old (Oct 2025) despite recent config changes.

Diagnosis (proves it in one shot):

docker exec dashy id   # -> uid=1000(node)
docker exec dashy sh -c 'touch /app/user-data/conf.yml && echo OK || echo FAIL'          # OK
docker exec dashy sh -c 'touch /app/user-data/config-backups/.w && echo OK || echo FAIL' # FAIL

Fix (unRAID-idiomatic): Normalize the tree to the unRAID standard 99:100 owner and make
the writable paths world-writable — that’s what lets the container write regardless of its uid:

ssh root@10.10.15.1 "chown -R 99:100 /mnt/user/appdata/dashy \
  && chmod 0777 /mnt/user/appdata/dashy /mnt/user/appdata/dashy/config-backups \
  && find /mnt/user/appdata/dashy -maxdepth 2 -type f -name '*.yml' -exec chmod 0666 {} +"

No restart needed. Re-run the write tests above to confirm both return OK. (Equivalently,
running unRAID’s Docker Safe New Permissions tool on the share fixes this — it sets
nobody:users + 0777/0666.)

Why not PUID/PGID: lissy93/dashy:latest is the official Node image, NOT a LinuxServer.io
image. Its Dockerfile hardcodes USER node (uid 1000) and does not honor PUID/PGID
env vars — setting them does nothing. The container always runs as uid 1000, which matches
neither root (0) nor unRAID’s nobody (99). So the only things that let it write are
(a) world-writable perms (0666/0777, ownership irrelevant), or (b) owning the files as
1000. Option (a) is preferred — it survives the unRAID New Permissions tool and matches the
rest of appdata. Mount: /mnt/user/appdata/dashy -> /app/user-data.

What Was Surprising

Dashy serves its own conf.yml over HTTP. The config file is publicly readable at
/conf.yml — no auth. This is by design (Dashy’s config editor works this way), but it
means the config (including internal IPs and service URLs) is visible to anyone on the
network who knows to look. Not a practical concern for a home network, but worth knowing.

allowConfigEdit: true with no users set — the dashboard is fully editable by anyone
who opens it. Since guest access is disabled but no users are defined, the auth system is
effectively inert. If you ever want to lock down the config editor, you need to add at least
one user entry to the auth.users list.

Dashy hot-reloads without a restart. Writing a new conf.yml takes effect within
a few seconds — no docker restart needed. This made iterating fast.

Correct Step-by-Step Workflow for Future Dashy Config Work

  1. Pull the live config:
    bash
    curl -s http://10.10.15.11:8080/conf.yml > ~/Documents/Coding/Container\ Managment/dashy-conf.yml
  2. Audit for issues (grep is your friend):
    bash
    # Find duplicates by IP
    grep -oP 'url: http://\K[^/]+' dashy-conf.yml | sort | uniq -d
    # Find items with no icon
    grep -B2 'url:' dashy-conf.yml | grep -v icon
  3. Edit locally — never edit the live file directly on the server.
  4. Validate YAML before deploying:
    bash
    python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" dashy-conf.yml && echo "Valid"
  5. Backup live config:
    bash
    ssh root@10.10.15.1 "cp /mnt/user/appdata/dashy/conf.yml /mnt/user/appdata/dashy/conf.yml.bak.$(date +%Y%m%d_%H%M%S)"
  6. Deploy:
    bash
    scp "/Users/kcossabo/Documents/Coding/Container Managment/dashy-conf.yml" \
    root@10.10.15.1:/mnt/user/appdata/dashy/conf.yml
  7. Verify — open http://home.cossaboon.net and check that sections and icons look right.
    Dashy hot-reloads within ~5 seconds.
  8. Rollback if needed:
    bash
    ssh root@10.10.15.1 "cp /mnt/user/appdata/dashy/conf.yml.bak.<timestamp> /mnt/user/appdata/dashy/conf.yml"

Recurring Maintenance Notes

  • When adding a new container: add it to the relevant Dashy section at the same time.
    Don’t let it accumulate in a catch-all. Pick the right section from the table in index.md.
  • When removing a container: grep the conf.yml for its IP/URL and remove the entry.
  • Icon CDN: https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/<name>.png
    — check dashboardicons.com for the exact filename before guessing.
  • The local working copy lives at ~/Documents/Coding/Container Managment/dashy-conf.yml
    on the Mac. Keep it in sync with the live file if making manual edits on the server.

About the Author

Kevin Cossaboon

A networking profesional located in Northren Virginia, USA. My hobbies are Technology and Photography. Love playing with the latest technology, and will try to post reviews of them. Also love my life long journey of learning to capture light, to trigger emotions, through photography.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.