Deployment

OpenClaw supports containerized deployments, managed platforms, and native daemon supervision. Restart sentinels coordinate graceful handoff across restarts. Tailscale provides secure remote exposure options.

Docker

The Dockerfile produces a minimal runtime image based on node:24-bookworm-slim. It uses a multi-stage build, runs as the non-root node user, and includes tini as the entrypoint. The default command is node openclaw.mjs gateway.

Optional build args:

  • OPENCLAW_INSTALL_BROWSER=1 — installs Chromium + Xvfb
  • OPENCLAW_INSTALL_DOCKER_CLI=1 — installs the Docker CLI (no daemon)
  • OPENCLAW_EXTENSIONS — selects bundled plugins at build time

Pre-created directories include /home/node/.openclaw and /home/node/.config/openclaw. Built-in probes are GET /healthz (liveness) and GET /readyz (readiness).

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 an openclaw-gateway service (builds from . by default) and an openclaw-cli service that shares the network.

Key environment variables pin container paths:

  • OPENCLAW_STATE_DIR
  • OPENCLAW_CONFIG_*
  • OPENCLAW_WORKSPACE_DIR

Run the stack with:

docker compose up -d

Override the image with OPENCLAW_IMAGE. Ports default to 18789 (gateway), 18790 (bridge), and 3978 (msteams). The compose file sets init: true, restart: unless-stopped, and a healthcheck against the internal /healthz probe. It also drops NET_RAW and NET_ADMIN capabilities.

Fly.io

fly.toml configures a Fly.io app (default name openclaw, region iad). It uses the local Dockerfile, sets NODE_ENV=production, pins state to /data, and runs:

node dist/index.js gateway --allow-unconfigured --port 3000 --bind lan

Deploy with:

fly deploy

A persistent volume at /data survives deploys. The HTTP service listens on internal port 3000 with auto_stop_machines=false.

Render

render.yaml defines a web service using the Docker runtime. It sets OPENCLAW_GATEWAY_PORT=8080, OPENCLAW_STATE_DIR=/data/.openclaw, and OPENCLAW_WORKSPACE_DIR=/data/workspace. A 1 GB disk is mounted at /data. The service uses the built-in /health probe.

Daemon installation (launchd / systemd)

Install a user-level service with the recommended first-run command:

openclaw onboard --install-daemon

This sets up launchd (macOS) or systemd (Linux) so the gateway runs in the background using your config and workspace.

Manage the service with:

openclaw gateway status
openclaw gateway stop

For foreground debugging:

openclaw gateway --port 18789 --verbose
openclaw gateway --bind lan --port 18789

In Docker images, run the equivalent directly:

node dist/index.js gateway --bind lan --port 18789

Restart sentinels

Restart sentinels are written on update or restart requests. They contain session key, delivery context, thread ID, continuation message, and update stats. On the next startup the gateway reads the sentinel, emits a system event, and can resume delivery.

sigusr1 triggers a controlled restart. Managed-service handoff uses a detached helper so the running gateway does not mutate its own install root.

Tailscale exposure

Tailscale settings live under the gateway.tailscale section of the config file. Supported modes are off (default), serve, and funnel. Serve and funnel modes require gateway.bind=loopback and gateway.auth.mode=password. Funnel additionally requires password auth.

See Configuration for the full set of gateway.* options and HTTP API for probe endpoints.

All container and daemon modes respect the same ~/.openclaw/openclaw.json (or path set by OPENCLAW_CONFIG_PATH) and workspace layout. Health and readiness probes are available on the gateway HTTP port for orchestration systems.