01Documentation
Hosting OpenClaw
Run OpenClaw inside a Sandbox0 sandbox when you want its gateway, workspace,
logs, and session state behind Sandbox0 lifecycle and network controls. The
openclaw template uses the upstream image. The configuration below explicitly
places OpenClaw state at /home/node/.openclaw on the writable RootFS, so
checkpointed pause/resume preserves it. Check s0 template get openclaw for
availability and the image pin in your region.
Create The Sandbox#
Set separate tokens for the Sandbox0 public route and the OpenClaw gateway:
bashexport OPENCLAW_GATEWAY_TOKEN="$(openssl rand -hex 32)" export OPENCLAW_ROUTE_TOKEN="$(openssl rand -hex 32)"
With Python 3, jq, and the CLI installed, generate a claim request on stdin.
This configures the service and route together, enables automatic wake-up,
and passes the gateway token into the service environment. Exporting a token
on your local machine alone does not pass it to a sandbox.
bashSANDBOX_ID="$( python3 - <<'PY' | s0 -o json sandbox create --config-file - | jq -er '.ID // .id' import hashlib import json import os print(json.dumps({ "template": "openclaw", "config": { "auto_resume": True, "services": [{ "id": "openclaw", "port": 18789, "runtime": { "type": "cmd", "command": ["openclaw", "gateway", "run", "--allow-unconfigured", "--auth", "token", "--bind", "lan", "--port", "18789"], "cwd": "/app", "env_vars": { "OPENCLAW_GATEWAY_TOKEN": os.environ["OPENCLAW_GATEWAY_TOKEN"], "OPENCLAW_STATE_DIR": "/home/node/.openclaw", }, }, "health_check": {"path": "/healthz"}, "ingress": {"public": True, "routes": [{ "id": "gateway", "path_prefix": "/", "resume": True, "auth": { "mode": "bearer", "bearer_token_sha256": hashlib.sha256( os.environ["OPENCLAW_ROUTE_TOKEN"].encode()).hexdigest(), }, }]}, }], }, })) PY )" s0 sandbox get "$SANDBOX_ID"
The command uses OpenClaw's foreground gateway options.
--allow-unconfigured is an initial bootstrap option; configure OpenClaw's
local gateway, model provider, and channels before using it for real work.
This example starts the gateway without configuring a model provider.
Persistence#
Files under /home/node/.openclaw use the same persistence boundary as the
rest of the writable RootFS. Pause checkpoints them; resume restores them into
the replacement runtime generation. Deleting the sandbox deletes its RootFS
state.
Create a named rootfs snapshot before deletion when you need a reusable restore point or want to claim another sandbox from the initialized OpenClaw state.
Use The Public URL#
bashexport OPENCLAW_PUBLIC_URL="$(s0 -o json sandbox service get --sandbox-id "$SANDBOX_ID" \ | jq -er '(.Services // .services)[] | select(.id == "openclaw") | .public_url')" curl -fsS "$OPENCLAW_PUBLIC_URL/healthz" \ -H "authorization: Bearer $OPENCLAW_ROUTE_TOKEN"
/healthz is OpenClaw's liveness endpoint;
it does not prove model or channel readiness. Route bearer auth is separate
from OpenClaw's own gateway authentication. WebSocket clients must supply the
route header and authenticate to OpenClaw with OPENCLAW_GATEWAY_TOKEN in
its native connection protocol. A normal browser cannot add the route bearer
header to every navigation and WebSocket handshake; put browser UI access
behind a frontend that authenticates those requests, and configure OpenClaw's
allowed origins and pairing as required.
With the default filesystem-only pause, the OpenClaw process is not retained; after resume, Sandbox0 starts the configured service command again against the restored RootFS. Explicit experimental memory pause/resume can retain supported process state instead. External clients must reconnect.