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.
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.
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
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.
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.
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.
bash
curl -s http://10.10.15.11:8080/conf.yml > ~/Documents/Coding/Container\ Managment/dashy-conf.yml
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
bash
python3 -c "import yaml, sys; yaml.safe_load(open(sys.argv[1]))" dashy-conf.yml && echo "Valid"
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)"
bash
scp "/Users/kcossabo/Documents/Coding/Container Managment/dashy-conf.yml" \
root@10.10.15.1:/mnt/user/appdata/dashy/conf.yml
bash
ssh root@10.10.15.1 "cp /mnt/user/appdata/dashy/conf.yml.bak.<timestamp> /mnt/user/appdata/dashy/conf.yml"
https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/png/<name>.png~/Documents/Coding/Container Managment/dashy-conf.yml