Gateway deployment
OpenClaw supports containerized deployments (Docker, multi-stage builds), managed platforms (Fly.io, Render), and native daemon supervision (launchd/systemd). Restart sentinels coordinate handoff across restarts. Tailscale provides secure exposure.
Docker
The Dockerfile produces a minimal runtime image using a multi-stage build with pinned Node 24 bookworm and Bun images. Build stages extract only package manifests first. The runtime stage is based on node:24-bookworm-slim and runs as the non-root node user (uid 1000).
Optional build args include:
OPENCLAW_INSTALL_BROWSER=1(installs Chromium + Xvfb)OPENCLAW_INSTALL_DOCKER_CLI=1(installs Docker CLI without daemon)OPENCLAW_EXTENSIONS(selects bundled plugins)OPENCLAW_IMAGE_APT_PACKAGES/OPENCLAW_IMAGE_PIP_PACKAGES
The image pre-creates owned directories under /home/node/.openclaw and /home/node/.config/openclaw. tini is the entrypoint; the default command is node openclaw.mjs gateway.
Built-in probes are GET /healthz (liveness) and GET /readyz (readiness). The healthcheck uses the loopback probe. Security settings drop NET_RAW/NET_ADMIN, set no-new-privileges, and apply cap_drop.
node dist/index.js gateway --bind lan --port 18789
Docker bridge networking with the default loopback bind makes the gateway unreachable from the host. Use --bind lan (or --network host) and configure auth when exposing from the container.
docker-compose
docker-compose.yml defines two services: openclaw-gateway (the main server, default image openclaw:local) and openclaw-cli (shares the gateway network).
Environment variables pin container paths (OPENCLAW_STATE_DIR, OPENCLAW_CONFIG_*, OPENCLAW_WORKSPACE_DIR). Volumes mount host ~/.openclaw (and optional auth-profile secrets). Default ports are 18789 (gateway), 18790 (bridge), and 3978 (msteams).
docker compose up -d
Use OPENCLAW_IMAGE to override the image tag. The CLI service inherits the gateway network and overrides the entrypoint. Both services use init: true, restart: unless-stopped, the internal /healthz probe, cap_drop: [NET_RAW, NET_ADMIN], security_opt: [no-new-privileges:true], and extra_hosts for host.docker.internal.
Fly.io
fly.toml configures a Fly.io deployment with app = "openclaw" (primary region iad by default). Environment includes NODE_ENV=production, OPENCLAW_PREFER_PNPM=1, OPENCLAW_STATE_DIR=/data, and NODE_OPTIONS=--max-old-space-size=1536.
The process runs node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan. HTTP service uses internal port 3000 with force HTTPS and auto_stop_machines=false. VM is shared-cpu-2x with 2048 MB and a persistent volume mounted at /data.
fly deploy
Render
render.yaml defines a web service (type web, runtime docker, plan starter) with healthCheckPath: /health. Environment variables include OPENCLAW_GATEWAY_PORT=8080, OPENCLAW_STATE_DIR=/data/.openclaw, OPENCLAW_WORKSPACE_DIR=/data/workspace, and OPENCLAW_GATEWAY_TOKEN (auto-generated). A 1 GB disk named openclaw-data is mounted at /data.
Daemon installation (launchd / systemd)
Install via the CLI:
openclaw onboard --install-daemon
This installs a user-level service (launchd on macOS, systemd on Linux) so the gateway stays running. Foreground/debug mode uses openclaw gateway --port 18789 --verbose. Check status with openclaw gateway status and stop with openclaw gateway stop.
The daemon runs the gateway with the user's config and workspace. Onboarding also sets up the recommended local-first layout.
Restart sentinels
Restart sentinels coordinate graceful handoff. They are written on update/restart requests (gateway.restart.* methods) and contain session key, delivery context, thread id, continuation message, and update stats.
On next startup the gateway reads the sentinel, emits a system event / wake, and can resume delivery or post-update messaging. sigusr1 triggers a controlled restart. Managed-service handoff (systemd/launchd) uses a detached helper. Last-known-good config and restart-sentinel refresh occur during post-ready sidecars.
Tailscale exposure
Tailscale configuration lives under gateway.tailscale:
mode:off(default),serve, orfunnel.- Serve/funnel require
gateway.bind=loopback(127.0.0.1) andgateway.auth.mode=password. - Funnel additionally requires password auth.
MagicDNS is used for hostnames; the gateway advertises the Tailscale address when enabled. Loopback bind is mandatory for serve/funnel modes; non-loopback binds are rejected when Tailscale exposure is active. Identity-bearing Tailscale connects can satisfy auth via headers when gateway.auth.allowTailscale is set.
Use gateway.tailscale together with the bind and auth settings. Before exposing, review the security and exposure runbooks.
Additional notes
- Nix users: see the separate nix-openclaw repository for declarative packaging.
- All container and daemon modes respect the same
~/.openclaw/openclaw.json(orOPENCLAW_CONFIG_PATH) and workspace layout. - Health and readiness probes are available on the gateway HTTP port for orchestration systems.
See Configuration for gateway.* settings and Linux server for VPS-specific tuning.