Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ packages/claw-plugin/static/
.env.local
.env.*.local

# Docker install state
docker/data/

# Logs
*.log

Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ powershell -c "irm https://openui.com/openclaw-os/install.ps1 | iex"

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.

Docker alternative:

```bash
cd docker
./scripts/init-env.sh
docker compose up -d --build
```

Windows PowerShell:

```powershell
cd docker
.\scripts\init-env.ps1
docker compose up -d --build
```

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.

or through published package

```bash
Expand Down
7 changes: 7 additions & 0 deletions docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.git
.DS_Store
.env
data
node_modules
npm-debug.log
Dockerfile~
32 changes: 32 additions & 0 deletions docker/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copy to .env or run ./scripts/init-env.sh.
OPENCLAW_VERSION=2026.5.27
OPENCLAW_OS_PLUGIN_VERSION=0.1.5

# The helper script generates a random value. Keep this private.
OPENCLAW_GATEWAY_TOKEN=

# Host ports. The gateway serves both Control UI and OpenClaw OS on this port.
OPENCLAW_GATEWAY_HOST_PORT=18789
OPENCLAW_BRIDGE_HOST_PORT=18790
OPENCLAW_MSTEAMS_HOST_PORT=3978

# Persistent host state.
OPENCLAW_CONFIG_DIR=./data/openclaw
OPENCLAW_AUTH_PROFILE_SECRET_DIR=./data/openclaw-auth-profile-secrets

# Gateway/container behavior.
OPENCLAW_GATEWAY_BIND=lan
OPENCLAW_GATEWAY_AUTH_MODE=token
OPENCLAW_DISABLE_BONJOUR=1
OPENCLAW_TZ=UTC

# Optional comma-separated origins if you reverse-proxy the gateway.
OPENCLAW_CONTROL_UI_EXTRA_ORIGINS=

# Optional provider keys. You can reference these from openclaw-os.yaml,
# for example: apiKeys.openai: ${OPENAI_API_KEY}
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
OPENROUTER_API_KEY=
GOOGLE_API_KEY=
GEMINI_API_KEY=
63 changes: 63 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
ARG NODE_IMAGE=node:24-bookworm-slim

FROM ${NODE_IMAGE}

ARG OPENCLAW_VERSION=2026.5.27
ARG OPENCLAW_OS_PLUGIN_VERSION=0.1.5

LABEL org.opencontainers.image.title="OpenClaw with OpenClaw OS" \
org.opencontainers.image.description="OpenClaw gateway image with the OpenClaw OS workspace plugin pre-cached" \
org.opencontainers.image.source="https://github.com/thesysdev/openclaw-os" \
org.opencontainers.image.documentation="https://www.openui.com/openclaw-os" \
org.opencontainers.image.licenses="MIT"

ENV NODE_ENV=production \
HOME=/home/node \
OPENCLAW_HOME=/home/node \
OPENCLAW_STATE_DIR=/home/node/.openclaw \
OPENCLAW_CONFIG_DIR=/home/node/.openclaw \
OPENCLAW_CONFIG_PATH=/home/node/.openclaw/openclaw.json \
OPENCLAW_WORKSPACE_DIR=/home/node/.openclaw/workspace \
OPENCLAW_OS_PLUGIN_PATH=/opt/openclaw-os-plugin/node_modules/@openuidev/openclaw-os-plugin \
NPM_CONFIG_AUDIT=false \
NPM_CONFIG_FUND=false

RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates \
curl \
git \
hostname \
lsof \
openssl \
procps \
python3 \
python3-yaml \
tini \
&& rm -rf /var/lib/apt/lists/*

RUN npm install -g "openclaw@${OPENCLAW_VERSION}" \
&& npm install --prefix /opt/openclaw-os-plugin --omit=dev "@openuidev/openclaw-os-plugin@${OPENCLAW_OS_PLUGIN_VERSION}" \
&& npm cache clean --force \
&& chown -R node:node /opt/openclaw-os-plugin

COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

RUN chmod 0755 /usr/local/bin/docker-entrypoint.sh \
&& install -d -m 0755 -o node -g node /home/node/.npm \
&& install -d -m 0755 -o node -g node /home/node/.config \
&& install -d -m 0700 -o node -g node \
/home/node/.openclaw \
/home/node/.openclaw/workspace \
/home/node/.config/openclaw

USER node
WORKDIR /home/node

EXPOSE 18789 18790 3978

HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=5 \
CMD node -e "fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

ENTRYPOINT ["tini", "-s", "--", "docker-entrypoint.sh"]
CMD ["gateway"]
124 changes: 124 additions & 0 deletions docker/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# OpenClaw OS Docker

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.

OpenClaw OS is served by the OpenClaw gateway at:

```text
http://localhost:18789/plugins/openclawos
```

## Quick Start

From this `docker/` directory:

```bash
./scripts/init-env.sh
docker compose up -d --build
```

Windows PowerShell:

```powershell
.\scripts\init-env.ps1
docker compose up -d --build
```

Wait until the gateway is healthy:

```bash
docker compose ps
```

The `openclaw-gateway` row should say `healthy`. First startup can take 20-60 seconds because the gateway installs/registers the OpenClaw OS plugin.

Then open:

- OpenClaw OS: `http://localhost:18789/plugins/openclawos`
- OpenClaw Control UI: `http://localhost:18789/`

Use the `OPENCLAW_GATEWAY_TOKEN` from `.env` when the UI asks for the gateway token.

If the browser says the page is empty or unavailable, the gateway is probably still starting or has crashed. Check:

```bash
docker compose ps
docker compose logs --tail=100 openclaw-gateway
```

## Configure Before Running

