diff --git a/docs/help/faq.md b/docs/help/faq.md index dfe6759cd28..c72d6561025 100644 --- a/docs/help/faq.md +++ b/docs/help/faq.md @@ -1156,6 +1156,19 @@ You still need to click the extension button on the tab you want to control (it Yes. See [Sandboxing](/gateway/sandboxing). For Docker-specific setup (full gateway in Docker or sandbox images), see [Docker](/install/docker). +### Docker feels limited How do I enable full features + +The default image is security-first and runs as the `node` user, so it does not +include system packages, Homebrew, or bundled browsers. For a fuller setup: + +- Persist `/home/node` with `OPENCLAW_HOME_VOLUME` so caches survive. +- Bake system deps into the image with `OPENCLAW_DOCKER_APT_PACKAGES`. +- Install Playwright browsers via the bundled CLI: + `node /app/node_modules/playwright-core/cli.js install chromium` +- Set `PLAYWRIGHT_BROWSERS_PATH` and ensure the path is persisted. + +Docs: [Docker](/install/docker), [Browser](/tools/browser). + **Can I keep DMs personal but make groups public sandboxed with one agent** Yes - if your private traffic is **DMs** and your public traffic is **groups**. diff --git a/docs/install/docker.md b/docs/install/docker.md index 6d5df617cb1..d112597d259 100644 --- a/docs/install/docker.md +++ b/docs/install/docker.md @@ -142,6 +142,61 @@ Notes: - If you change `OPENCLAW_DOCKER_APT_PACKAGES`, rerun `docker-setup.sh` to rebuild the image. +### Power-user / full-featured container (opt-in) + +The default Docker image is **security-first** and runs as the non-root `node` +user. This keeps the attack surface small, but it means: + +- no system package installs at runtime +- no Homebrew by default +- no bundled Chromium/Playwright browsers + +If you want a more full-featured container, use these opt-in knobs: + +1) **Persist `/home/node`** so browser downloads and tool caches survive: + +```bash +export OPENCLAW_HOME_VOLUME="openclaw_home" +./docker-setup.sh +``` + +2) **Bake system deps into the image** (repeatable + persistent): + +```bash +export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq" +./docker-setup.sh +``` + +3) **Install Playwright browsers without `npx`** (avoids npm override conflicts): + +```bash +docker compose run --rm openclaw-cli \ + node /app/node_modules/playwright-core/cli.js install chromium +``` + +If you need Playwright to install system deps, rebuild the image with +`OPENCLAW_DOCKER_APT_PACKAGES` instead of using `--with-deps` at runtime. + +4) **Persist Playwright browser downloads**: + +- Set `PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright` in + `docker-compose.yml`. +- Ensure `/home/node` persists via `OPENCLAW_HOME_VOLUME`, or mount + `/home/node/.cache/ms-playwright` via `OPENCLAW_EXTRA_MOUNTS`. + +### Permissions + EACCES + +The image runs as `node` (uid 1000). If you see permission errors on +`/home/node/.openclaw`, make sure your host bind mounts are owned by uid 1000. + +Example (Linux host): + +```bash +sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace +``` + +If you choose to run as root for convenience, you accept the security tradeoff. + ### Faster rebuilds (recommended) To speed up rebuilds, order your Dockerfile so dependency layers are cached. diff --git a/docs/tools/browser.md b/docs/tools/browser.md index b02130b3c0b..848977d1e69 100644 --- a/docs/tools/browser.md +++ b/docs/tools/browser.md @@ -326,6 +326,20 @@ If you see `Playwright is not available in this gateway build`, install the full Playwright package (not `playwright-core`) and restart the gateway, or reinstall OpenClaw with browser support. +#### Docker Playwright install + +If your Gateway runs in Docker, avoid `npx playwright` (npm override conflicts). +Use the bundled CLI instead: + +```bash +docker compose run --rm openclaw-cli \ + node /app/node_modules/playwright-core/cli.js install chromium +``` + +To persist browser downloads, set `PLAYWRIGHT_BROWSERS_PATH` (for example, +`/home/node/.cache/ms-playwright`) and make sure `/home/node` is persisted via +`OPENCLAW_HOME_VOLUME` or a bind mount. See [Docker](/install/docker). + ## How it works (internal) High-level flow: