OpenClaw/Moltbot/Clawdbot - Playwright + Chromium automation bot with root access, multi-arch
10K+
This document provides an overview of the multi-stage Dockerfile used to build an optimized OpenClaw runtime environment. The image includes OpenClaw gateway, Python, Bun, UV, and Playwright for browser automation.
Below is the full Dockerfile with all comments translated into English.
# ========== Stage 1: Build Environment ==========
FROM node:22-bookworm AS builder
LABEL maintainer="Wan Jie <[email protected]>" \
version="2026.*.*" \
description="OpenClaw Image,include PLAYWRIGHT, chromium,agent-browser with fonts-noto-cjk"
# Set locale to Chinese UTF-8 (required for some fonts and applications)
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8 \
DEBIAN_FRONTEND=noninteractive
# Install build dependencies (including compilation tools and full Python environment)
RUN apt-get update && apt-get install -y --no-install-recommends \
git openssh-client build-essential python3-full python3-pip python3-venv \
ca-certificates curl unzip \
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
libgbm1 libpango-1.0-0 libcairo2 libasound2 \
fonts-noto-cjk fonts-noto-color-emoji locales \
gnupg2 \
&& sed -i 's/^# \(zh_CN.UTF-8\)/\1/' /etc/locale.gen && locale-gen \
&& apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 871920D1991BC93C || true \
&& rm -rf /var/lib/apt/lists/*
# Create Python virtual environment and install required packages
ENV VIRTUAL_ENV=/opt/venv
RUN python3 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir huggingface_hub jupyterlab \
&& pip cache purge
# Install Bun
RUN curl -fsSL https://bun.sh/install | bash
ENV BUN_INSTALL=/root/.bun
ENV PATH="${BUN_INSTALL}/bin:${PATH}"
# Install UV
RUN curl -LsSf https://astral.sh/uv/install.sh | sh \
&& mv /root/.local/bin/uv /usr/local/bin/uv
# Install OpenClaw core to a custom directory (avoid polluting global system)
RUN npm install --prefix /opt/openclaw -g openclaw@latest --unsafe-perm && npm cache clean --force
# Install Playwright (specific version, download browser)
ARG PLAYWRIGHT_VERSION=1.50.1
WORKDIR /app
RUN corepack enable && corepack prepare pnpm@latest --activate \
&& printf '{"name":"openclaw-app","private":true}' > package.json \
&& pnpm add -D playwright@${PLAYWRIGHT_VERSION} \
&& pnpm exec playwright install chromium \
&& pnpm store prune
# ---------- Write the original start-openclaw script ----------
RUN echo '#!/bin/bash\n\
set -e\n\
# Default environment variable values\n\
export OPENAI_API_BASE="${OPENAI_API_BASE:-https://api.openai.com/v1}"\n\
export OPENAI_API_KEY="${OPENAI_API_KEY:-sk-placeholder}"\n\
export MODEL="${MODEL:-openrouter/free:free}"\n\
export PORT="${PORT:-18789}"\n\
\n\
mkdir -p /root/.openclaw/sessions /root/.openclaw/agents/main/sessions\n\
\n\
# Clean up BaseUrl format\n\
CLEAN_BASE=$(echo "$OPENAI_API_BASE" | sed "s|/chat/completions||g" | sed "s|/v1/|/v1|g" | sed "s|/v1$|/v1|g")\n\
\n\
# Dynamically generate openclaw.json\n\
cat <<EOF > /root/.openclaw/openclaw.json\n\
{\n\
"models": {\n\
"providers": {\n\
"nvidia": {\n\
"baseUrl": "$CLEAN_BASE",\n\
"apiKey": "$OPENAI_API_KEY",\n\
"api": "openai-completions",\n\
"models": [{ "id": "$MODEL", "name": "PrimaryModel", "contextWindow": 128000 }]\n\
}\n\
}\n\
},\n\
"agents": { "defaults": { "model": { "primary": "nvidia/$MODEL" } } },\n\
"gateway": {\n\
"mode": "local", "bind": "lan", "port": $PORT,\n\
"trustedProxies": ["0.0.0.0/0", "10.0.0.0/8", "172.16.0.0/12", "10.233.64.0/18", "100.64.0.0/10", "127.0.0.1/8"],\n\
"auth": { "mode": "token" },\n\
"controlUi": { "enabled": true, "dangerouslyAllowHostHeaderOriginFallback": true, "allowInsecureAuth": true, "dangerouslyDisableDeviceAuth": true}\n\
}\n\
}\n\
EOF\n\
\n\
# Dynamically find the Chromium path from playwright and set CHROME_PATH (if not specified or missing)\n\
if [ ! -f "$CHROME_PATH" ]; then\n\
CHROME_PATH=$(find /root/.cache/ms-playwright -name chrome -type f 2>/dev/null | head -1)\n\
export CHROME_PATH\n\
fi\n\
\n\
openclaw doctor --fix || true\n\
echo "🚀 Starting OpenClaw on port $PORT..."\n\
exec openclaw gateway run --port $PORT\n\
' > /usr/local/bin/start-openclaw && chmod +x /usr/local/bin/start-openclaw
# ========== Stage 2: Final Runtime Image ==========
FROM node:22-bookworm-slim
# Set locale to Chinese UTF-8
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8 \
DEBIAN_FRONTEND=noninteractive
# Install runtime essential libraries, locales and generate Chinese environment
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates curl \
libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
libxkbcommon0 libxcomposite1 libxdamage1 libxext6 libxfixes3 libxrandr2 \
libgbm1 libpango-1.0-0 libcairo2 libasound2 \
fonts-noto-cjk fonts-noto-color-emoji \
python3-minimal python3-venv \
locales \
&& sed -i 's/^# \(zh_CN.UTF-8\)/\1/' /etc/locale.gen \
&& locale-gen \
&& rm -rf /var/lib/apt/lists/*
# Copy Python virtual environment from builder stage
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Copy Bun
COPY --from=builder /root/.bun /root/.bun
ENV BUN_INSTALL=/root/.bun
ENV PATH="${BUN_INSTALL}/bin:${PATH}"
# Copy UV
COPY --from=builder /usr/local/bin/uv /usr/local/bin/uv
# Copy OpenClaw (custom installation directory) and add to PATH
COPY --from=builder /opt/openclaw /opt/openclaw
ENV PATH="/opt/openclaw/bin:${PATH}"
# Copy Playwright browsers
COPY --from=builder /root/.cache/ms-playwright /root/.cache/ms-playwright
ENV PLAYWRIGHT_BROWSERS_PATH=/root/.cache/ms-playwright
# CHROME_PATH is not set statically here; it will be dynamically located by the startup script
# Copy the original scripts
COPY --from=builder /usr/local/bin/start-openclaw /usr/local/bin/start-openclaw
WORKDIR /app
ARG PORT=18789
ENV PORT=${PORT}
EXPOSE ${PORT}
CMD ["/usr/local/bin/start-openclaw"]
huggingface_hub, jupyterlab) from system Python./opt/openclaw to avoid global npm pollution.openclaw.json based on environment variables (OPENAI_API_BASE, OPENAI_API_KEY, MODEL, PORT).CHROME_PATH is not set.| Variable | Description | Default |
|---|---|---|
OPENAI_API_BASE | Base URL for OpenAI-compatible API | https://api.openai.com/v1 |
OPENAI_API_KEY | API key for the provider | sk-placeholder |
MODEL | Model ID to use (e.g., openrouter/free:free) | openrouter/free:free |
PORT | Port for OpenClaw gateway | 18789 |
HF_TOKEN | Hugging Face token for authentication | (optional) |
Build the image:
docker build -t openclaw-image .
Run the container:
docker run -p 18789:18789 \
-e OPENAI_API_BASE="https://your-custom-endpoint/v1" \
-e OPENAI_API_KEY="your-api-key" \
-e MODEL="your-model-id" \
cnrock/openclaw
The OpenClaw gateway will be available on port 18789.
/root/.cache/ms-playwright and consumed by OpenClaw for web automation tasks.Content type
Image
Digest
sha256:9fee05700…
Size
956.9 MB
Last updated
3 months ago
docker pull cnrock/openclaw