Edit `openclaw-os.yaml` before starting the container:

```yaml
model:
primary: openai/gpt-5.5
thinking: medium

apiKeys:
openai: sk-your-key-here
```

You can also keep secrets in `.env` and reference them from YAML:

```env
OPENAI_API_KEY=sk-your-key-here
```

```yaml
apiKeys:
openai: ${OPENAI_API_KEY}
```

The container applies `openclaw-os.yaml` on every start and stores API keys in OpenClaw's auth-profile store under `./data/openclaw`.

To print the token-authenticated OpenClaw OS URL:

```bash
./scripts/openclaw.sh os url
```

Windows PowerShell:

```powershell
.\scripts\openclaw.ps1 os url
```

## CLI Examples

```bash
# Check gateway health/status.
./scripts/openclaw.sh gateway probe

# Configure models, channels, plugins, and gateway settings.
./scripts/openclaw.sh configure

# Approve browser/device pairing requests.
./scripts/openclaw.sh devices list
./scripts/openclaw.sh devices approve <request-id>
```

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`.

## Version Pins

Defaults are pinned in `.env.example`:

- `openclaw@2026.5.27`
- `@openuidev/openclaw-os-plugin@0.1.5`

Change `OPENCLAW_VERSION` or `OPENCLAW_OS_PLUGIN_VERSION`, then rebuild:

```bash
docker compose build --no-cache
docker compose up -d
```

## Persistence

Compose bind-mounts state into:

- `./data/openclaw` for OpenClaw config, workspace, sessions, and installed plugin state
- `./data/openclaw-auth-profile-secrets` for auth-profile secret material

Keep both directories private.
83 changes: 83 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
services:
openclaw-gateway:
image: ${OPENCLAW_IMAGE:-openclaw-os:local}
build:
context: .
args:
OPENCLAW_VERSION: ${OPENCLAW_VERSION:-2026.5.27}
OPENCLAW_OS_PLUGIN_VERSION: ${OPENCLAW_OS_PLUGIN_VERSION:-0.1.5}
env_file:
- path: .env
required: false
environment:
HOME: /home/node
OPENCLAW_HOME: /home/node
OPENCLAW_STATE_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
OPENCLAW_GATEWAY_BIND: ${OPENCLAW_GATEWAY_BIND:-lan}
OPENCLAW_GATEWAY_AUTH_MODE: ${OPENCLAW_GATEWAY_AUTH_MODE:-token}
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
OPENCLAW_GATEWAY_HOST_PORT: ${OPENCLAW_GATEWAY_HOST_PORT:-18789}
OPENCLAW_CONTROL_UI_EXTRA_ORIGINS: ${OPENCLAW_CONTROL_UI_EXTRA_ORIGINS:-}
OPENCLAW_BOOTSTRAP_CONFIG: /etc/openclaw-os/openclaw-os.yaml
OPENCLAW_OS_AUTO_INSTALL: ${OPENCLAW_OS_AUTO_INSTALL:-1}
OPENCLAW_OS_PLUGIN_SPEC: ${OPENCLAW_OS_PLUGIN_SPEC:-}
OPENCLAW_DISABLE_BONJOUR: ${OPENCLAW_DISABLE_BONJOUR:-1}
OPENAI_API_KEY: ${OPENAI_API_KEY:-}
ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-}
OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:-}
GOOGLE_API_KEY: ${GOOGLE_API_KEY:-}
GEMINI_API_KEY: ${GEMINI_API_KEY:-}
TZ: ${OPENCLAW_TZ:-UTC}
volumes:
- ./openclaw-os.yaml:/etc/openclaw-os/openclaw-os.yaml:ro
- ${OPENCLAW_CONFIG_DIR:-./data/openclaw}:/home/node/.openclaw
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-./data/openclaw-auth-profile-secrets}:/home/node/.config/openclaw
ports:
- "${OPENCLAW_GATEWAY_HOST_PORT:-18789}:18789"
- "${OPENCLAW_BRIDGE_HOST_PORT:-18790}:18790"
- "${OPENCLAW_MSTEAMS_HOST_PORT:-3978}:3978"
extra_hosts:
- "host.docker.internal:host-gateway"
cap_drop:
- NET_RAW
- NET_ADMIN
security_opt:
- no-new-privileges:true
restart: unless-stopped

openclaw-cli:
image: ${OPENCLAW_IMAGE:-openclaw-os:local}
profiles:
- tools
network_mode: "service:openclaw-gateway"
env_file:
- path: .env
required: false
environment:
HOME: /home/node
OPENCLAW_HOME: /home/node
OPENCLAW_STATE_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_DIR: /home/node/.openclaw
OPENCLAW_CONFIG_PATH: /home/node/.openclaw/openclaw.json
OPENCLAW_WORKSPACE_DIR: /home/node/.openclaw/workspace
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN:-}
OPENCLAW_BOOTSTRAP_CONFIG: /etc/openclaw-os/openclaw-os.yaml
BROWSER: echo
TZ: ${OPENCLAW_TZ:-UTC}
volumes:
- ./openclaw-os.yaml:/etc/openclaw-os/openclaw-os.yaml:ro
- ${OPENCLAW_CONFIG_DIR:-./data/openclaw}:/home/node/.openclaw
- ${OPENCLAW_AUTH_PROFILE_SECRET_DIR:-./data/openclaw-auth-profile-secrets}:/home/node/.config/openclaw
cap_drop:
- NET_RAW
- NET_ADMIN
security_opt:
- no-new-privileges:true
entrypoint: ["tini", "-s", "--", "docker-entrypoint.sh"]
command: ["cli", "--help"]
depends_on:
openclaw-gateway:
condition: service_healthy
Loading
Loading