Teams running OpenClaw Gateway on Docker / Compose rarely burn the most time pulling images—they burn it when restarts, upgrades, or docker compose down wipe pairing and config, or Skills directories are read-only with Permission denied spam that does not match networking entries in official troubleshooting. This article splits work with Docker networking triage, post-install doctor triage, Docker production & Gateway runbook, and unattended remote Mac operations: six volume/permission pitfalls, two tables for what to persist versus anti-patterns, a symptom→command→fix matrix, copy-paste inspect snippets, a six-step runbook, and three dashboard metrics. Triage order: volumes and UID/GID first, networking and reverse proxies second.
Images are immutable templates; only state written to the writable layer, anonymous volumes, or non-persisted paths disappears. Capture the signals below in change tickets and review them on the same line as Compose revisions and image tags.
down -v or cleanup scripts delete pairing caches even when “nothing changed in git.”user is a common failure mode.:ro for “security” blocks token caches or local state the upstream example expects; failures may be silent until restart.docker commit looks tempting but upgrades or tag changes still discard that layer—avoid for production.If networking triage still shows intermittent CLI success yet guaranteed failure after restart, return here to verify named volumes land on the expected disk and the process user can write Skills before touching network_mode or proxies.
Exact subpaths follow your image and docs; the table frames three engineering questions: survives container lifecycle, needs backup, shared read-only? Record answers in README and on-call playbooks.
| Class | Typical persisted content | Recommended pattern | Anti-pattern |
|---|---|---|---|
| Config & secrets material | Gateway endpoints, provider selection, channel token paths | Host bind or named volume; permissions scoped to runtime user | Baking into the image; storing under directories cleaned by sync tools |
| Runtime & pairing | Device pairing and session restore state | Dedicated bind subtree; tar before upgrades | Anonymous volumes not documented in Compose; single prune deletes everything |
| Skills / extensions | Team-owned skill files and scripts | Bind beside the repo; identical paths in CI and prod | :ro while runtime caches must be writable; UID cannot write |
| Logs & buffers | Large logs, exports | Separate volume or host path with rotation | Filling the writable layer until OOM or unexpected read-only FS |
While running checks, log image IDs, Compose project names, and volume names in the same shell session to simplify rollbacks; reuse the release checklist page from the production runbook.
| Symptom | Check first | Typical fix | If still failing |
|---|---|---|---|
Everything feels like a fresh install after docker compose up | docker inspect Mounts vs expected host paths; recent -v cleanup | Explicit binds or named volumes; document whether down may use -v | Verify you are in the correct Compose project directory |
| Skills ignored or writes fail | In-container id versus host ls -ln ownership | Tune user, chmod, or align UID in Dockerfile/entrypoint | Confirm mounts are not :ro |
| Streams of permission errors | SELinux/AppArmor on Linux; Docker Desktop file sharing on macOS | Linux: evaluate labels or :z against your security baseline; macOS: add paths to File Sharing | Rule out disk-level read-only before reopening networking triage |
| Half-working after an image bump | Config schema changes; legacy data dir still mounted | Follow release notes; back up before upgrade | Run openclaw doctor against documented breaking changes |
# 1) Do mounts land on the host paths you expect? (replace container)
docker inspect -f '{{ json .Mounts }}' <container> | jq .
# 2) Runtime user inside the container (compare to host ownership)
docker exec -it <container> id
# 3) Compose projects and volumes (avoid anonymous drift)
docker compose ls
docker volume ls | grep <project>
# 4) Example bind backup before upgrade (path per team convention)
tar czf openclaw-state-$(date +%Y%m%d).tgz ./openclaw-data/
Note: Docker Desktop on remote Macs usually keeps binds under user home directories; Linux cloud hosts may need different user lines and permission models. Do not assume “works on my laptop” equals “works on pooled hosts.”
down -v destroys.openclaw doctor and channel probes to avoid false negatives.Permission denied / EACCES; correlated Gateway upgrades usually indicate mounts, not providers.Plot these next to disk and log metrics from the remote Mac operations article—volume issues often show up as runaway disk or read-only mounts before CPU spikes.
Many teams colocate Gateway and Skills under one host tree in 2025–2026; without quotas on log-only subtrees, logs can fill the bind and block config writes. Fix rotation or split volumes before endlessly recreating containers.
Also distinguish docker compose restart from down/up: the former usually keeps declared volumes; the latter with cleanup flags changes data fate—use a shared verb cheat sheet in runbooks.
Single-user laptop permissions differ from pooled remote hosts with automation logins; sleep, sync utilities, and manual bind edits make “worked yesterday” non-reproducible. Operating OpenClaw as a 24/7 control plane needs contracted paths, reversible upgrades, and auditable permissions.
Learning loops on personal hardware are fine, but production cost shows up as pager noise and dead channels. Ephemeral scratch containers without stable mounts multiply failure domains during upgrades. Teams that need always-on, backup-friendly, portable Gateways usually converge faster on professional Mac cloud footprints with Apple Silicon bare metal and multi-region choice than on endlessly tweaking personal Docker setups. MACCOME offers Mac Mini M4 / M4 Pro rentals across regions plus public help docs—start with the Help Center and rates, then pick regional checkout.
Rollout tip: run table 2 checks on the same host class you will use in production (Docker Desktop vs Linux) before wiring channels and models—avoid “works locally, fails in the cloud” UID and path drift.
If you also run Kubernetes, pods recycle more often than Compose stacks: anything not backed by a PVC vanishes during rolling updates—the same explicit persistence rule applies, just verify with kubectl describe pvc and mount manifests.
FAQ
How does this differ from the Docker networking triage article?
Networking handles connectivity and namespaces; this handles whether data is on disk and writable. For install entry points see the three-platform install guide. Access and pricing: Help Center and rental rates.
Doctor or volumes first?
Volumes and permissions first, then doctor, to avoid false positives from constantly recreated containers. WSL2 specifics remain in the post-install doctor article.
How does this pair with remote Mac operations?
That article covers launchd/systemd, logs, and hang triage; this covers Docker persistence and writability. Both belong in the same change review and on-call index.