From 48d352a14261ea16d2f0330b3022d8133fd09718 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:46:03 +0200 Subject: [PATCH 1/8] feat: add Docker Sandboxes announcement to README Replace the Agent Swarms / Claude Code lines at the top with a prominent Docker Sandboxes announcement section including install commands and a link to the blog post. Co-Authored-By: Claude Opus 4.6 --- README.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index e0e167d..3443b92 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,23 @@ Discord  โ€ข   34.9k tokens, 17% of context window

-Using Claude Code, NanoClaw can dynamically rewrite its code to customize its feature set for your needs. -**New:** First AI assistant to support [Agent Swarms](https://code.claude.com/docs/en/agent-teams). Spin up teams of agents that collaborate in your chat. +
+
+

๐Ÿณ Now Running in Docker Sandboxes

+

Every agent gets its own isolated container inside a micro VM.
Hypervisor-level isolation. Millisecond startup. No complex setup.

+ +```bash +# macOS (Apple Silicon) +curl -fsSL https://nanoclaw.dev/install-docker-sandboxes.sh | bash + +# Windows (WSL) +curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash +``` + +

Read the announcement โ†’

+
+
## Why I Built NanoClaw @@ -70,8 +84,8 @@ Then run `/setup`. Claude Code handles everything: dependencies, authentication, - **Main channel** - Your private channel (self-chat) for admin control; every group is completely isolated - **Scheduled tasks** - Recurring jobs that run Claude and can message you back - **Web access** - Search and fetch content from the Web -- **Container isolation** - Agents are sandboxed in Apple Container (macOS) or Docker (macOS/Linux) -- **Agent Swarms** - Spin up teams of specialized agents that collaborate on complex tasks. NanoClaw is the first personal AI assistant to support agent swarms. +- **Container isolation** - Agents are sandboxed in [Docker Sandboxes](https://nanoclaw.dev/blog/nanoclaw-docker-sandboxes) (micro VM isolation), Apple Container (macOS), or Docker (macOS/Linux) +- **Agent Swarms** - Spin up teams of specialized agents that collaborate on complex tasks - **Optional integrations** - Add Gmail (`/add-gmail`) and more via skills ## Usage From 49595b9c700e052902590c6e1bf079bab9f2f6d4 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:48:10 +0200 Subject: [PATCH 2/8] fix: separate install commands into individual code blocks Allows each curl command to be copied independently without the comment line. Co-Authored-By: Claude Opus 4.6 --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3443b92..51a9f95 100644 --- a/README.md +++ b/README.md @@ -18,11 +18,13 @@

๐Ÿณ Now Running in Docker Sandboxes

Every agent gets its own isolated container inside a micro VM.
Hypervisor-level isolation. Millisecond startup. No complex setup.

+**macOS (Apple Silicon)** ```bash -# macOS (Apple Silicon) curl -fsSL https://nanoclaw.dev/install-docker-sandboxes.sh | bash +``` -# Windows (WSL) +**Windows (WSL)** +```bash curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash ``` From 2a90f9813820a4af67b5d4a8aa614de45384d667 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:49:01 +0200 Subject: [PATCH 3/8] fix: add supported platforms note to Docker Sandboxes section Co-Authored-By: Claude Opus 4.6 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 51a9f95..d7f440e 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,8 @@ curl -fsSL https://nanoclaw.dev/install-docker-sandboxes.sh | bash curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash ``` +

Currently supported on macOS (Apple Silicon) and Windows (x86). Linux support coming soon.

+

Read the announcement โ†’


From 3414625a6db6d5ba23b99fc98248b0eb5f1433ec Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:55:27 +0200 Subject: [PATCH 4/8] fix: left-align install commands in announcement section Keep heading and description centered, but left-align the install blocks and labels so they don't clash with the code block layout. Co-Authored-By: Claude Opus 4.6 --- README.md | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index d7f440e..b93abbb 100644 --- a/README.md +++ b/README.md @@ -13,10 +13,8 @@ 34.9k tokens, 17% of context window

-
-
-

๐Ÿณ Now Running in Docker Sandboxes

-

Every agent gets its own isolated container inside a micro VM.
Hypervisor-level isolation. Millisecond startup. No complex setup.

+

๐Ÿณ Now Running in Docker Sandboxes

+

Every agent gets its own isolated container inside a micro VM.
Hypervisor-level isolation. Millisecond startup. No complex setup.

**macOS (Apple Silicon)** ```bash @@ -28,11 +26,9 @@ curl -fsSL https://nanoclaw.dev/install-docker-sandboxes.sh | bash curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash ``` -

Currently supported on macOS (Apple Silicon) and Windows (x86). Linux support coming soon.

+> Currently supported on macOS (Apple Silicon) and Windows (x86). Linux support coming soon. -

Read the announcement โ†’

-
-
+

Read the announcement โ†’

## Why I Built NanoClaw From c7391757ac7c399af28dc06d411a939bf017435b Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:56:14 +0200 Subject: [PATCH 5/8] fix: add divider between badges and announcement section Co-Authored-By: Claude Opus 4.6 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b93abbb..853d30e 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ 34.9k tokens, 17% of context window

+--- +

๐Ÿณ Now Running in Docker Sandboxes

Every agent gets its own isolated container inside a micro VM.
Hypervisor-level isolation. Millisecond startup. No complex setup.

From 6f64b31d03182ca9548e7ea4af4c15591357ef5a Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 11:57:07 +0200 Subject: [PATCH 6/8] fix: add divider after announcement section Co-Authored-By: Claude Opus 4.6 --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 853d30e..ddc498a 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash

Read the announcement โ†’

+--- + ## Why I Built NanoClaw [OpenClaw](https://github.com/openclaw/openclaw) is an impressive project, but I wouldn't have been able to sleep if I had given complex software I didn't understand full access to my life. OpenClaw has nearly half a million lines of code, 53 config files, and 70+ dependencies. Its security is at the application level (allowlists, pairing codes) rather than true OS-level isolation. Everything runs in one Node process with shared memory. From e6ff5c640c921068c092331382030f8a2fd86d00 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 12:02:15 +0200 Subject: [PATCH 7/8] feat: add manual Docker Sandboxes setup guide MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step-by-step guide for running NanoClaw in Docker Sandboxes from scratch without the install script. Covers proxy patches, DinD mount fixes, channel setup, networking details, and troubleshooting. Validated on macOS (Apple Silicon) with WhatsApp โ€” other channels and environments may need additional proxy patches. Co-Authored-By: Claude Opus 4.6 --- README.md | 2 +- docs/docker-sandboxes.md | 359 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 360 insertions(+), 1 deletion(-) create mode 100644 docs/docker-sandboxes.md diff --git a/README.md b/README.md index ddc498a..1e5401f 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ curl -fsSL https://nanoclaw.dev/install-docker-sandboxes-windows.sh | bash > Currently supported on macOS (Apple Silicon) and Windows (x86). Linux support coming soon. -

Read the announcement โ†’

+

Read the announcement โ†’  ยท  Manual setup guide โ†’

--- diff --git a/docs/docker-sandboxes.md b/docs/docker-sandboxes.md new file mode 100644 index 0000000..77dad83 --- /dev/null +++ b/docs/docker-sandboxes.md @@ -0,0 +1,359 @@ +# Running NanoClaw in Docker Sandboxes (Manual Setup) + +This guide walks through setting up NanoClaw inside a [Docker Sandbox](https://docs.docker.com/security/sandbox/) from scratch โ€” no install script, no pre-built fork. You'll clone the upstream repo, apply the necessary patches, and have agents running in full hypervisor-level isolation. + +## Architecture + +``` +Host (macOS / Windows WSL) +โ””โ”€โ”€ Docker Sandbox (micro VM with isolated kernel) + โ”œโ”€โ”€ NanoClaw process (Node.js) + โ”‚ โ”œโ”€โ”€ Channel adapters (WhatsApp, Telegram, etc.) + โ”‚ โ””โ”€โ”€ Container spawner โ†’ nested Docker daemon + โ””โ”€โ”€ Docker-in-Docker + โ””โ”€โ”€ nanoclaw-agent containers + โ””โ”€โ”€ Claude Agent SDK +``` + +Each agent runs in its own container, inside a micro VM that is fully isolated from your host. Two layers of isolation: per-agent containers + the VM boundary. + +The sandbox provides a MITM proxy at `host.docker.internal:3128` that handles network access and injects your Anthropic API key automatically. + +> **Note:** This guide is based on a validated setup running on macOS (Apple Silicon) with WhatsApp. Other channels (Telegram, Slack, etc.) and environments (Windows WSL) may require additional proxy patches for their specific HTTP/WebSocket clients. The core patches (container runner, credential proxy, Dockerfile) apply universally โ€” channel-specific proxy configuration varies. + +## Prerequisites + +- **Docker Desktop v4.40+** with Sandbox support +- **Anthropic API key** (the sandbox proxy manages injection) +- For **Telegram**: a bot token from [@BotFather](https://t.me/BotFather) and your chat ID +- For **WhatsApp**: a phone with WhatsApp installed + +Verify sandbox support: +```bash +docker sandbox version +``` + +## Step 1: Create the Sandbox + +On your host machine: + +```bash +# Create a workspace directory +mkdir -p ~/nanoclaw-workspace + +# Create a shell sandbox with the workspace mounted +docker sandbox create shell ~/nanoclaw-workspace +``` + +If you're using WhatsApp, configure proxy bypass so WhatsApp's Noise protocol isn't MITM-inspected: + +```bash +docker sandbox network proxy shell-nanoclaw-workspace \ + --bypass-host web.whatsapp.com \ + --bypass-host "*.whatsapp.com" \ + --bypass-host "*.whatsapp.net" +``` + +Telegram does not need proxy bypass. + +Enter the sandbox: +```bash +docker sandbox run shell-nanoclaw-workspace +``` + +## Step 2: Install Prerequisites + +Inside the sandbox: + +```bash +sudo apt-get update && sudo apt-get install -y build-essential python3 +npm config set strict-ssl false +``` + +## Step 3: Clone and Install NanoClaw + +NanoClaw must live inside the workspace directory โ€” Docker-in-Docker can only bind-mount from the shared workspace path. + +```bash +# Clone to home first (virtiofs can corrupt git pack files during clone) +cd ~ +git clone https://github.com/qwibitai/nanoclaw.git + +# Replace with YOUR workspace path (the host path you passed to `docker sandbox create`) +WORKSPACE=/Users/you/nanoclaw-workspace + +# Move into workspace so DinD mounts work +mv nanoclaw "$WORKSPACE/nanoclaw" +cd "$WORKSPACE/nanoclaw" + +# Install dependencies +npm install +npm install https-proxy-agent +``` + +## Step 4: Apply Proxy and Sandbox Patches + +NanoClaw needs several patches to work inside a Docker Sandbox. These handle proxy routing, CA certificates, and Docker-in-Docker mount restrictions. + +### 4a. Dockerfile โ€” proxy args for container image build + +`npm install` inside `docker build` fails with `SELF_SIGNED_CERT_IN_CHAIN` because the sandbox's MITM proxy presents its own certificate. Add proxy build args to `container/Dockerfile`: + +Add these lines after the `FROM` line: + +```dockerfile +# Accept proxy build args +ARG http_proxy +ARG https_proxy +ARG no_proxy +ARG NODE_EXTRA_CA_CERTS +ARG npm_config_strict_ssl=true +RUN npm config set strict-ssl ${npm_config_strict_ssl} +``` + +And after the `RUN npm install` line: + +```dockerfile +RUN npm config set strict-ssl true +``` + +### 4b. Build script โ€” forward proxy args + +Patch `container/build.sh` to pass proxy env vars to `docker build`: + +Add these `--build-arg` flags to the `docker build` command: + +```bash +--build-arg http_proxy="${http_proxy:-$HTTP_PROXY}" \ +--build-arg https_proxy="${https_proxy:-$HTTPS_PROXY}" \ +--build-arg no_proxy="${no_proxy:-$NO_PROXY}" \ +--build-arg npm_config_strict_ssl=false \ +``` + +### 4c. Container runner โ€” proxy forwarding, CA cert mount, /dev/null fix + +Three changes to `src/container-runner.ts`: + +**Replace `/dev/null` shadow mount.** The sandbox rejects `/dev/null` bind mounts. Find where `.env` is shadow-mounted to `/dev/null` and replace it with an empty file: + +```typescript +// Create an empty file to shadow .env (Docker Sandbox rejects /dev/null mounts) +const emptyEnvPath = path.join(DATA_DIR, 'empty-env'); +if (!fs.existsSync(emptyEnvPath)) fs.writeFileSync(emptyEnvPath, ''); +// Use emptyEnvPath instead of '/dev/null' in the mount +``` + +**Forward proxy env vars** to spawned agent containers. Add `-e` flags for `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY` and their lowercase variants. + +**Mount CA certificate.** If `NODE_EXTRA_CA_CERTS` or `SSL_CERT_FILE` is set, copy the cert into the project directory and mount it into agent containers: + +```typescript +const caCertSrc = process.env.NODE_EXTRA_CA_CERTS || process.env.SSL_CERT_FILE; +if (caCertSrc) { + const certDir = path.join(DATA_DIR, 'ca-cert'); + fs.mkdirSync(certDir, { recursive: true }); + fs.copyFileSync(caCertSrc, path.join(certDir, 'proxy-ca.crt')); + // Mount: certDir -> /workspace/ca-cert (read-only) + // Set NODE_EXTRA_CA_CERTS=/workspace/ca-cert/proxy-ca.crt in the container +} +``` + +### 4d. Container runtime โ€” prevent self-termination + +In `src/container-runtime.ts`, the `cleanupOrphans()` function matches containers by the `nanoclaw-` prefix. Inside a sandbox, the sandbox container itself may match (e.g., `nanoclaw-docker-sandbox`). Filter out the current hostname: + +```typescript +// In cleanupOrphans(), filter out os.hostname() from the list of containers to stop +``` + +### 4e. Credential proxy โ€” route through MITM proxy + +In `src/credential-proxy.ts`, upstream API requests need to go through the sandbox proxy. Add `HttpsProxyAgent` to outbound requests: + +```typescript +import { HttpsProxyAgent } from 'https-proxy-agent'; + +const proxyUrl = process.env.HTTPS_PROXY || process.env.https_proxy; +const upstreamAgent = proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; +// Pass upstreamAgent to https.request() options +``` + +### 4f. Setup script โ€” proxy build args + +Patch `setup/container.ts` to pass the same proxy `--build-arg` flags as `build.sh` (Step 4b). + +## Step 5: Build + +```bash +npm run build +bash container/build.sh +``` + +## Step 6: Add a Channel + +### Telegram + +```bash +# Apply the Telegram skill +npx tsx scripts/apply-skill.ts .claude/skills/add-telegram + +# Rebuild after applying the skill +npm run build + +# Configure .env +cat > .env << EOF +TELEGRAM_BOT_TOKEN= +ASSISTANT_NAME=nanoclaw +ANTHROPIC_API_KEY=proxy-managed +EOF +mkdir -p data/env && cp .env data/env/env + +# Register your chat +npx tsx setup/index.ts --step register \ + --jid "tg:" \ + --name "My Chat" \ + --trigger "@nanoclaw" \ + --folder "telegram_main" \ + --channel telegram \ + --assistant-name "nanoclaw" \ + --is-main \ + --no-trigger-required +``` + +**To find your chat ID:** Send any message to your bot, then: +```bash +curl -s --proxy $HTTPS_PROXY "https://api.telegram.org/bot/getUpdates" | python3 -m json.tool +``` + +**Telegram in groups:** Disable Group Privacy in @BotFather (`/mybots` > Bot Settings > Group Privacy > Turn off), then remove and re-add the bot. + +**Important:** If the Telegram skill creates `src/channels/telegram.ts`, you'll need to patch it for proxy support. Add an `HttpsProxyAgent` and pass it to grammy's `Bot` constructor via `baseFetchConfig.agent`. Then rebuild. + +### WhatsApp + +Make sure you configured proxy bypass in [Step 1](#step-1-create-the-sandbox) first. + +```bash +# Apply the WhatsApp skill +npx tsx scripts/apply-skill.ts .claude/skills/add-whatsapp + +# Rebuild +npm run build + +# Configure .env +cat > .env << EOF +ASSISTANT_NAME=nanoclaw +ANTHROPIC_API_KEY=proxy-managed +EOF +mkdir -p data/env && cp .env data/env/env + +# Authenticate (choose one): + +# QR code โ€” scan with WhatsApp camera: +npx tsx src/whatsapp-auth.ts + +# OR pairing code โ€” enter code in WhatsApp > Linked Devices > Link with phone number: +npx tsx src/whatsapp-auth.ts --pairing-code --phone + +# Register your chat (JID = your phone number + @s.whatsapp.net) +npx tsx setup/index.ts --step register \ + --jid "@s.whatsapp.net" \ + --name "My Chat" \ + --trigger "@nanoclaw" \ + --folder "whatsapp_main" \ + --channel whatsapp \ + --assistant-name "nanoclaw" \ + --is-main \ + --no-trigger-required +``` + +**Important:** The WhatsApp skill files (`src/channels/whatsapp.ts` and `src/whatsapp-auth.ts`) also need proxy patches โ€” add `HttpsProxyAgent` for WebSocket connections and a proxy-aware version fetch. Then rebuild. + +### Both Channels + +Apply both skills, patch both for proxy support, combine the `.env` variables, and register each chat separately. + +## Step 7: Run + +```bash +npm start +``` + +You don't need to set `ANTHROPIC_API_KEY` manually. The sandbox proxy intercepts requests and replaces `proxy-managed` with your real key automatically. + +## Networking Details + +### How the proxy works + +All traffic from the sandbox routes through the host proxy at `host.docker.internal:3128`: + +``` +Agent container โ†’ DinD bridge โ†’ Sandbox VM โ†’ host.docker.internal:3128 โ†’ Host proxy โ†’ api.anthropic.com +``` + +**"Bypass" does not mean traffic skips the proxy.** It means the proxy passes traffic through without MITM inspection. Node.js doesn't automatically use `HTTP_PROXY` env vars โ€” you need explicit `HttpsProxyAgent` configuration in every HTTP/WebSocket client. + +### Shared paths for DinD mounts + +Only the workspace directory is available for Docker-in-Docker bind mounts. Paths outside the workspace fail with "path not shared": +- `/dev/null` โ†’ replace with an empty file in the project dir +- `/usr/local/share/ca-certificates/` โ†’ copy cert to project dir +- `/home/agent/` โ†’ clone to workspace instead + +### Git clone and virtiofs + +The workspace is mounted via virtiofs. Git's pack file handling can corrupt over virtiofs during clone. Workaround: clone to `/home/agent` first, then `mv` into the workspace. + +## Troubleshooting + +### npm install fails with SELF_SIGNED_CERT_IN_CHAIN +```bash +npm config set strict-ssl false +``` + +### Container build fails with proxy errors +```bash +docker build \ + --build-arg http_proxy=$http_proxy \ + --build-arg https_proxy=$https_proxy \ + -t nanoclaw-agent:latest container/ +``` + +### Agent containers fail with "path not shared" +All bind-mounted paths must be under the workspace directory. Check: +- Is NanoClaw cloned into the workspace? (not `/home/agent/`) +- Is the CA cert copied to the project root? +- Has the empty `.env` shadow file been created? + +### Agent containers can't reach Anthropic API +Verify proxy env vars are forwarded to agent containers. Check container logs for `HTTP_PROXY=http://host.docker.internal:3128`. + +### WhatsApp error 405 +The version fetch is returning a stale version. Make sure the proxy-aware `fetchWaVersionViaProxy` patch is applied โ€” it fetches `sw.js` through `HttpsProxyAgent` and parses `client_revision`. + +### WhatsApp "Connection failed" immediately +Proxy bypass not configured. From the **host**, run: +```bash +docker sandbox network proxy \ + --bypass-host web.whatsapp.com \ + --bypass-host "*.whatsapp.com" \ + --bypass-host "*.whatsapp.net" +``` + +### Telegram bot doesn't receive messages +1. Check the grammy proxy patch is applied (look for `HttpsProxyAgent` in `src/channels/telegram.ts`) +2. Check Group Privacy is disabled in @BotFather if using in groups + +### Git clone fails with "inflate: data stream error" +Clone to a non-workspace path first, then move: +```bash +cd ~ && git clone https://github.com/qwibitai/nanoclaw.git && mv nanoclaw /path/to/workspace/nanoclaw +``` + +### WhatsApp QR code doesn't display +Run the auth command interactively inside the sandbox (not piped through `docker sandbox exec`): +```bash +docker sandbox run shell-nanoclaw-workspace +# Then inside: +npx tsx src/whatsapp-auth.ts +``` From df9ba0e5f92be15e15872faece9a789c93662f53 Mon Sep 17 00:00:00 2001 From: gavrielc Date: Fri, 13 Mar 2026 12:03:27 +0200 Subject: [PATCH 8/8] fix: correct Docker Sandboxes documentation URL Co-Authored-By: Claude Opus 4.6 --- docs/docker-sandboxes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docker-sandboxes.md b/docs/docker-sandboxes.md index 77dad83..e887bad 100644 --- a/docs/docker-sandboxes.md +++ b/docs/docker-sandboxes.md @@ -1,6 +1,6 @@ # Running NanoClaw in Docker Sandboxes (Manual Setup) -This guide walks through setting up NanoClaw inside a [Docker Sandbox](https://docs.docker.com/security/sandbox/) from scratch โ€” no install script, no pre-built fork. You'll clone the upstream repo, apply the necessary patches, and have agents running in full hypervisor-level isolation. +This guide walks through setting up NanoClaw inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) from scratch โ€” no install script, no pre-built fork. You'll clone the upstream repo, apply the necessary patches, and have agents running in full hypervisor-level isolation. ## Architecture