Single-file bind mounts pin the container to that file's inode at mount time. sed -i and most editors write-then-rename (atomic write), which swaps in a new inode at the same path -- the container kept reading the orphaned original and never saw edits, silently breaking the hot-reload from the previous commit. Caught by actually testing the reload live instead of trusting the code. Directory mounts resolve paths dynamically and don't have this problem. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1.9 KiB
Editing monitored hosts without a redeploy
config/hosts.yaml's sshHosts and knownDevices lists are re-read on the next poll
cycle (checks the file's mtime, reloads if changed) — no container restart needed.
- Proxmox-monitored hosts (the node + every LXC) need no config at all — they're auto-discovered from the Proxmox API on every poll already.
- SSH-monitored hosts (
sshHosts): editconfig/hosts.yamlon the deploy host directly (/opt/homelab-monitor/config/hosts.yamlon CT122), save, wait up to one poll interval (POLL_INTERVAL_SECONDS, default 30s). Adding a new SSH host still needs a one-time manual step first — installing the forced-command key on the target (seedocs/ssh-collector-key-setup.md) — that part can't be automated away, so a web form wouldn't make this fully self-service regardless of hot-reload. knownDevices(device discovery labeling): same file, same reload path, no manual step needed since it's just a label list.
If the file fails to parse (bad YAML), the error is logged and the previous in-memory config keeps running rather than crashing the poller.
Gotcha that broke this on first deploy
docker-compose.yml originally bind-mounted the single file
(./config/hosts.yaml:/app/config/hosts.yaml:ro). Single-file bind mounts pin the
container to that file's inode at mount time. sed -i, most text editors, and any
tool that does an atomic write (write to a temp file, then rename() over the
original — the common safe-write pattern) swap in a new inode at the same path. The
container kept reading the original (now-orphaned) inode and never saw edits made this
way, no matter how long you waited for the next poll cycle. Fixed by mounting the
directory instead (./config:/app/config:ro), which resolves paths dynamically
rather than pinning to a specific inode. Confirmed via docker exec ... stat showing a
stale mtime that didn't match the host file before this fix.