Skip to content

Commit f1a4612

Browse files
authored
feat(kiloclaw): add headless Chromium browser support (#951)
## Summary - Install chromium in the Docker image so OpenClaw's built-in browser tool works out of the box - Configure browser.headless, browser.noSandbox, and browser.enabled in the openclaw.json config patch for containerized operation - Sync the same browser config to config-writer.ts so config restores don't lose browser support <!-- What changed and why? Keep this brief and outcome-focused. --> <!-- Include any architectural changes and enough context for a reviewer unfamiliar with this code area. --> ## Verification <!-- List the checks you ran and what passed. Add command output notes when useful. --> - Deploy a fresh kiloclaw instance (destroy + recreate to trigger fresh install path) - Verify which chromium returns /usr/bin/chromium on the Fly machine - Verify cat /root/.openclaw/openclaw.json | grep -A4 browser shows enabled: true, headless: true, noSandbox: true - Verify Chromium processes are running (ps -ef | grep chromium) - Ask the agent to use the browser tool (e.g. "use the browser tool to open https://example.com and take a screenshot") — confirms end-to-end CDP functionality - All 505 kiloclaw tests pass ## Visual Changes None — this is backend/infrastructure only. <!-- If UI/visual behavior changed, add before/after screenshots in the table below. --> <!-- If there are no visual changes, replace the table with: N/A --> | Before | After | | ------ | ----- | | | | ## Reviewer Notes - OpenClaw auto-detects /usr/bin/chromium on Linux and auto-adds --disable-dev-shm-usage, so no executablePath config is needed - noSandbox: true is required in containers — Chromium's setuid sandbox needs kernel namespacing that's unavailable in Docker/Fly - The chromium apt package installs to /usr/bin/ which is outside the Fly Volume mount at /root, so it survives volume mounts and restarts - Image size increases ~200-250 MB due to Chromium and its dependencies - Existing instances need tools.profile: "full" to see the browser tool — the "messaging" profile (onboard default) doesn't include it. Fresh installs already get "full" via the startup script <!-- Optional: reviewer focus areas, edge cases, or context that helps review quickly. -->
2 parents 49aa8cc + 44f9876 commit f1a4612

5 files changed

Lines changed: 29 additions & 1 deletion

File tree

kiloclaw/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ENV NODE_VERSION=22.13.1
55
RUN apt-get update \
66
&& apt-get install -y --no-install-recommends \
77
ca-certificates curl gnupg git xz-utils unzip jq ripgrep rsync zstd \
8-
build-essential python3 ffmpeg tmux \
8+
build-essential python3 ffmpeg tmux chromium \
99
&& ARCH="$(dpkg --print-architecture)" \
1010
&& case "${ARCH}" in \
1111
amd64) NODE_ARCH="x64" ;; \

kiloclaw/controller/src/config-writer.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,11 @@ describe('generateBaseConfig', () => {
9292
expect(config.tools.exec.host).toBe('gateway');
9393
expect(config.tools.exec.security).toBe('allowlist');
9494
expect(config.tools.exec.ask).toBe('on-miss');
95+
96+
// Browser
97+
expect(config.browser.enabled).toBe(true);
98+
expect(config.browser.headless).toBe(true);
99+
expect(config.browser.noSandbox).toBe(true);
95100
});
96101

97102
it('always sets tool profile to full on restore', () => {

kiloclaw/controller/src/config-writer.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,14 @@ export function generateBaseConfig(
172172
config.tools.exec.security = 'allowlist';
173173
config.tools.exec.ask = 'on-miss';
174174

175+
// Browser: headless Chromium for the browser tool in Docker.
176+
// OpenClaw auto-detects /usr/bin/chromium and adds --disable-dev-shm-usage on Linux.
177+
// noSandbox is required in containers (Chromium's setuid sandbox needs kernel namespacing).
178+
config.browser = config.browser ?? {};
179+
config.browser.enabled = true;
180+
config.browser.headless = true;
181+
config.browser.noSandbox = true;
182+
175183
// Telegram
176184
if (env.TELEGRAM_BOT_TOKEN) {
177185
const dmPolicy = env.TELEGRAM_DM_POLICY || 'pairing';

kiloclaw/start-openclaw.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,14 @@ config.tools.exec.host = 'gateway';
268268
config.tools.exec.security = 'allowlist';
269269
config.tools.exec.ask = 'on-miss';
270270
271+
// Browser: headless Chromium for the browser tool in Docker.
272+
// OpenClaw auto-detects /usr/bin/chromium and adds --disable-dev-shm-usage on Linux.
273+
// noSandbox is required in containers (Chromium's setuid sandbox needs kernel namespacing).
274+
config.browser = config.browser || {};
275+
config.browser.enabled = true;
276+
config.browser.headless = true;
277+
config.browser.noSandbox = true;
278+
271279
// Telegram configuration
272280
// Overwrite entire channel object to drop stale keys that would fail
273281
// OpenClaw's strict config validation (matches moltworker behavior)

src/app/(app)/claw/components/changelog-data.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@ export type ChangelogEntry = {
1010

1111
// Newest entries first. Developers add new entries to the top of this array.
1212
export const CHANGELOG_ENTRIES: ChangelogEntry[] = [
13+
{
14+
date: '2026-03-09',
15+
description:
16+
'Added headless Chromium browser support. OpenClaw\'s built-in browser tool now works out of the box for web browsing, screenshots, and CDP automation. Requires the "full" tool profile.',
17+
category: 'feature',
18+
deployHint: 'redeploy_required',
19+
},
1320
{
1421
date: '2026-03-05',
1522
description:

0 commit comments

Comments
 (0)