setupCommand (one-time container setup)
The one-time container setup hook, where it is configured, and its common pitfalls
The hook that runs once after a sandbox container is created, and the defaults that most often make it fail.
setupCommand (one-time container setup)
setupCommand runs once after the sandbox container is created (not on every run). It executes inside the container via sh -lc.
If access is revoked before setup completes, OpenClaw retains the container and its saved data for inspection. Later requests reject that incomplete container instead of restarting it or replaying setup. Preserve any needed container data before explicitly recreating the sandbox.
Paths:
- Global:
agents.defaults.sandbox.docker.setupCommand - Per-agent:
agents.entries.*.sandbox.docker.setupCommand
Common pitfalls
- Default
docker.networkis"none"(no egress), so package installs will fail. docker.network: "container:<id>"requiresdangerouslyAllowContainerNamespaceJoin: trueand is break-glass only.readOnlyRoot: trueprevents writes; setreadOnlyRoot: falseor bake a custom image.usermust be root for package installs. Docker can omituseror setuser: "0:0"; rootful Podman must setuser: "0:0"because its default preserves workspace ownership. Rootless Podman rejects zero-valued users; bake packages into the image or use rootful Podman.- Sandbox exec does not inherit host
process.env. Useagents.defaults.sandbox.docker.env(or a custom image) for skill API keys. - Values in
agents.defaults.sandbox.docker.envremain visible through container metadata commands such asdocker inspectorpodman inspect. Docker and Podman require portable environment names and single-line, non-NUL values because secure engine environment files are line-delimited; config validation andopenclaw doctorreject invalid entries before sandbox use. Rename invalid keys, use single-line values, or deliver multiline material through a mounted file or custom image; this requires manual remediation becausedoctor --fixcannot safely preserve the original value. SSH and OpenShell backends still support multiline values. Use a custom image, mounted secret file, or another secret delivery path if metadata exposure is not acceptable.