- config.yml: default/commit -> frank-medium (dankserver); task/tiny/smol/vision -> frank-small (dankclaw-3090); vision xhigh - models.yml: add llamacpp (dankclaw-3090) provider; frank-large preserve_thinking + context notes - niri: focus-ring/border/shadow layout, hot-corners off, re-add noctalia.kdl include; blankpad eDP-1 scale 1.0 - memories: flush rollouts; retire frank_large + marreta_authentik skills; add auth-chain/kv-pool/quadlet-log skills - managed-skills: 40+ new fleet runbook skills - agent/skills: import built-in skill set
3.7 KiB
name, description
| name | description |
|---|---|
| container-config-drift-crashloop | Diagnose a container that crash-loops or stays unhealthy while its compose/unit definition looks correct: config drift kept alive by a restart policy, with the inspect commands, the Devices-vs-CreateCommand false negative, and the compose-to-Quadlet migration order. |
A container that restarts forever while its definition is correct
When to use
A container is crash-looping or perpetually "unhealthy", but the file that defines it (compose service, unit, deploy script) looks right. Also when a service has been quietly down for days and nobody noticed, because a restart policy kept something running.
The cause is usually config drift: the running container was created from an older definition, and the restart policy restarts it instead of recreating it. A compose/unit edit does not touch an existing container.
Diagnose (5 minutes, in this order)
-
Who started it? The label names the owner, not your guesswork:
podman inspect <name> --format 'unit={{index .Config.Labels "PODMAN_SYSTEMD_UNIT"}} restart={{.HostConfig.RestartPolicy.Name}} created={{.Created}}'podman-compose@…means compose owns it, whatever unit files exist. Comparecreatedwith when the definition last changed. A container older than the edit that should have replaced it is the bug. -
What is it ACTUALLY running? Read the argv, not the summary fields:
podman inspect <name> --format '{{.Config.CreateCommand}}'Trap:
{{.HostConfig.Devices}}prints an empty list even when--deviceflags are present — a false negative that can send you hunting the wrong root cause.CreateCommandis the truth; grep it for the flag you care about (--device,--group-add,-e, mounts). -
What does the process say?
podman logs <name> | grep -iE 'error|cannot|Runtime'. A capability error (No HIP GPUs are available) alongside a missing device flag in step 2 confirms drift rather than a code or image fault. Count the damage:podman inspect --format '{{.RestartCount}}'.
Fix
Quickest unblock: recreate from the definition (podman compose up -d --force-recreate <svc>), which is what should have happened automatically.
Durable fix, when the host is governed by a repo that requires boot-persistent units (this one does): migrate the service to a Quadlet. Order that worked:
- build the image and
installthe unit file to~/.config/containers/systemd/ - stop/disable the legacy unit and move its file to
~/.AGENTTRASH/— a leftover~/.config/systemd/user/<svc>.servicecollides by name with the unit the Quadlet generator produces podman rm -f <container>— the stale container holds the name the unit's container needs, and it carries the old configsystemctl --user daemon-reload && systemctl --user restart <svc>.service- delete the compose service so only one owner remains per container name
Verify the capability, not the status
Up and even healthy can be true of a half-configured container. Check the
thing that was broken, from inside:
podman exec <name> python3 -c "import torch; print(torch.cuda.is_available())"
ss -ltn | grep <port> # confirm the bind addresses, not the intent
And confirm boot persistence the way the generator exposes it:
systemctl --user is-enabled <svc>.service → generated is healthy; an
explicit enable fails on generated units.
Related reading in this repo
- AGENTS.md "Boot Persistence & Self-Healing" — the rule this enforces
serverAppConfigs-docs/Dankclaw/ComfyUI.md— the 9,146-restart incidentserverAppConfigs-docs/Infrastructure/Observability.md— same class, twice