Running OpenClaw with container-backed tooling means the Gateway must agree with the host on which OCI runtime answers docker or podman calls, where repositories and caches live, and how skills pull dependencies. The --container switch and OPENCLAW_CONTAINER should tell the same story in every shell, Compose service, and CI row; when they diverge, you get flaky “works on my laptop” failures. This runbook orders mode → socket → mounts → skill installs → doctor, then sketches a high-RAM remote Mac Gateway away from CI churn. For native versus Compose layouts first, see
OpenClaw remote Mac deployment: install paths, Docker vs native daemons, and workflow sketches.
1. One source of truth for --container and OPENCLAW_CONTAINER
Pick one authority per environment: bake OPENCLAW_CONTAINER=true into Compose and treat the CLI flag as optional, or standardise on explicit flags in CI and forbid silent shell exports. Document the choice so on-call engineers do not flip both independently. In GitHub Actions or Buildkite, print the resolved pair at job start and fail fast when they disagree. That visibility prevents subtle bugs where a developer shell enables container mode while a systemd unit does not, leaving half the toolchain on the host PATH.
2. Docker versus Podman: sockets, contexts, and CLI passthrough
Mount the correct control socket and set DOCKER_HOST (or Podman’s equivalent) to match. Docker Desktop on macOS often exposes /var/run/docker.sock through a VM bridge; rootless Podman uses a user-scoped socket that differs by distro. Verify the CLI inside the image talks to that socket—mixing a Podman client with a Docker daemon yields confusing “connection refused” errors. Prefer two Compose profiles instead of symlinked sockets. After any socket move, run info or version from the same network namespace the Gateway uses.
3. Bind mounts: workspace, config, caches, and read-only policy
Mount workspace and state with explicit host paths that exist before up. Keep policy files read-only where practical so plugins cannot rewrite openclaw.json. Split ephemeral caches from durable queues so prune jobs do not delete in-flight work. Align UID and GID with the container user; macOS bind mounts differ from Linux CI, so document numeric IDs you tested. When checkouts rotate, update Compose paths together—stale binds top the ENOENT list during skills.
4. Skill dependency installs: image-first, then idempotent setupCommand
Bake heavy dependencies into the image so cold starts stay seconds. Reserve setupCommand for semver-pinned, idempotent steps—checksum verify or tarball unpack—not interactive prompts or chained cd tied to a home layout. Log toolchain versions after setup for quick diffs. Put native compilers in the same image layer as matching headers; mixing packages across restarts creates linker errors that masquerade as OpenClaw bugs. Centralise shared runtime installs to dedupe downloads.
5. doctor as a cross-check, not a random button
Run doctor only after mounts and sockets are stable. Compare results to launchd or Compose logs, listeners, and routes in order: permissions, engine reachability, Gateway binds, plugins, then proxies. Save stdout to the ticket. Fix duplicate routes or container-mode mismatches before raising log verbosity. For long-lived Gateway stability on macOS, read
OpenClaw Gateway launchd stability: doctor, status, logs, and port binding.
- Does
OPENCLAW_CONTAINERmatch the CLI flag in every unit file? - Is the mounted socket the same one your smoke test used?
- Are skill install scripts idempotent across container restarts?
6. Example: remote high-memory Mac as an isolated Gateway
Provision a dedicated high-RAM Mac over SSH or a tailnet; install Compose, monitoring, and log shipping only—label self-hosted runners elsewhere so PR bursts never starve the Gateway. Use fast NVMe for layers and skill caches, pin Node and engines to production, snapshot after green doctor runs, restrict inbound ports to mesh or bastion, rotate deploy keys with CI secrets, and restart weekly in a window to clear leaked descriptors. You trade colocation with build farms for predictable latency to channels and MCP backends.
Why a Mac mini-class node still wins for this Gateway pattern
Container passthrough is only half the story—you still want a host that sips power, stays quiet, and survives months unattended. Apple Silicon Mac mini systems pair memory bandwidth with macOS’s Unix stack, Gatekeeper, SIP, and FileVault, which beats a generic tower under a desk for unattended Gateways. Idle draw stays low while SSH and engine sockets stay up; GPU and Neural Engine remain ready if you add on-device inference. Skipping sleep-prone laptops cuts support noise and total cost of ownership. If you want that isolated high-memory footprint without rack gear, open the Macstripe home page, pick a nearby region, and choose a Mac mini M4 with the RAM your Gateway needs—solid hardware is the fastest way to keep doctor green after every restart.