Skip to content

Commit 52ce371

Browse files
committed
Add Docker install path
1 parent 076ae63 commit 52ce371

13 files changed

Lines changed: 760 additions & 0 deletions

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ packages/claw-plugin/static/
5555
.env.local
5656
.env.*.local
5757

58+
# Docker install state
59+
docker/data/
60+
5861
# Logs
5962
*.log
6063

README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ powershell -c "irm https://openui.com/openclaw-os/install.ps1 | iex"
3939

4040
The installer downloads the latest source, builds the workspace UI, registers it as an OpenClaw plugin, restarts the gateway, and opens the dashboard in your browser.
4141

42+
Docker alternative:
43+
44+
```bash
45+
cd docker
46+
./scripts/init-env.sh
47+
docker compose up -d --build
48+
```
49+
50+
Windows PowerShell:
51+
52+
```powershell
53+
cd docker
54+
.\scripts\init-env.ps1
55+
docker compose up -d --build
56+
```
57+
58+
The Docker install runs OpenClaw, preloads the OpenClaw OS plugin, and reads model/API-key settings from [`docker/openclaw-os.yaml`](./docker/openclaw-os.yaml). See [`docker/README.md`](./docker/README.md) for setup details, Windows notes, and the wrapper CLI commands.
59+
4260
or through published package
4361

4462
```bash

docker/.dockerignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.git
2+
.DS_Store
3+
.env
4+
data
5+
node_modules
6+
npm-debug.log
7+
Dockerfile~

docker/.env.example

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Copy to .env or run ./scripts/init-env.sh.
2+
OPENCLAW_VERSION=2026.5.27
3+
OPENCLAW_OS_PLUGIN_VERSION=0.1.5
4+
5+
# The helper script generates a random value. Keep this private.
6+
OPENCLAW_GATEWAY_TOKEN=
7+
8+
# Host ports. The gateway serves both Control UI and OpenClaw OS on this port.
9+
OPENCLAW_GATEWAY_HOST_PORT=18789
10+
OPENCLAW_BRIDGE_HOST_PORT=18790
11+
OPENCLAW_MSTEAMS_HOST_PORT=3978
12+
13+
# Persistent host state.
14+
OPENCLAW_CONFIG_DIR=./data/openclaw
15+
OPENCLAW_AUTH_PROFILE_SECRET_DIR=./data/openclaw-auth-profile-secrets
16+
17+
# Gateway/container behavior.
18+
OPENCLAW_GATEWAY_BIND=lan
19+
OPENCLAW_GATEWAY_AUTH_MODE=token
20+
OPENCLAW_DISABLE_BONJOUR=1
21+
OPENCLAW_TZ=UTC
22+
23+
# Optional comma-separated origins if you reverse-proxy the gateway.
24+
OPENCLAW_CONTROL_UI_EXTRA_ORIGINS=
25+
26+
# Optional provider keys. You can reference these from openclaw-os.yaml,
27+
# for example: apiKeys.openai: ${OPENAI_API_KEY}
28+
OPENAI_API_KEY=
29+
ANTHROPIC_API_KEY=
30+
OPENROUTER_API_KEY=
31+
GOOGLE_API_KEY=
32+
GEMINI_API_KEY=

docker/Dockerfile

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
ARG NODE_IMAGE=node:24-bookworm-slim
2+
3+
FROM ${NODE_IMAGE}
4+
5+
ARG OPENCLAW_VERSION=2026.5.27
6+
ARG OPENCLAW_OS_PLUGIN_VERSION=0.1.5
7+
8+
LABEL org.opencontainers.image.title="OpenClaw with OpenClaw OS" \
9+
org.opencontainers.image.description="OpenClaw gateway image with the OpenClaw OS workspace plugin pre-cached" \
10+
org.opencontainers.image.source="https://github.com/thesysdev/openclaw-os" \
11+
org.opencontainers.image.documentation="https://www.openui.com/openclaw-os" \
12+
org.opencontainers.image.licenses="MIT"
13+
14+
ENV NODE_ENV=production \
15+
HOME=/home/node \
16+
OPENCLAW_HOME=/home/node \
17+
OPENCLAW_STATE_DIR=/home/node/.openclaw \
18+
OPENCLAW_CONFIG_DIR=/home/node/.openclaw \
19+
OPENCLAW_CONFIG_PATH=/home/node/.openclaw/openclaw.json \
20+
OPENCLAW_WORKSPACE_DIR=/home/node/.openclaw/workspace \
21+
OPENCLAW_OS_PLUGIN_PATH=/opt/openclaw-os-plugin/node_modules/@openuidev/openclaw-os-plugin \
22+
NPM_CONFIG_AUDIT=false \
23+
NPM_CONFIG_FUND=false
24+
25+
RUN apt-get update \
26+
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
27+
ca-certificates \
28+
curl \
29+
git \
30+
hostname \
31+
lsof \
32+
openssl \
33+
procps \
34+
python3 \
35+
python3-yaml \
36+
tini \
37+
&& rm -rf /var/lib/apt/lists/*
38+
39+
RUN npm install -g "openclaw@${OPENCLAW_VERSION}" \
40+
&& npm install --prefix /opt/openclaw-os-plugin --omit=dev "@openuidev/openclaw-os-plugin@${OPENCLAW_OS_PLUGIN_VERSION}" \
41+
&& npm cache clean --force \
42+
&& chown -R node:node /opt/openclaw-os-plugin
43+
44+
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
45+
46+
RUN chmod 0755 /usr/local/bin/docker-entrypoint.sh \
47+
&& install -d -m 0755 -o node -g node /home/node/.npm \
48+
&& install -d -m 0755 -o node -g node /home/node/.config \
49+
&& install -d -m 0700 -o node -g node \
50+
/home/node/.openclaw \
51+
/home/node/.openclaw/workspace \
52+
/home/node/.config/openclaw
53+
54+
USER node
55+
WORKDIR /home/node
56+
57+
EXPOSE 18789 18790 3978
58+
59+
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \
60+
CMD node -e "fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
61+
62+
ENTRYPOINT ["tini", "-s", "--", "docker-entrypoint.sh"]
63+
CMD ["gateway"]

docker/README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# OpenClaw OS Docker
2+
3+
Docker image and Compose setup for running OpenClaw with OpenClaw OS registered as a gateway plugin. This is useful when the native installer is not a good fit, especially on Windows.
4+
5+
OpenClaw OS is served by the OpenClaw gateway at:
6+
7+
```text
8+
http://localhost:18789/plugins/openclawos
9+
```
10+
11+
## Quick Start
12+
13+
From this `docker/` directory:
14+
15+
```bash
16+
./scripts/init-env.sh
17+
docker compose up -d --build
18+
```
19+
20+
Windows PowerShell:
21+
22+
```powershell
23+
.\scripts\init-env.ps1
24+
docker compose up -d --build
25+
```
26+
27+
Wait until the gateway is healthy:
28+
29+
```bash
30+
docker compose ps
31+
```
32+
33+
The `openclaw-gateway` row should say `healthy`. First startup can take 20-60 seconds because the gateway installs/registers the OpenClaw OS plugin.
34+
35+
Then open:
36+
37+
- OpenClaw OS: `http://localhost:18789/plugins/openclawos`
38+
- OpenClaw Control UI: `http://localhost:18789/`
39+
40+
Use the `OPENCLAW_GATEWAY_TOKEN` from `.env` when the UI asks for the gateway token.
41+
42+
If the browser says the page is empty or unavailable, the gateway is probably still starting or has crashed. Check:
43+
44+
```bash
45+
docker compose ps
46+
docker compose logs --tail=100 openclaw-gateway
47+
```
48+
49+
## Configure Before Running
50+
51+
Edit `openclaw-os.yaml` before starting the container:
52+
53+
```yaml
54+
model:
55+
primary: openai/gpt-5.5
56+
thinking: medium
57+
58+
apiKeys:
59+
openai: sk-your-key-here
60+
```
61+
62+
You can also keep secrets in `.env` and reference them from YAML:
63+
64+
```env
65+
OPENAI_API_KEY=sk-your-key-here
66+
```
67+
68+
```yaml
69+
apiKeys:
70+
openai: ${OPENAI_API_KEY}
71+
```
72+
73+
The container applies `openclaw-os.yaml` on every start and stores API keys in OpenClaw's auth-profile store under `./data/openclaw`.
74+
75+
To print the token-authenticated OpenClaw OS URL:
76+
77+
```bash
78+
./scripts/openclaw.sh os url
79+
```
80+
81+
Windows PowerShell:
82+
83+
```powershell
84+
.\scripts\openclaw.ps1 os url
85+
```
86+
87+
## CLI Examples
88+
89+
```bash
90+
# Check gateway health/status.
91+
./scripts/openclaw.sh gateway probe
92+
93+
# Configure models, channels, plugins, and gateway settings.
94+
./scripts/openclaw.sh configure
95+
96+
# Approve browser/device pairing requests.
97+
./scripts/openclaw.sh devices list
98+
./scripts/openclaw.sh devices approve <request-id>
99+
```
100+
101+
Use the wrapper scripts for gateway/device commands instead of a host-installed `openclaw` binary. The wrapper always uses the OpenClaw CLI inside this image, so its gateway protocol matches the container. A host-installed OpenClaw CLI may be older than the Docker gateway and fail with `protocol mismatch`.
102+
103+
## Version Pins
104+
105+
Defaults are pinned in `.env.example`:
106+
107+
- `openclaw@2026.5.27`
108+
- `@openuidev/openclaw-os-plugin@0.1.5`
109+
110+
Change `OPENCLAW_VERSION` or `OPENCLAW_OS_PLUGIN_VERSION`, then rebuild:
111+
112+
```bash
113+
docker compose build --no-cache
114+
docker compose up -d
115+
```
116+
117+
## Persistence
118+
119+
Compose bind-mounts state into:
120+
121+
- `./data/openclaw` for OpenClaw config, workspace, sessions, and installed plugin state
122+
- `./data/openclaw-auth-profile-secrets` for auth-profile secret material
123+
124+
Keep both directories private.

docker/docker-compose.yml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
services:
2+
openclaw-gateway:
3+
image: ${OPENCLAW_IMAGE:-openclaw-os:local}
4+
build:
5+
context: .
6+
args:
7+
OPENCLAW_VERSION: ${OPENCLAW_VERSION:-2026.5.27}
8+
OPENCLAW_OS_PLUGIN_VERSION: ${OPENCLAW_OS_PLUGIN_VERSION:-0.1.5}
9+
env_file:
10+
- path: .env
11+
required: false
12+
environment:
13+
HOME: /home/node
14+
OPENCLAW_HOME: /home/node
15+
OPENCLAW_STATE_DIR: /home/node/.openclaw
16+
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
17+
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
18+
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
19+
OPENCLAW_GATEWAY_BIND: ${OPENCLAW_GATEWAY_BIND:-lan}
20+
OPENCLAW_GATEWAY_AUTH_MODE: ${OPENCLAW_GATEWAY_AUTH_MODE:-token}
21+
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
22+
OPENCLAW_GATEWAY_HOST_PORT: ${OPENCLAW_GATEWAY_HOST_PORT:-18789}
23+
OPENCLAW_CONTROL_UI_EXTRA_ORIGINS: ${OPENCLAW_CONTROL_UI_EXTRA_ORIGINS:-}
24+
OPENCLAW_BOOTSTRAP_CONFIG: /etc/openclaw-os/openclaw-os.yaml
25+
OPENCLAW_OS_AUTO_INSTALL: ${OPENCLAW_OS_AUTO_INSTALL:-1}
26+
OPENCLAW_OS_PLUGIN_SPEC: ${OPENCLAW_OS_PLUGIN_SPEC:-}
27+
OPENCLAW_DISABLE_BONJOUR: ${OPENCLAW_DISABLE_BONJOUR:-1}
28+
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
29+
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
30+
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
31+
GOOGLE_API_KEY: ${GOOGLE_API_KEY:-}
32+
GEMINI_API_KEY: ${GEMINI_API_KEY:-}
33+
TZ: ${OPENCLAW_TZ:-UTC}
34+
volumes:
35+
- ./openclaw-os.yaml:/etc/openclaw-os/openclaw-os.yaml:ro
36+
- ${OPENCLAW_CONFIG_DIR:-./data/openclaw}:/home/node/.openclaw
37+
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-./data/openclaw-auth-profile-secrets}:/home/node/.config/openclaw
38+
ports:
39+
- "${OPENCLAW_GATEWAY_HOST_PORT:-18789}:18789"
40+
- "${OPENCLAW_BRIDGE_HOST_PORT:-18790}:18790"
41+
- "${OPENCLAW_MSTEAMS_HOST_PORT:-3978}:3978"
42+
extra_hosts:
43+
- "host.docker.internal:host-gateway"
44+
cap_drop:
45+
- NET_RAW
46+
- NET_ADMIN
47+
security_opt:
48+
- no-new-privileges:true
49+
restart: unless-stopped
50+
51+
openclaw-cli:
52+
image: ${OPENCLAW_IMAGE:-openclaw-os:local}
53+
profiles:
54+
- tools
55+
network_mode: "service:openclaw-gateway"
56+
env_file:
57+
- path: .env
58+
required: false
59+
environment:
60+
HOME: /home/node
61+
OPENCLAW_HOME: /home/node
62+
OPENCLAW_STATE_DIR: /home/node/.openclaw
63+
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
64+
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
65+
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
66+
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
67+
OPENCLAW_BOOTSTRAP_CONFIG: /etc/openclaw-os/openclaw-os.yaml
68+
BROWSER: echo
69+
TZ: ${OPENCLAW_TZ:-UTC}
70+
volumes:
71+
- ./openclaw-os.yaml:/etc/openclaw-os/openclaw-os.yaml:ro
72+
- ${OPENCLAW_CONFIG_DIR:-./data/openclaw}:/home/node/.openclaw
73+
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-./data/openclaw-auth-profile-secrets}:/home/node/.config/openclaw
74+
cap_drop:
75+
- NET_RAW
76+
- NET_ADMIN
77+
security_opt:
78+
- no-new-privileges:true
79+
entrypoint: ["tini", "-s", "--", "docker-entrypoint.sh"]
80+
command: ["cli", "--help"]
81+
depends_on:
82+
openclaw-gateway:
83+
condition: service_healthy

0 commit comments

Comments
 (0)