Docker
Docker (optional)
Docker is optional. Use it only if you want a containerized gateway or to validate the Docker flow.
Is Docker right for me?
- Yes: you want an isolated, throwaway gateway environment or to run RemoteClaw on a host without local installs.
- No: you are running on your own machine and just want the fastest dev loop. Use the normal install flow instead.
- Sandboxing note: agent sandboxing uses Docker too, but it does not require the full gateway to run in Docker. See Sandboxing.
Prerequisites
- Docker Desktop (or Docker Engine) + Docker Compose v2
- At least 2 GB RAM for image build (
pnpm installmay be OOM-killed on 1 GB hosts with exit 137) - Enough disk for images and logs
- If running on a VPS/public host, review
Security hardening for network exposure,
especially Docker
DOCKER-USERfirewall policy.
Containerized Gateway
```bash./scripts/docker/setup.sh```
This builds the gateway image locally. To use a pre-built image instead:
```bashexport REMOTECLAW_IMAGE="ghcr.io/remoteclaw/remoteclaw:latest"./scripts/docker/setup.sh```
Pre-built images are published at the[GitHub Container Registry](https://github.com/remoteclaw/remoteclaw/pkgs/container/remoteclaw).Common tags: `main`, `latest`, `<version>` (e.g. `2026.2.26`).- prompt for provider API keys- generate a gateway token and write it to `.env`- start the gateway via Docker ComposeNeed the URL again?
```bashdocker compose run --rm remoteclaw-cli dashboard --no-open``````bash# WhatsApp (QR)docker compose run --rm remoteclaw-cli channels login
# Telegramdocker compose run --rm remoteclaw-cli channels add --channel telegram --token "<token>"
# Discorddocker compose run --rm remoteclaw-cli channels add --channel discord --token "<token>"```
Docs: [WhatsApp](/channels/whatsapp), [Telegram](/channels/telegram), [Discord](/channels/discord)Manual flow
If you prefer to run each step yourself instead of using the setup script:
docker build -t remoteclaw:local -f Dockerfile .docker compose run --rm remoteclaw-cli onboarddocker compose up -d remoteclaw-gatewayEnvironment variables
The setup script accepts these optional environment variables:
| Variable | Purpose |
|---|---|
REMOTECLAW_IMAGE | Use a remote image instead of building locally |
REMOTECLAW_DOCKER_APT_PACKAGES | Install extra apt packages during build (space-separated) |
REMOTECLAW_EXTENSIONS | Pre-install extension deps at build time (space-separated names) |
REMOTECLAW_EXTRA_MOUNTS | Extra host bind mounts (comma-separated source:target[:opts]) |
REMOTECLAW_HOME_VOLUME | Persist /home/node in a named Docker volume |
REMOTECLAW_SANDBOX | Opt in to sandbox bootstrap (1, true, yes, on) |
REMOTECLAW_DOCKER_SOCKET | Override Docker socket path |
Health checks
Container probe endpoints (no auth required):
curl -fsS http://127.0.0.1:18789/healthz # livenesscurl -fsS http://127.0.0.1:18789/readyz # readinessThe Docker image includes a built-in HEALTHCHECK that pings /healthz.
If checks keep failing, Docker marks the container as unhealthy and
orchestration systems can restart or replace it.
Authenticated deep health snapshot:
docker compose exec remoteclaw-gateway node dist/index.js health --token "$REMOTECLAW_GATEWAY_TOKEN"LAN vs loopback
scripts/docker/setup.sh defaults REMOTECLAW_GATEWAY_BIND=lan so host access to
http://127.0.0.1:18789 works with Docker port publishing.
lan(default): host browser and host CLI can reach the published gateway port.loopback: only processes inside the container network namespace can reach the gateway directly.
Storage and persistence
Docker Compose bind-mounts REMOTECLAW_CONFIG_DIR to /home/node/.remoteclaw and
REMOTECLAW_WORKSPACE_DIR to /home/node/.remoteclaw/workspace, so those paths
survive container replacement.
For full persistence details on VM deployments, see Docker VM Runtime - What persists where.
Disk growth hotspots: watch media/, session JSONL files, cron/runs/*.jsonl,
and rolling file logs under /tmp/remoteclaw/.
Shell helpers (optional)
For easier day-to-day Docker management, install ClawDock:
mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/remoteclaw/remoteclaw/main/scripts/shell-helpers/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.shecho 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrcThen use clawdock-start, clawdock-stop, clawdock-dashboard, etc. Run
clawdock-help for all commands.
See the ClawDock Helper README.
Custom socket path (e.g. rootless Docker):
```bashexport REMOTECLAW_SANDBOX=1export REMOTECLAW_DOCKER_SOCKET=/run/user/1000/docker.sock./scripts/docker/setup.sh```
The script mounts `docker.sock` only after sandbox prerequisites pass. Ifsandbox setup cannot complete, the script resets `agents.defaults.sandbox.mode`to `off`.```bashdocker compose run -T --rm remoteclaw-cli gateway probedocker compose run -T --rm remoteclaw-cli devices list --json``````bashsudo chown -R 1000:1000 /path/to/remoteclaw-config /path/to/remoteclaw-workspace``````dockerfileFROM node:24-bookwormRUN curl -fsSL https://bun.sh/install | bashENV PATH="/root/.bun/bin:${PATH}"RUN corepack enableWORKDIR /appCOPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./COPY ui/package.json ./ui/package.jsonCOPY scripts ./scriptsRUN pnpm install --frozen-lockfileCOPY . .RUN pnpm buildRUN pnpm ui:installRUN pnpm ui:buildENV NODE_ENV=productionCMD ["node","dist/index.js"]```1. **Persist `/home/node`**: `export REMOTECLAW_HOME_VOLUME="remoteclaw_home"`2. **Bake system deps**: `export REMOTECLAW_DOCKER_APT_PACKAGES="git curl jq"`3. **Install Playwright browsers**: ```bash docker compose run --rm remoteclaw-cli \ node /app/node_modules/playwright-core/cli.js install chromium ```4. **Persist browser downloads**: set `PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` and use `REMOTECLAW_HOME_VOLUME` or `REMOTECLAW_EXTRA_MOUNTS`.Running on a VPS?
See Hetzner (Docker VPS) and Docker VM Runtime for shared VM deployment steps including binary baking, persistence, and updates.
Agent Sandbox
When agents.defaults.sandbox is enabled, the gateway runs agent tool execution
(shell, file read/write, etc.) inside isolated Docker containers while the
gateway itself stays on the host. This gives you a hard wall around untrusted or
multi-tenant agent sessions without containerizing the entire gateway.
Sandbox scope can be per-agent (default), per-session, or shared. Each scope
gets its own workspace mounted at /workspace. You can also configure
allow/deny tool policies, network isolation, resource limits, and browser
containers.
For full configuration, images, security notes, and multi-agent profiles, see:
- Sandboxing — complete sandbox reference
- OpenShell — interactive shell access to sandbox containers
- Multi-Agent Sandbox and Tools — per-agent overrides
Quick enable
{ agents: { defaults: { sandbox: { mode: "non-main", // off | non-main | all scope: "agent", // session | agent | shared }, }, },}Build the default sandbox image:
scripts/sandbox-setup.shTroubleshooting
```bashdocker compose run --rm remoteclaw-cli dashboard --no-opendocker compose run --rm remoteclaw-cli devices listdocker compose run --rm remoteclaw-cli devices approve <requestId>```
More detail: [Dashboard](/web/dashboard), [Devices](/cli/devices).```bashdocker compose run --rm remoteclaw-cli config set gateway.mode localdocker compose run --rm remoteclaw-cli config set gateway.bind landocker compose run --rm remoteclaw-cli devices list --url ws://127.0.0.1:18789```