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
1 change: 1 addition & 0 deletions advanced/container-runtime.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
| Health check | `docker info` | `container system status` |
| Platform | macOS, Linux, Windows (WSL2) | macOS 15+ only |

### Switching runtimes

Check warning on line 48 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L48

Did you really mean 'runtimes'?

Run the `/convert-to-apple-container` skill in Claude Code. To revert, use `git revert`.

Expand All @@ -57,15 +57,15 @@
- **Bun** (pinned to 1.3.12) — runs agent-runner TypeScript directly (no compilation)
- **Chromium** — browser automation via agent-browser
- **Claude Code SDK** — `@anthropic-ai/claude-code` installed globally via pnpm
- **tini** — PID 1 signal forwarding (ensures outbound.db writes finalize on SIGTERM)

Check warning on line 60 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L60

Did you really mean 'tini'?
- **pnpm** (via corepack) — for global Node CLI installs

Check warning on line 61 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L61

Did you really mean 'corepack'?
- **System tools** — `curl`, `git`, `ca-certificates`, `unzip`
- **Optional CJK fonts** — `fonts-noto-cjk` (~200 MB, opt-in via `INSTALL_CJK_FONTS=true`)

### Key design decisions

- **Source is NOT baked in** — `/app/src` is a read-only bind mount from the host. Source changes never require an image rebuild.
- **`only-built-dependencies` allowlist** in `.npmrc` for `agent-browser` and `@anthropic-ai/claude-code`

Check warning on line 68 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L68

Did you really mean 'allowlist'?
- **Runs as `node` user** (non-root) with `/workspace/group` as working directory
- **Entrypoint**: `tini -> entrypoint.sh -> exec bun run /app/src/index.ts`

Expand All @@ -82,6 +82,7 @@
- Tag: derived from the checkout-scoped base image and agent group
- Built on top of `nanoclaw-agent-v2-<slug>:latest`
- Adds custom apt and npm packages
- Build timeout: 15 minutes (accommodates large apt/npm package installs on slow networks)

## Two-database IO model

Expand All @@ -94,7 +95,7 @@
| `messages_in` | Inbound messages, tasks, system notifications |
| `delivered` | Tracks delivery outcomes for outbound message IDs |
| `destinations` | Live destination map (channels and other agents) |
| `session_routing` | Default reply routing (channel_type, platform_id, thread_id) |

Check warning on line 98 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L98

Did you really mean 'channel_type'?

Check warning on line 98 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L98

Did you really mean 'platform_id'?

Check warning on line 98 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L98

Did you really mean 'thread_id'?

### outbound.db (container writes, host reads)

Expand All @@ -109,7 +110,7 @@

Three invariants are critical for correctness:

1. **`journal_mode=DELETE`** — WAL's mmapped `-shm` doesn't refresh across Docker mounts

Check warning on line 113 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L113

Did you really mean 'WAL's'?

Check warning on line 113 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L113

Did you really mean 'mmapped'?
2. **Host opens-writes-closes per operation** — closing invalidates the container's page cache
3. **One writer per file** — DELETE-mode journal unlink isn't atomic across the mount

Expand All @@ -117,7 +118,7 @@

### Spawning containers

Containers are spawned by the `spawnContainer` function. Wake calls are deduplicated via an in-flight promise map.

Check warning on line 121 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L121

Did you really mean 'deduplicated'?

<Steps>
<Step title="Read agent group config">
Expand Down Expand Up @@ -157,7 +158,7 @@
| Agent-runner source | `/app/src` | RO | Bind mount from host |
| Container skills | `/app/skills` | RO | Shared skill definitions |
| Claude SDK state | `/home/node/.claude` | RW | SDK state + skill symlinks |
| Additional mounts | `/workspace/extra/{name}` | Per-config | Validated against allowlist |

Check warning on line 161 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L161

Did you really mean 'allowlist'?
| Provider mounts | Various | Per-provider | Provider-contributed |

### Timeouts and stale detection
Expand All @@ -165,7 +166,7 @@
Containers have two timeout/detection mechanisms:

1. **Container timeout** — maximum runtime before force kill (default: 30 minutes)
2. **Stale detection** — host sweep checks `.heartbeat` mtime and `processing_ack` age to detect stuck containers

Check warning on line 169 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L169

Did you really mean 'mtime'?

### Container shutdown

Expand Down Expand Up @@ -204,7 +205,7 @@

<Accordion title="Inspect container mounts">
```bash
docker inspect nanoclaw-{session-id} | jq '.[0].Mounts'

Check warning on line 208 in advanced/container-runtime.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

advanced/container-runtime.mdx#L208

Did you really mean 'jq'?
```
</Accordion>

