2026-07-16 Docker Services Down After Docker Desktop Restart
What I set out to do
Figure out why every Docker service on atlas (media stack, SigNoz, Open WebUI, SillyTavern) was stopped.
What I actually did
Traced the outage to a single event: Docker Desktop on atlas did a full quit-and-relaunch at 7:14 AM. Its graceful shutdown stopped every container in the same second (SIGTERM, SIGKILL for slow stoppers like ClickHouse), and since all containers use the unless-stopped restart policy, a graceful stop marks them “stopped” and the policy deliberately does not resurrect them when the daemon comes back. restart: always would have.
A detour worth remembering: docker ps -a claimed the containers exited “32 minutes ago” when the real stop was 11 hours earlier. The Docker Desktop Linux VM’s clock lags after Mac sleep, so container timestamps were off by ~10.5 hours.
Restored everything with hm switch, which brought back the media stack and Open WebUI via their activation hooks (the recent autoStart = true change in the media-stack module). SigNoz, SillyTavern, and watchtower needed manual docker compose up -d / docker start: their modules only sync config at activation and only up when the config hash changed and the stack is already running. All 20 containers verified healthy afterwards.
What was striking
The new media-stack autoStart is not a daemon-restart safety net: it only fires at home-manager switch time. After any Docker Desktop restart, the recovery command is hm switch plus manual ups for SigNoz/SillyTavern/watchtower. If unattended recovery matters, the fix is restart: always on the compose services.
Also: the SigNoz terraform reconcile was skipped during the switch because SigNoz was down at that moment; the next hm switch will reconcile normally.
Related
2026-07-16 Superpowers Plugin Evaluation Research
Follow-up: autoStart landed for SigNoz and SillyTavern (dace539)
Closed the gap the same day. programs.signoz.autoStart (daemon-guarded plain up -d in syncSigNoz, never --force-recreate so ClickHouse is untouched; reconcile health poll extended 60s to 120s for the cold-start path) and programs.sillytavern.autoStart (wired to mkComposeDeploy’s existing ensureRunning knob, the Open WebUI model). Both default true. Verified end-to-end: stopped both stacks, ran hm switch, both resurrected and the terraform reconcile applied cleanly through the cold start. hm switch is now the single recovery command for everything except watchtower, which no module owns. Unattended recovery (no switch at all) would still need restart: always or a supervised unit, the direction 2026-07-14 Runtime State Reconciliation Framework already points.
Follow-up 2: watchtower declared as a module (9cfd2cd)
Watchtower turned out to have unless-stopped like everything else; it stayed down for the same graceful-stop reason, but was the one container no module owned (hand-run docker run from 2026-07-01). Folded it into watchtower.nix via mkComposeDeploy with autoStart, preserving its exact runtime config (daily 04:00 schedule, --cleanup, docker.sock bind). Migration required docker rm -f on the old container since it held the name.
Design catch worth remembering: compose derives the project name from the compose file’s directory, so SillyTavern (which passes its compose file straight from /nix/store) is in a project literally named store. A second store-path stack would share that project, and up --remove-orphans would delete the neighbor’s containers as orphans. Watchtower’s compose file is therefore copied into ~/.local/share/watchtower (the Open WebUI model). SillyTavern still sits in project store; harmless while it’s alone there, but a candidate for the same treatment.
With this, hm switch resurrects the entire fleet: media stack, Open WebUI, SigNoz, SillyTavern, and watchtower. Nothing manual remains.
Follow-up 3: SillyTavern out of project store (859eac7)
Closed the candidate flagged in follow-up 2: SillyTavern’s compose file is now copied into ~/.local/share/sillytavern like the others, so its compose project is sillytavern instead of store. Live migration was down-old-project, hm switch recreates under the new one; UI verified back at HTTP 200. No stack runs from /nix/store anymore, so the shared-project orphan-delete hazard is gone for good.