Expand Down
1 change: 1 addition & 0 deletions concepts/containers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
tag: "UPDATED"
---

NanoClaw runs all agents inside containers (lightweight Linux VMs) to provide true OS-level isolation. This is the primary security boundary that makes Bash access and code execution safe.

Check warning on line 7 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L7

Did you really mean 'VMs'?

## Why containers?

Expand Down Expand Up @@ -34,7 +34,7 @@
- **Tools**: `agent-browser` for browser automation, `vercel` CLI, `curl`, `git`
- **SDK**: `@anthropic-ai/claude-code` installed globally via pnpm
- **PID 1**: `tini` for proper signal forwarding so `outbound.db` writes finalize on SIGTERM
- **User**: `node` (uid 1000, non-root)

Check warning on line 37 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L37

Did you really mean 'uid'?
- **Working directory**: `/workspace/group`

<Note>
Expand All @@ -45,7 +45,7 @@

The entrypoint uses `tini` for signal forwarding:

1. **tini** starts as PID 1 (forwards signals cleanly)

Check warning on line 48 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L48

Did you really mean 'tini'?
2. **entrypoint.sh** runs setup scripts
3. **Bun executes agent-runner**: `exec bun run /app/src/index.ts`
4. Agent-runner polls `inbound.db` for messages and writes responses to `outbound.db`
Expand Down Expand Up @@ -82,7 +82,7 @@
| Agent-runner source | `/app/src` | Read-only | Shared source (bind mount from host) |
| Container skills | `/app/skills` | Read-only | Shared skill definitions |
| Claude SDK state | `/home/node/.claude` | Read-write | SDK state + skill symlinks |
| Additional mounts | `/workspace/extra/{name}` | Per-config | From `container.json` (validated against allowlist) |

Check warning on line 85 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L85

Did you really mean 'allowlist'?

<Warning>
The `container.json` file is mounted read-only as a nested mount inside the read-write agent group folder. This prevents the agent from modifying its own container configuration.
Expand All @@ -90,7 +90,7 @@

### Mount security

All additional mounts are validated against the allowlist at `~/.config/nanoclaw/mount-allowlist.json`:

Check warning on line 93 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L93

Did you really mean 'allowlist'?

```json
{
Expand All @@ -101,7 +101,7 @@
"description": "Development projects"
}
],
"blockedPatterns": ["password", "secret", "token"]

Check warning on line 104 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L104

Did you really mean 'blockedPatterns'?
}
```

Expand Down Expand Up @@ -154,6 +154,7 @@
- Image tag: derived from the checkout-scoped base image and agent group
- Built on top of the base `nanoclaw-agent-v2-<slug>:latest` image
- Cached — only rebuilt when package lists change
- Image build is bounded by a 15-minute timeout to allow for large package installs

## Timeouts

Expand Down Expand Up @@ -206,7 +207,7 @@
- **Headless**: always (no display in container)
- **User data**: stored in group folder (persists across runs)
- **Network**: full access (same as host, no restrictions)
- **Optional CJK fonts**: install via `INSTALL_CJK_FONTS=true` build arg (~200 MB)

Check warning on line 210 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L210

Did you really mean 'arg'?

## Security implications

Expand All @@ -219,13 +220,13 @@

### What containers DON'T protect against

- **Network access** — agents have full network access (can exfiltrate data)

Check warning on line 223 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L223

Did you really mean 'exfiltrate'?
- **Mounted directory tampering** — agents can modify anything in mounted read-write directories
- **Vault-based API access** — containers can make authenticated API requests through the OneCLI vault (though they cannot extract real credentials)
- **Resource exhaustion** — no CPU/memory limits enforced (can DoS host)

<Warning>
Containers provide filesystem isolation, not network isolation. Agents can make arbitrary HTTP requests and exfiltrate data over the network.

Check warning on line 229 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L229

Did you really mean 'exfiltrate'?
</Warning>

## Troubleshooting
Expand All @@ -246,7 +247,7 @@

1. Check mount paths are readable by host user
2. Check uid/gid mapping
3. Verify allowlist includes path (for additional mounts)

Check warning on line 250 in concepts/containers.mdx

View check run for this annotation

Mintlify / Mintlify Validation (qwibitai-nanoclaw-8) - vale-spellcheck

concepts/containers.mdx#L250

Did you really mean 'allowlist'?
4. Check symlink resolution didn't change path

## Related topics
Expand Down