From 993a94bab54df59e4613f629ac9280e0cbd1aa8c Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Fri, 16 Jan 2026 15:40:00 +0100 Subject: [PATCH 1/2] vendor: docker sandboxes v0.7.1 cli docs Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- .../reference/cli/docker/sandbox/create.md | 6 + .../cli/docker/sandbox/create/cagent.md | 6 + .../cli/docker/sandbox/create/codex.md | 6 + .../cli/docker/sandbox/create/gemini.md | 6 + .../cli/docker/sandbox/create/kiro.md | 6 + content/reference/cli/docker/sandbox/exec.md | 6 + .../cli/docker/sandbox/network/_index.md | 6 + .../cli/docker/sandbox/network/log.md | 6 + .../cli/docker/sandbox/network/proxy.md | 6 + content/reference/cli/docker/sandbox/reset.md | 6 + content/reference/cli/docker/sandbox/stop.md | 6 + data/sandbox-cli/docker_sandbox.yaml | 22 ++- data/sandbox-cli/docker_sandbox_create.yaml | 94 +++++++++++++ .../docker_sandbox_create_cagent.yaml | 40 ++++++ .../docker_sandbox_create_claude.yaml | 51 +++++++ .../docker_sandbox_create_codex.yaml | 40 ++++++ .../docker_sandbox_create_gemini.yaml | 40 ++++++ .../docker_sandbox_create_kiro.yaml | 40 ++++++ data/sandbox-cli/docker_sandbox_exec.yaml | 132 ++++++++++++++++++ data/sandbox-cli/docker_sandbox_ls.yaml | 90 +++++++++--- data/sandbox-cli/docker_sandbox_network.yaml | 41 ++++++ .../docker_sandbox_network_log.yaml | 67 +++++++++ .../docker_sandbox_network_proxy.yaml | 102 ++++++++++++++ data/sandbox-cli/docker_sandbox_reset.yaml | 61 ++++++++ data/sandbox-cli/docker_sandbox_rm.yaml | 19 ++- data/sandbox-cli/docker_sandbox_run.yaml | 117 ++++------------ data/sandbox-cli/docker_sandbox_stop.yaml | 36 +++++ data/sandbox-cli/docker_sandbox_version.yaml | 14 +- 28 files changed, 957 insertions(+), 115 deletions(-) create mode 100644 content/reference/cli/docker/sandbox/create.md create mode 100644 content/reference/cli/docker/sandbox/create/cagent.md create mode 100644 content/reference/cli/docker/sandbox/create/codex.md create mode 100644 content/reference/cli/docker/sandbox/create/gemini.md create mode 100644 content/reference/cli/docker/sandbox/create/kiro.md create mode 100644 content/reference/cli/docker/sandbox/exec.md create mode 100644 content/reference/cli/docker/sandbox/network/_index.md create mode 100644 content/reference/cli/docker/sandbox/network/log.md create mode 100644 content/reference/cli/docker/sandbox/network/proxy.md create mode 100644 content/reference/cli/docker/sandbox/reset.md create mode 100644 content/reference/cli/docker/sandbox/stop.md create mode 100644 data/sandbox-cli/docker_sandbox_create.yaml create mode 100644 data/sandbox-cli/docker_sandbox_create_cagent.yaml create mode 100644 data/sandbox-cli/docker_sandbox_create_claude.yaml create mode 100644 data/sandbox-cli/docker_sandbox_create_codex.yaml create mode 100644 data/sandbox-cli/docker_sandbox_create_gemini.yaml create mode 100644 data/sandbox-cli/docker_sandbox_create_kiro.yaml create mode 100644 data/sandbox-cli/docker_sandbox_exec.yaml create mode 100644 data/sandbox-cli/docker_sandbox_network.yaml create mode 100644 data/sandbox-cli/docker_sandbox_network_log.yaml create mode 100644 data/sandbox-cli/docker_sandbox_network_proxy.yaml create mode 100644 data/sandbox-cli/docker_sandbox_reset.yaml create mode 100644 data/sandbox-cli/docker_sandbox_stop.yaml diff --git a/content/reference/cli/docker/sandbox/create.md b/content/reference/cli/docker/sandbox/create.md new file mode 100644 index 000000000000..84fa5bff7e7a --- /dev/null +++ b/content/reference/cli/docker/sandbox/create.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_create +title: docker sandbox create +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/create/cagent.md b/content/reference/cli/docker/sandbox/create/cagent.md new file mode 100644 index 000000000000..6e591150fcca --- /dev/null +++ b/content/reference/cli/docker/sandbox/create/cagent.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_create_cagent +title: docker sandbox create cagent +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/create/codex.md b/content/reference/cli/docker/sandbox/create/codex.md new file mode 100644 index 000000000000..ffd660d6ddee --- /dev/null +++ b/content/reference/cli/docker/sandbox/create/codex.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_create_codex +title: docker sandbox create codex +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/create/gemini.md b/content/reference/cli/docker/sandbox/create/gemini.md new file mode 100644 index 000000000000..e047236c5e82 --- /dev/null +++ b/content/reference/cli/docker/sandbox/create/gemini.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_create_gemini +title: docker sandbox create gemini +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/create/kiro.md b/content/reference/cli/docker/sandbox/create/kiro.md new file mode 100644 index 000000000000..2acff8995527 --- /dev/null +++ b/content/reference/cli/docker/sandbox/create/kiro.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_create_kiro +title: docker sandbox create kiro +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/exec.md b/content/reference/cli/docker/sandbox/exec.md new file mode 100644 index 000000000000..48ef9655da8c --- /dev/null +++ b/content/reference/cli/docker/sandbox/exec.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_exec +title: docker sandbox exec +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/network/_index.md b/content/reference/cli/docker/sandbox/network/_index.md new file mode 100644 index 000000000000..e9b8f8ad0522 --- /dev/null +++ b/content/reference/cli/docker/sandbox/network/_index.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_network +title: docker sandbox network +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/network/log.md b/content/reference/cli/docker/sandbox/network/log.md new file mode 100644 index 000000000000..038b8ebbad45 --- /dev/null +++ b/content/reference/cli/docker/sandbox/network/log.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_network_log +title: docker sandbox network log +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/network/proxy.md b/content/reference/cli/docker/sandbox/network/proxy.md new file mode 100644 index 000000000000..56fd1f5648a5 --- /dev/null +++ b/content/reference/cli/docker/sandbox/network/proxy.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_network_proxy +title: docker sandbox network proxy +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/reset.md b/content/reference/cli/docker/sandbox/reset.md new file mode 100644 index 000000000000..a2c80836e8f8 --- /dev/null +++ b/content/reference/cli/docker/sandbox/reset.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_reset +title: docker sandbox reset +layout: cli +--- diff --git a/content/reference/cli/docker/sandbox/stop.md b/content/reference/cli/docker/sandbox/stop.md new file mode 100644 index 000000000000..0048464da300 --- /dev/null +++ b/content/reference/cli/docker/sandbox/stop.md @@ -0,0 +1,6 @@ +--- +datafolder: sandbox-cli +datafile: docker_sandbox_stop +title: docker sandbox stop +layout: cli +--- diff --git a/data/sandbox-cli/docker_sandbox.yaml b/data/sandbox-cli/docker_sandbox.yaml index 151e981725a7..851e10ad871a 100644 --- a/data/sandbox-cli/docker_sandbox.yaml +++ b/data/sandbox-cli/docker_sandbox.yaml @@ -5,16 +5,24 @@ usage: docker sandbox pname: docker plink: docker.yaml cname: - - docker sandbox inspect + - docker sandbox create + - docker sandbox exec - docker sandbox ls + - docker sandbox network + - docker sandbox reset - docker sandbox rm - docker sandbox run + - docker sandbox stop - docker sandbox version clink: - - docker_sandbox_inspect.yaml + - docker_sandbox_create.yaml + - docker_sandbox_exec.yaml - docker_sandbox_ls.yaml + - docker_sandbox_network.yaml + - docker_sandbox_reset.yaml - docker_sandbox_rm.yaml - docker_sandbox_run.yaml + - docker_sandbox_stop.yaml - docker_sandbox_version.yaml options: - option: debug @@ -28,6 +36,16 @@ options: experimentalcli: false kubernetes: false swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false diff --git a/data/sandbox-cli/docker_sandbox_create.yaml b/data/sandbox-cli/docker_sandbox_create.yaml new file mode 100644 index 000000000000..ea3dbc0ed95e --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create.yaml @@ -0,0 +1,94 @@ +command: docker sandbox create +short: Create a sandbox for an agent +long: |- + Create a sandbox with access to a host workspace for an agent. + + Available agents are provided as subcommands. Use "create AGENT --help" for agent-specific options. +usage: docker sandbox create [OPTIONS] AGENT WORKSPACE +pname: docker sandbox +plink: docker_sandbox.yaml +cname: + - docker sandbox create cagent + - docker sandbox create claude + - docker sandbox create codex + - docker sandbox create gemini + - docker sandbox create kiro +clink: + - docker_sandbox_create_cagent.yaml + - docker_sandbox_create_claude.yaml + - docker_sandbox_create_codex.yaml + - docker_sandbox_create_gemini.yaml + - docker_sandbox_create_kiro.yaml +options: + - option: load-local-template + value_type: bool + default_value: "false" + description: | + Load a locally built template image into the sandbox (useful for testing local changes) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: name + value_type: string + description: | + Name for the sandbox (default: -, letters, numbers, hyphens, and underscores) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: quiet + shorthand: q + value_type: bool + default_value: "false" + description: Suppress verbose output + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: template + shorthand: t + value_type: string + description: | + Container image to use for the sandbox (default: agent-specific image) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_create_cagent.yaml b/data/sandbox-cli/docker_sandbox_create_cagent.yaml new file mode 100644 index 000000000000..6b9035b0fe05 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create_cagent.yaml @@ -0,0 +1,40 @@ +command: docker sandbox create cagent +short: Create a sandbox for cagent +long: |- + Create a sandbox with access to a host workspace for cagent. + + The workspace path is required and will be exposed inside the sandbox at the same path as on the host. + + Use 'docker sandbox run SANDBOX' to start cagent after creation. +usage: docker sandbox create cagent WORKSPACE +pname: docker sandbox create +plink: docker_sandbox_create.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_create_claude.yaml b/data/sandbox-cli/docker_sandbox_create_claude.yaml new file mode 100644 index 000000000000..e1ecab4613b8 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create_claude.yaml @@ -0,0 +1,51 @@ +command: docker sandbox create claude +short: Create a sandbox for claude +long: |- + Create a sandbox with access to a host workspace for claude. + + The workspace path is required and will be exposed inside the sandbox at the same path as on the host. + + Use 'docker sandbox run SANDBOX' to start claude after creation. +usage: docker sandbox create claude WORKSPACE +pname: docker sandbox create +plink: docker_sandbox_create.yaml +options: + - option: patch-settings + value_type: bool + default_value: "false" + description: Intercept claude settings API call and patch payload + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_create_codex.yaml b/data/sandbox-cli/docker_sandbox_create_codex.yaml new file mode 100644 index 000000000000..b5ed8c460efe --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create_codex.yaml @@ -0,0 +1,40 @@ +command: docker sandbox create codex +short: Create a sandbox for codex +long: |- + Create a sandbox with access to a host workspace for codex. + + The workspace path is required and will be exposed inside the sandbox at the same path as on the host. + + Use 'docker sandbox run SANDBOX' to start codex after creation. +usage: docker sandbox create codex WORKSPACE +pname: docker sandbox create +plink: docker_sandbox_create.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_create_gemini.yaml b/data/sandbox-cli/docker_sandbox_create_gemini.yaml new file mode 100644 index 000000000000..6b7a0ec11916 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create_gemini.yaml @@ -0,0 +1,40 @@ +command: docker sandbox create gemini +short: Create a sandbox for gemini +long: |- + Create a sandbox with access to a host workspace for gemini. + + The workspace path is required and will be exposed inside the sandbox at the same path as on the host. + + Use 'docker sandbox run SANDBOX' to start gemini after creation. +usage: docker sandbox create gemini WORKSPACE +pname: docker sandbox create +plink: docker_sandbox_create.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_create_kiro.yaml b/data/sandbox-cli/docker_sandbox_create_kiro.yaml new file mode 100644 index 000000000000..0f3fbd29f440 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_create_kiro.yaml @@ -0,0 +1,40 @@ +command: docker sandbox create kiro +short: Create a sandbox for kiro +long: |- + Create a sandbox with access to a host workspace for kiro. + + The workspace path is required and will be exposed inside the sandbox at the same path as on the host. + + Use 'docker sandbox run SANDBOX' to start kiro after creation. +usage: docker sandbox create kiro WORKSPACE +pname: docker sandbox create +plink: docker_sandbox_create.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_exec.yaml b/data/sandbox-cli/docker_sandbox_exec.yaml new file mode 100644 index 000000000000..096918d4eb1e --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_exec.yaml @@ -0,0 +1,132 @@ +command: docker sandbox exec +short: Execute a command inside a sandbox +long: |- + Execute a command in a sandbox that was previously created with 'docker sandbox create'. + + The command and any additional arguments are executed inside the sandbox container. +usage: docker sandbox exec [OPTIONS] SANDBOX COMMAND [ARG...] +pname: docker sandbox +plink: docker_sandbox.yaml +options: + - option: detach + shorthand: d + value_type: bool + default_value: "false" + description: 'Detached mode: run command in the background' + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: detach-keys + value_type: string + description: Override the key sequence for detaching a container + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: env + shorthand: e + value_type: stringArray + default_value: '[]' + description: Set environment variables + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: env-file + value_type: stringArray + default_value: '[]' + description: Read in a file of environment variables + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: interactive + shorthand: i + value_type: bool + default_value: "false" + description: Keep STDIN open even if not attached + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: privileged + value_type: bool + default_value: "false" + description: Give extended privileges to the command + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: tty + shorthand: t + value_type: bool + default_value: "false" + description: Allocate a pseudo-TTY + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: user + shorthand: u + value_type: string + description: 'Username or UID (format: [:])' + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: workdir + shorthand: w + value_type: string + description: Working directory inside the container + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_ls.yaml b/data/sandbox-cli/docker_sandbox_ls.yaml index 60b1c1734016..e633f9ac24d3 100644 --- a/data/sandbox-cli/docker_sandbox_ls.yaml +++ b/data/sandbox-cli/docker_sandbox_ls.yaml @@ -1,14 +1,21 @@ command: docker sandbox ls aliases: docker sandbox ls, docker sandbox list -short: List sandboxes -long: |- - List all sandboxes. - - This command lists all sandboxes using the Docker API. -usage: docker sandbox ls +short: List VMs +long: List all VMs managed by sandboxd with their sandboxes +usage: docker sandbox ls [OPTIONS] pname: docker sandbox plink: docker_sandbox.yaml options: + - option: json + value_type: bool + default_value: "false" + description: Output in JSON format + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false - option: no-trunc value_type: bool default_value: "false" @@ -24,7 +31,7 @@ options: shorthand: q value_type: bool default_value: "false" - description: Only display sandbox IDs + description: Only display VM names details_url: '#quiet' deprecated: false hidden: false @@ -44,28 +51,38 @@ inherited_options: experimentalcli: false kubernetes: false swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false examples: |- - ### List all sandboxes + ### List all VMs ```console $ docker sandbox ls - SANDBOX ID NAME WORKSPACE CREATED - abc123def my-project /home/user/my-project 2 hours ago - def456ghi ml-work /home/user/ml-projects 1 day ago + VM ID NAME STATUS WORKSPACE SOCKET PATH SANDBOXES AGENTS + abc123def claude-vm running /home/user/my-project /Users/.../docker-1764682554072.sock 2 claude + def456ghi gemini-vm stopped /home/user/ml-projects ``` - ### Show only sandbox IDs (--quiet) {#quiet} + ### Show only VM names (--quiet) {#quiet} ```text --quiet ``` - Output only sandbox IDs: + Output only VM names: ```console $ docker sandbox ls --quiet - abc123def - def456ghi + claude-vm + gemini-vm ``` ### Don't truncate output (--no-trunc) {#no-trunc} @@ -74,16 +91,49 @@ examples: |- --no-trunc ``` - By default, long sandbox IDs and workspace paths are truncated for readability. Use `--no-trunc` to display the full values: + By default, long VM IDs, workspace paths, and socket paths are truncated for readability. Use `--no-trunc` to display the full values: ```console $ docker sandbox ls - SANDBOX ID TEMPLATE NAME WORKSPACE STATUS CREATED - abc123def456 ubuntu my-project /home/user/.../my-project running 2 hours ago + VM ID NAME STATUS WORKSPACE SOCKET PATH SANDBOXES AGENTS + abc123def claude-vm running /home/user/.../my-project ...sandboxes/vm/claude-vm/docker.sock 2 claude $ docker sandbox ls --no-trunc - SANDBOX ID TEMPLATE NAME WORKSPACE STATUS CREATED - abc123def456ghi789jkl ubuntu my-project /home/user/very/long/path/to/my-project running 2 hours ago + VM ID NAME STATUS WORKSPACE SOCKET PATH SANDBOXES AGENTS + abc123def456ghi789jkl claude-vm running /home/user/very/long/path/to/my-project /Users/user/.docker/sandboxes/vm/claude-vm/docker-1764682554072.sock 2 claude + ``` + + ### JSON output (--json) + + ```text + --json + ``` + + Output detailed VM information in JSON format: + + ```console + $ docker sandbox ls --json + { + "vms": [ + { + "name": "claude-vm", + "agent": "claude", + "status": "running", + "socket_path": "/Users/user/.docker/sandboxes/vm/claude-vm/docker-1234567890.sock", + "sandbox_count": 2, + "workspaces": [ + "/home/user/my-project", + "/home/user/another-project" + ] + }, + { + "name": "gemini-vm", + "agent": "gemini", + "status": "stopped", + "sandbox_count": 0 + } + ] + } ``` deprecated: false hidden: false diff --git a/data/sandbox-cli/docker_sandbox_network.yaml b/data/sandbox-cli/docker_sandbox_network.yaml new file mode 100644 index 000000000000..9d40fd65c9f8 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_network.yaml @@ -0,0 +1,41 @@ +command: docker sandbox network +short: Manage sandbox networking +long: Manage sandbox networking +usage: docker sandbox network +pname: docker sandbox +plink: docker_sandbox.yaml +cname: + - docker sandbox network log + - docker sandbox network proxy +clink: + - docker_sandbox_network_log.yaml + - docker_sandbox_network_proxy.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_network_log.yaml b/data/sandbox-cli/docker_sandbox_network_log.yaml new file mode 100644 index 000000000000..36ad716f4714 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_network_log.yaml @@ -0,0 +1,67 @@ +command: docker sandbox network log +short: Show network logs +long: Show network logs +usage: docker sandbox network log +pname: docker sandbox network +plink: docker_sandbox_network.yaml +options: + - option: json + value_type: bool + default_value: "false" + description: Output in JSON format + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: limit + value_type: int + default_value: "0" + description: Maximum number of log entries to show + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: quiet + shorthand: q + value_type: bool + default_value: "false" + description: Only display log entries + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_network_proxy.yaml b/data/sandbox-cli/docker_sandbox_network_proxy.yaml new file mode 100644 index 000000000000..2e068aa8aa7d --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_network_proxy.yaml @@ -0,0 +1,102 @@ +command: docker sandbox network proxy +short: Manage proxy configuration for a sandbox +long: Manage proxy configuration for a sandbox +usage: docker sandbox network proxy [OPTIONS] +pname: docker sandbox network +plink: docker_sandbox_network.yaml +options: + - option: allow-cidr + value_type: string + description: | + Remove an IP range in CIDR notation from the block or bypass lists (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: allow-host + value_type: string + description: Permit access to a domain or IP (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: block-cidr + value_type: string + description: | + Block access to an IP range in CIDR notation (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: block-host + value_type: string + description: Block access to a domain or IP (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: bypass-cidr + value_type: string + description: | + Bypass proxy for an IP range in CIDR notation (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: bypass-host + value_type: string + description: Bypass proxy for a domain or IP (can be specified multiple times) + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: policy + value_type: allow|deny + description: Set the default policy + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_reset.yaml b/data/sandbox-cli/docker_sandbox_reset.yaml new file mode 100644 index 000000000000..41f438c6e94a --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_reset.yaml @@ -0,0 +1,61 @@ +command: docker sandbox reset +short: Reset all VM sandboxes and clean up state +long: |- + Reset all VM sandboxes and permanently delete all VM data. + + This command will: + - Stop all running VMs gracefully (30s timeout) + - Delete all VM state directories in ~/.docker/sandboxes/vm/ + - Clear all internal registries + + The daemon will continue running with fresh state after reset. + + ⚠️ WARNING: This is a destructive operation that cannot be undone! + All running agents will be forcefully terminated and their work will be lost. + + By default, you will be prompted to confirm (y/N). + Use --force to skip the confirmation prompt. +usage: docker sandbox reset [OPTIONS] +pname: docker sandbox +plink: docker_sandbox.yaml +options: + - option: force + shorthand: f + value_type: bool + default_value: "false" + description: Skip confirmation prompt + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_rm.yaml b/data/sandbox-cli/docker_sandbox_rm.yaml index 5a7a40882373..a26ba4c51f42 100644 --- a/data/sandbox-cli/docker_sandbox_rm.yaml +++ b/data/sandbox-cli/docker_sandbox_rm.yaml @@ -1,10 +1,13 @@ command: docker sandbox rm +aliases: docker sandbox rm, docker sandbox remove short: Remove one or more sandboxes long: |- - Remove one or more sandboxes by their IDs or names. + Remove one or more sandboxes and all their associated resources. - This command removes the specified sandboxes. Each sandbox is identified by its unique ID or name. -usage: docker sandbox rm [OPTIONS] SANDBOX [SANDBOX...] + This command will: + - Check if the sandbox exists + - Remove the sandbox and clean up its associated resources +usage: docker sandbox rm SANDBOX [SANDBOX...] pname: docker sandbox plink: docker_sandbox.yaml inherited_options: @@ -19,6 +22,16 @@ inherited_options: experimentalcli: false kubernetes: false swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false examples: |- ### Remove a sandbox diff --git a/data/sandbox-cli/docker_sandbox_run.yaml b/data/sandbox-cli/docker_sandbox_run.yaml index 58f67cac7d85..3e7eaefdbe4b 100644 --- a/data/sandbox-cli/docker_sandbox_run.yaml +++ b/data/sandbox-cli/docker_sandbox_run.yaml @@ -1,55 +1,38 @@ command: docker sandbox run -short: Run an AI agent inside a sandbox +short: Run an agent in a sandbox long: |- - Run an AI agent inside a sandbox with access to a host workspace. + Run an agent in a sandbox. Create the sandbox if it does not exist. - The agent argument must be one of: claude, gemini. - Agent-specific options can be passed after the agent name. - If no workspace is specified via the "--workspace" option, the current working directory is used. - The workspace is exposed inside the sandbox at the same path as on the host. -usage: docker sandbox run [options] [agent-options] + Pass agent arguments after the "--" separator. + + Examples: + # Create and run a sandbox with claude in current directory + docker sandbox run claude . + + # Run an existing sandbox + docker sandbox run existing-sandbox + + # Run a sandbox with agent arguments + docker sandbox run claude . -- -p "What version are you running?" +usage: docker sandbox run SANDBOX [-- AGENT_ARGS...] | AGENT WORKSPACE [-- AGENT_ARGS...] pname: docker sandbox plink: docker_sandbox.yaml options: - - option: credentials - value_type: string - default_value: sandbox - description: Credentials source (host, sandbox, or none) - details_url: '#credentials' - deprecated: false - hidden: false - experimental: false - experimentalcli: false - kubernetes: false - swarm: false - option: detached shorthand: d value_type: bool default_value: "false" - description: Create sandbox without running agent interactively - deprecated: false - hidden: false - experimental: false - experimentalcli: false - kubernetes: false - swarm: false - - option: env - shorthand: e - value_type: stringSlice - default_value: '[]' - description: 'Set environment variables (format: KEY=VALUE)' - details_url: '#env' + description: Return sandbox ID without running agent (hidden, for testing) deprecated: false - hidden: false + hidden: true experimental: false experimentalcli: false kubernetes: false swarm: false - - option: mount-docker-socket + - option: load-local-template value_type: bool default_value: "false" - description: Mount the host's Docker socket into the sandbox - details_url: '#mount-docker-socket' + description: Load a locally built template image into the sandbox deprecated: false hidden: false experimental: false @@ -58,7 +41,7 @@ options: swarm: false - option: name value_type: string - description: Name for the sandbox + description: 'Name for the sandbox (default: -)' details_url: '#name' deprecated: false hidden: false @@ -66,17 +49,6 @@ options: experimentalcli: false kubernetes: false swarm: false - - option: quiet - shorthand: q - value_type: bool - default_value: "false" - description: Suppress verbose output - deprecated: false - hidden: false - experimental: false - experimentalcli: false - kubernetes: false - swarm: false - option: template shorthand: t value_type: string @@ -89,31 +61,6 @@ options: experimentalcli: false kubernetes: false swarm: false - - option: volume - shorthand: v - value_type: stringSlice - default_value: '[]' - description: | - Bind mount a volume or host file or directory into the sandbox (format: hostpath:sandboxpath[:readonly|:ro]) - details_url: '#volume' - deprecated: false - hidden: false - experimental: false - experimentalcli: false - kubernetes: false - swarm: false - - option: workspace - shorthand: w - value_type: string - default_value: . - description: Workspace path - details_url: '#workspace' - deprecated: false - hidden: false - experimental: false - experimentalcli: false - kubernetes: false - swarm: false inherited_options: - option: debug shorthand: D @@ -126,6 +73,16 @@ inherited_options: experimentalcli: false kubernetes: false swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false examples: |- ### Run Claude in the current directory @@ -197,22 +154,6 @@ examples: |- Use `:ro` or `:readonly` to make mounts read-only. - ### Configure credential access (--credentials) {#credentials} - - ```text - --credentials MODE - ``` - - Control how the agent accesses credentials. Valid modes are: - - - `sandbox` (default): Authenticate once and share credentials across sandboxes - - `host`: Share host credentials (~/.gitconfig, ~/.ssh, etc.) - - `none`: Handle authentication manually - - ```console - $ docker sandbox run --credentials host claude - ``` - ### Use a custom base image (-t, --template) {#template} ```text diff --git a/data/sandbox-cli/docker_sandbox_stop.yaml b/data/sandbox-cli/docker_sandbox_stop.yaml new file mode 100644 index 000000000000..97551892c3a2 --- /dev/null +++ b/data/sandbox-cli/docker_sandbox_stop.yaml @@ -0,0 +1,36 @@ +command: docker sandbox stop +short: Stop one or more sandboxes without removing them +long: | + Stop one or more sandboxes without removing them. The sandboxes can be restarted later. +usage: docker sandbox stop SANDBOX [SANDBOX...] +pname: docker sandbox +plink: docker_sandbox.yaml +inherited_options: + - option: debug + shorthand: D + value_type: bool + default_value: "false" + description: Enable debug logging + deprecated: false + hidden: false + experimental: false + experimentalcli: false + kubernetes: false + swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false +deprecated: false +hidden: false +experimental: false +experimentalcli: false +kubernetes: false +swarm: false + diff --git a/data/sandbox-cli/docker_sandbox_version.yaml b/data/sandbox-cli/docker_sandbox_version.yaml index 286d5860a60b..bd5a940139cc 100644 --- a/data/sandbox-cli/docker_sandbox_version.yaml +++ b/data/sandbox-cli/docker_sandbox_version.yaml @@ -1,6 +1,6 @@ command: docker sandbox version -short: Show sandboxd version information -long: Show sandboxd version information +short: Show sandbox version information +long: Show sandbox version information usage: docker sandbox version pname: docker sandbox plink: docker_sandbox.yaml @@ -16,6 +16,16 @@ inherited_options: experimentalcli: false kubernetes: false swarm: false + - option: socket + value_type: string + description: | + Connect to daemon at specific socket path (for development/debugging) + deprecated: false + hidden: true + experimental: false + experimentalcli: false + kubernetes: false + swarm: false deprecated: false hidden: false experimental: false From 2869118ccbb759096a53d6be0162c4f34475ec7e Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 13 Jan 2026 11:22:26 +0100 Subject: [PATCH 2/2] sandboxes: rewrite for microvm-based sandboxes Signed-off-by: David Karlsson <35727626+dvdksn@users.noreply.github.com> --- _vale/config/vocabularies/Docker/accept.txt | 2 + content/manuals/ai/sandboxes/_index.md | 98 +++-- .../manuals/ai/sandboxes/advanced-config.md | 305 ---------------- content/manuals/ai/sandboxes/agents.md | 66 ++++ content/manuals/ai/sandboxes/architecture.md | 207 +++++++++++ content/manuals/ai/sandboxes/claude-code.md | 140 +++----- content/manuals/ai/sandboxes/get-started.md | 113 ++++-- content/manuals/ai/sandboxes/migration.md | 189 ++++++++++ .../manuals/ai/sandboxes/network-policies.md | 340 ++++++++++++++++++ content/manuals/ai/sandboxes/templates.md | 161 +++++++++ .../manuals/ai/sandboxes/troubleshooting.md | 16 +- content/manuals/ai/sandboxes/workflows.md | 157 ++++++++ data/summary.yaml | 2 +- 13 files changed, 1311 insertions(+), 485 deletions(-) delete mode 100644 content/manuals/ai/sandboxes/advanced-config.md create mode 100644 content/manuals/ai/sandboxes/agents.md create mode 100644 content/manuals/ai/sandboxes/architecture.md create mode 100644 content/manuals/ai/sandboxes/migration.md create mode 100644 content/manuals/ai/sandboxes/network-policies.md create mode 100644 content/manuals/ai/sandboxes/templates.md create mode 100644 content/manuals/ai/sandboxes/workflows.md diff --git a/_vale/config/vocabularies/Docker/accept.txt b/_vale/config/vocabularies/Docker/accept.txt index 88eedf3531e4..f74583b1d1db 100644 --- a/_vale/config/vocabularies/Docker/accept.txt +++ b/_vale/config/vocabularies/Docker/accept.txt @@ -1,6 +1,7 @@ (?i)[A-Z]{2,}'?s jq ripgrep +exfiltration sandboxing Adreno Aleksandrov @@ -242,6 +243,7 @@ Zsh [Cc]ompose [Cc]onfigs [dD]eduplicate +[Dd]enylist [Dd]ev [Dd]iscoverability [Dd]istroless diff --git a/content/manuals/ai/sandboxes/_index.md b/content/manuals/ai/sandboxes/_index.md index 4958b3de2c7c..0e737fc3b530 100644 --- a/content/manuals/ai/sandboxes/_index.md +++ b/content/manuals/ai/sandboxes/_index.md @@ -12,59 +12,83 @@ params: {{< summary-bar feature_name="Docker Sandboxes" >}} -Docker Sandboxes simplifies running AI agents securely on your local machine. -Designed for developers building with coding agents like Claude Code, Sandboxes -isolate your agents from your local machine while preserving a familiar -development experience. With Docker Sandboxes, agents can execute commands, -install packages, and modify files inside a containerized workspace that -mirrors your local directory. This gives you full agent autonomy without -compromising safety. +Docker Sandboxes lets you run AI coding agents in isolated environments on your +machine. If you're building with agents like Claude Code, Sandboxes provides a +secure way to give agents autonomy without compromising your system. -## How it works +## Why use Docker Sandboxes + +AI agents need to execute commands, install packages, and test code. Running +them directly on your host machine means they have full access to your files, +processes, and network. Docker Sandboxes isolates agents in microVMs, each with +its own Docker daemon. Agents can spin up test containers and modify their +environment without affecting your host. + +You get: + +- Agent autonomy without host system risk +- Private Docker daemon for running test containers +- File sharing between host and sandbox +- Network access control + +For a comparison between Docker Sandboxes and other approaches to isolating +coding agents, see [Comparison to alternatives](./architecture.md#comparison-to-alternatives). -When you run `docker sandbox run `: +## How to use sandboxes -1. Docker creates a container from a template image and mounts your current - working directory into the container at the same path. +To create and run a sandbox: -2. Docker discovers your Git `user.name` and `user.email` configuration and - injects it into the container so commits made by the agent are attributed - to you. +```console +$ docker sandbox run claude ~/my-project +``` -3. On first run, you're prompted to authenticate. Credentials are stored in a - Docker volume and reused for future sandboxed agents. +This command creates a sandbox for your workspace (`~/my-project`) and starts +the Claude Code agent inside it. The agent can now work with your code, install +tools, and run containers inside the isolated sandbox. -4. The agent starts inside the container with bypass permissions enabled. +## How it works + +Sandboxes run in lightweight microVMs with private Docker daemons. Each sandbox +is completely isolated - the agent runs inside the VM and can't access your +host Docker daemon, containers, or files outside the workspace. + +Your workspace directory syncs between host and sandbox at the same absolute +path, so file paths in error messages match between environments. -### Workspace mounting +Sandboxes don't appear in `docker ps` on your host because they're VMs, not +containers. Use `docker sandbox ls` to see them. -Your workspace directory is mounted into the container at the same absolute path -(on macOS and Linux). For example, `/Users/alice/projects/myapp` on your host -is also `/Users/alice/projects/myapp` in the container. This means: +For technical details on the architecture, isolation model, and networking, see +[Architecture](architecture.md). -- File paths in error messages match your host -- Scripts with hard-coded paths work as expected -- Changes to workspace files are immediately visible on both host and container +### Multiple sandboxes -### One sandbox per workspace +Create separate sandboxes for different projects: -Docker enforces one sandbox per workspace. When you run `docker sandbox run -` in the same directory, Docker reuses the existing container. This -means state (installed packages, temporary files) persists across agent sessions -in that workspace. +```console +$ docker sandbox run claude ~/project-a +$ docker sandbox run claude ~/project-b +``` -> [!NOTE] -> To change a sandbox's configuration (environment variables, mounted volumes, -> etc.), you need to remove and recreate it. See -> [Managing sandboxes](advanced-config.md#managing-sandboxes) for details. +Each sandbox is completely isolated from the others. Sandboxes persist until +you remove them, so installed packages and configuration stay available for +that workspace. -## Release status +## Supported agents -Docker Sandboxes is an experimental feature. Features and setup are subject to -change. +Docker Sandboxes works with multiple AI coding agents: -Report issues on the [Docker Desktop issue tracker](https://github.com/docker/desktop-feedback). +- **Claude Code** - Anthropic's coding agent +- **Codex** - OpenAI's Codex agent (partial support; in development) +- **Gemini** - Google's Gemini agent (partial support; in development) +- **cagent** - Docker's [cagent](/ai/cagent/) (partial support; in development) +- **Kiro** - by AWS (partial support; in development) ## Get started Head to the [Get started guide](get-started.md) to run your first sandboxed agent. + +## Troubleshooting + +See [Troubleshooting](./troubleshooting) for common configuration errors, or +report issues on the [Docker Desktop issue tracker](https://github.com/docker/desktop-feedback). diff --git a/content/manuals/ai/sandboxes/advanced-config.md b/content/manuals/ai/sandboxes/advanced-config.md deleted file mode 100644 index 2a733066afa9..000000000000 --- a/content/manuals/ai/sandboxes/advanced-config.md +++ /dev/null @@ -1,305 +0,0 @@ ---- -title: Advanced configurations -linkTitle: Advanced -description: Docker access, volume mounting, environment variables, custom templates, and sandbox management. -weight: 40 ---- - -{{< summary-bar feature_name="Docker Sandboxes" >}} - -This guide covers advanced configurations for sandboxed agents running locally. - -## Managing sandboxes - -### Recreating sandboxes - -Since Docker enforces one sandbox per workspace, the same sandbox is reused -each time you run `docker sandbox run ` in a given directory. To create -a fresh sandbox, you need to remove the existing one first: - -```console -$ docker sandbox ls # Find the sandbox ID -$ docker sandbox rm -$ docker sandbox run # Creates a new sandbox -``` - -### When to recreate sandboxes - -Sandboxes remember their initial configuration and don't pick up changes from subsequent `docker sandbox run` commands. You must recreate the sandbox to modify: - -- Environment variables (the `-e` flag) -- Volume mounts (the `-v` flag) -- Docker socket access (the `--mount-docker-socket` flag) -- Credentials mode (the `--credentials` flag) - -### Listing and inspecting sandboxes - -View all your sandboxes: - -```console -$ docker sandbox ls -``` - -Get detailed information about a specific sandbox: - -```console -$ docker sandbox inspect -``` - -This shows the sandbox's configuration, including environment variables, volumes, and creation time. - -### Removing sandboxes - -Remove a specific sandbox: - -```console -$ docker sandbox rm -``` - -Remove all sandboxes at once: - -```console -$ docker sandbox rm $(docker sandbox ls -q) -``` - -This is useful for cleanup when you're done with a project or want to start fresh. - -## Giving agents access to Docker - -Mount the Docker socket to give agents access to Docker commands inside the -container. The agent can build images, run containers, and work with Docker -Compose setups. - -> [!CAUTION] -> Mounting the Docker socket grants the agent full access to your Docker daemon, -> which has root-level privileges on your system. The agent can start or stop -> any container, access volumes, and potentially escape the sandbox. Only use -> this option when you fully trust the code the agent is working with. - -### Enable Docker socket access - -Use the `--mount-docker-socket` flag: - -```console -$ docker sandbox run --mount-docker-socket claude -``` - -This mounts your host's Docker socket (`/var/run/docker.sock`) into the -container, giving the agent access to Docker commands. - -> [!IMPORTANT] -> The agent can see and interact with all containers on your host, not just -> those created within the sandbox. - -### Example: Testing a containerized application - -If your project has a Dockerfile, the agent can build and test it: - -```console -$ cd ~/my-docker-app -$ docker sandbox run --mount-docker-socket claude -``` - -Example conversation: - -```plaintext -You: "Build the Docker image and run the tests" - -Claude: *runs* - docker build -t myapp:test . - docker run myapp:test npm test -``` - -### What agents can do with Docker socket access - -With Docker access enabled, agents can: - -- Start multi-container applications with Docker Compose -- Build images for multiple architectures -- Manage existing containers on your host -- Validate Dockerfiles and test build processes - -## Environment variables - -Pass environment variables to configure the sandbox environment with the `-e` -flag: - -```console -$ docker sandbox run \ - -e NODE_ENV=development \ - -e DATABASE_URL=postgresql://localhost/myapp_dev \ - -e DEBUG=true \ - claude -``` - -These variables are available to all processes in the container, including the -agent and any commands it runs. Use multiple `-e` flags for multiple variables. - -### Example: Development environment setup - -Set up a complete development environment: - -```console -$ docker sandbox run \ - -e NODE_ENV=development \ - -e DATABASE_URL=postgresql://localhost/myapp_dev \ - -e REDIS_URL=redis://localhost:6379 \ - -e LOG_LEVEL=debug \ - claude -``` - -Example conversation: - -```plaintext -You: "Run the database migrations and start the development server" - -Claude: *uses DATABASE_URL and other environment variables* - npm run migrate - npm run dev -``` - -### Common use cases - -API keys for testing: - -```console -$ docker sandbox run \ - -e STRIPE_TEST_KEY=sk_test_xxx \ - -e SENDGRID_API_KEY=SG.xxx \ - claude -``` - -> [!CAUTION] -> Only use test/development API keys in sandboxes, never production keys. - -Loading from .env files: - -Sandboxes don't automatically load `.env` files from your workspace, but you can ask Claude to use them: - -```plaintext -You: "Load environment variables from .env.development and start the server" -``` - -Claude can use `dotenv` tools or source the file directly. - -## Volume mounting - -Mount additional directories or files to share data beyond your main workspace. -Use the `-v` flag with the syntax `host-path:container-path`: - -```console -$ docker sandbox run -v ~/datasets:/data claude -``` - -This makes `~/datasets` available at `/data` inside the container. The agent -can read and write files in this location. - -Read-only mounts: - -Add `:ro` to prevent modifications: - -```console -$ docker sandbox run -v ~/configs/app.yml:/config/app.yml:ro claude -``` - -Multiple mounts: - -Use multiple `-v` flags to mount several locations: - -```console -$ docker sandbox run \ - -v ~/datasets:/data:ro \ - -v ~/models:/models \ - -v ~/.cache/pip:/root/.cache/pip \ - claude -``` - -### Example: Machine learning workflow - -Set up an ML environment with shared datasets, model storage, and persistent -caches: - -```console -$ docker sandbox run \ - -v ~/datasets:/data:ro \ - -v ~/models:/models \ - -v ~/.cache/pip:/root/.cache/pip \ - claude -``` - -This provides read-only access to datasets (preventing accidental modifications), -read-write access to save trained models, and a persistent pip cache for faster -package installs across sessions. - -Example conversation: - -```plaintext -You: "Train a model on the MNIST dataset and save it to /models" - -Claude: *runs* - python train.py --data /data/mnist --output /models/mnist_model.h5 -``` - -### Common use cases - -Shared configuration files: - -```console -$ docker sandbox run -v ~/.aws:/root/.aws:ro claude -``` - -Build caches: - -```console -$ docker sandbox run \ - -v ~/.cache/go-build:/root/.cache/go-build \ - -v ~/go/pkg/mod:/go/pkg/mod \ - claude -``` - -Custom tools: - -```console -$ docker sandbox run -v ~/bin:/shared-bin:ro claude -``` - -## Custom templates - -Create custom sandbox templates to reuse configured environments. Instead of -installing tools every time you start an agent, build a Docker image with -everything pre-installed: - -```dockerfile -# syntax=docker/dockerfile:1 -FROM docker/sandbox-templates:claude-code -RUN <}} + +Docker Sandboxes supports multiple AI coding agents. All agents run isolated +inside microVMs with private Docker daemons. + +## Supported agents + +| Agent | Command | Status | Notes | +| ----------- | -------- | ------------ | -------------------------- | +| Claude Code | `claude` | Experimental | Most tested implementation | +| Codex | `codex` | Experimental | In development | +| Gemini | `gemini` | Experimental | In development | +| cagent | `cagent` | Experimental | In development | +| Kiro | `kiro` | Experimental | In development | + +## Experimental status + +All agents are experimental features. This means: + +- Breaking changes may occur between Docker Desktop versions +- Features may be incomplete or change significantly +- Stability and performance are not production-ready +- Limited support and documentation + +Use sandboxes for development and testing, not production workloads. + +## Using different agents + +The agent type is specified when creating a sandbox: + +```console +$ docker sandbox create claude ~/my-project +$ docker sandbox create codex ~/my-project +$ docker sandbox create gemini ~/my-project +$ docker sandbox create cagent ~/my-project +$ docker sandbox create kiro ~/my-project +``` + +Each agent runs in its own isolated sandbox. The agent type is bound to the +sandbox when created and cannot be changed later. + +## Agent-specific configuration + +Different agents may require different authentication methods or configuration. +See the agent-specific documentation: + +- [Claude Code configuration](claude-code.md) + +## Requirements + +- Docker Desktop 4.58 or later +- Platform support: + - macOS with virtualization.framework +- API keys or credentials for your chosen agent + +## Next steps + +- [Claude Code configuration](claude-code.md) +- [Custom templates](templates.md) +- [Using sandboxes effectively](workflows.md) diff --git a/content/manuals/ai/sandboxes/architecture.md b/content/manuals/ai/sandboxes/architecture.md new file mode 100644 index 000000000000..86ab04cda8a5 --- /dev/null +++ b/content/manuals/ai/sandboxes/architecture.md @@ -0,0 +1,207 @@ +--- +title: Architecture +description: Technical architecture of Docker Sandboxes including microVM isolation, private Docker daemon, and workspace syncing. +weight: 60 +--- + +{{< summary-bar feature_name="Docker Sandboxes" >}} + +This page explains how Docker Sandboxes works and the design decisions behind +it. + +## Why microVMs? + +AI coding agents need to build images, run containers, and use Docker Compose. +Giving an agent access to your host Docker daemon means it can see your +containers, pull images, and run workloads directly on your system. That's too +much access for autonomous code execution. + +Running the agent in a container doesn't solve this. Containers share the host +kernel (or in the case of Docker Desktop, share the same virtual machine) and +can't safely isolate something that needs its own Docker daemon. +Docker-in-Docker approaches either compromise isolation (privileged mode with +host socket mounting) or create nested daemon complexity. + +MicroVMs provide the isolation boundary needed. Each sandbox gets its own VM +with a private Docker daemon. The agent can build images, start containers, and +run tests without any access to your host Docker environment. When you remove +the sandbox, everything inside - images, containers, packages - is gone. + +## Isolation model + +### Private Docker daemon per sandbox + +Each sandbox runs a complete Docker daemon inside its VM. This daemon is +isolated from your host and from other sandboxes. + +```plaintext +Host system (your Docker Desktop) + ├── Your containers and images + │ + ├── Sandbox VM 1 + │ ├── Docker daemon (isolated) + │ ├── Agent container + │ └── Other containers (created by agent) + │ + └── Sandbox VM 2 + ├── Docker daemon (isolated) + └── Agent container +``` + +When an agent runs `docker build` or `docker compose up`, those commands +execute inside the sandbox using the private daemon. The agent sees only +containers it creates. It cannot access your host containers, images, or +volumes. + +This architecture solves a fundamental constraint: autonomous agents need full +Docker capabilities but cannot safely share your Docker daemon. + +### Hypervisor-level isolation + +Sandboxes use your system's native virtualization: + +- macOS: virtualization.framework + +This provides hypervisor-level isolation between the sandbox and your host. +Unlike containers (which share the host kernel), VMs have separate kernels and +cannot access host resources outside their defined boundaries. + +### What this means for security + +The VM boundary provides: + +- Process isolation - Agent processes run in a separate kernel +- Filesystem isolation - Only your workspace is accessible +- Network isolation - Sandboxes cannot reach each other +- Docker isolation - No access to host daemon, containers, or images + +Network filtering adds an additional control layer for HTTP/HTTPS traffic. See +[Network policies](network-policies.md) for details on that mechanism. + +## Workspace syncing + +### Bidirectional file sync + +Your workspace syncs to the sandbox at the same absolute path: + +- Host: `/Users/alice/projects/myapp` +- Sandbox: `/Users/alice/projects/myapp` + +Changes sync both ways. Edit a file on your host, and the agent sees it. The +agent modifies a file, and you see the change on your host. + +This is file synchronization, not volume mounting. Files are copied between +host and VM. This approach works across different filesystems and maintains +consistent paths regardless of platform differences. + +### Path preservation + +Preserving absolute paths means: + +- File paths in error messages match between host and sandbox +- Hard-coded paths in configuration files work correctly +- Build outputs reference paths you can find on your host + +The agent sees the same directory structure you see, reducing confusion when +debugging issues or reviewing changes. + +## Storage and persistence + +### What persists + +When you create a sandbox, these persist until you remove it: + +- Docker images and containers - Built or pulled by the agent +- Installed packages - System packages added with apt, yum, etc. +- Agent state - Credentials, configuration, history +- Workspace changes - Files created or modified sync back to host + +### What's ephemeral + +Sandboxes are lightweight but not stateless. They persist between runs but are +isolated from each other. Each sandbox maintains its own: + +- Docker daemon state +- Image cache +- Package installations + +When you remove a sandbox with `docker sandbox rm`, the entire VM and its +contents are deleted. Images built inside the sandbox, packages installed, and +any state not synced to your workspace are gone. + +### Disk usage + +Each sandbox consumes disk space for: + +- VM disk image (grows as you build images and install packages) +- Docker images pulled or built inside the sandbox +- Container layers and volumes + +Multiple sandboxes do not share images or layers. Each has its own isolated +Docker daemon and storage. + +## Networking + +### Internet access + +Sandboxes have outbound internet access through your host's network connection. +Agents can install packages, pull images, and access APIs. + +An HTTP/HTTPS filtering proxy runs on your host and is available at +`host.docker.internal:3128`. Agents automatically use this proxy for outbound +web requests. You can configure network policies to control which destinations +are allowed. See [Network policies](network-policies.md). + +### Sandbox isolation + +Sandboxes cannot communicate with each other. Each VM has its own private +network namespace. An agent in one sandbox cannot reach services or containers +in another sandbox. + +Sandboxes also cannot access your host's `localhost` services. The VM boundary +prevents direct access to services running on your host machine. + +## Lifecycle + +### Creating and running + +`docker sandbox run` initializes a VM with a workspace for a specified agent, +and starts the agent inside an existing sandbox. You can stop and restart the +agent without recreating the VM, preserving installed packages and Docker +images. + +`docker sandbox create` initializes the VM with a workspace but doesn't start +the agent automatically. This separates environment setup from agent execution. + +### State management + +Sandboxes persist until explicitly removed. Stopping an agent doesn't delete +the VM. This means: + +- Installed packages remain available +- Built images stay cached +- Environment setup persists between runs + +Use `docker sandbox rm` to delete a sandbox and reclaim disk space. + +## Comparison to alternatives + +Understanding when to use sandboxes versus other approaches: + +| Approach | Isolation | Agent Docker access | Host impact | Use case | +| --------------------------- | ----------------- | ------------------------ | ----------------------------------- | --------------------------------------------- | +| Sandboxes (microVMs) | Hypervisor-level | Private daemon | None - fully isolated | Autonomous agents building/running containers | +| Container with socket mount | Kernel namespaces | Host daemon (shared) | Agent sees all host containers | Trusted tools that need Docker CLI | +| Docker-in-Docker | Nested containers | Private daemon (complex) | Moderate - privileged mode required | CI/CD environments | +| Host execution | None | Host daemon | Full - direct system access | Manual development by trusted humans | + +Sandboxes trade higher resource overhead (VM + daemon) for complete isolation. +Use containers when you need lightweight packaging without Docker access. Use +sandboxes when you need to give something autonomous full Docker capabilities +without trusting it with your host environment. + +## Next steps + +- [Network policies](network-policies.md) +- [Custom templates](templates.md) +- [Using sandboxes effectively](workflows.md) diff --git a/content/manuals/ai/sandboxes/claude-code.md b/content/manuals/ai/sandboxes/claude-code.md index 22a28e9771f6..75034304bc3c 100644 --- a/content/manuals/ai/sandboxes/claude-code.md +++ b/content/manuals/ai/sandboxes/claude-code.md @@ -11,39 +11,10 @@ running Claude Code in a sandboxed environment. ## Quick start -The simplest way to start Claude in a sandbox: +To create a sandbox and run Claude Code for a project directory: ```console -$ docker sandbox run claude -``` - -This starts a sandboxed Claude Code agent with the current working directory as -its workspace. - -Or specify a different workspace: - -```console -$ docker sandbox run -w ~/my-project claude -``` - -## Passing CLI options to Claude - -Claude Code supports various command-line options that you can pass through -`docker sandbox run`. Any arguments after the agent name (`claude`) are passed -directly to Claude Code inside the sandbox. - -### Continue previous conversation - -Resume your most recent conversation: - -```console -$ docker sandbox run claude -c -``` - -Or use the long form: - -```console -$ docker sandbox run claude --continue +$ docker sandbox run claude ~/my-project ``` ### Pass a prompt directly @@ -51,103 +22,94 @@ $ docker sandbox run claude --continue Start Claude with a specific prompt: ```console -$ docker sandbox run claude "Add error handling to the login function" +$ docker sandbox run -- "Add error handling to the login function" ``` -This starts Claude and immediately processes the prompt. - -### Combine options - -You can combine sandbox options with Claude options: +Or: ```console -$ docker sandbox run -e DEBUG=1 claude -c +$ docker sandbox run -- "$(cat prompt.txt)" ``` -This creates a sandbox with `DEBUG` set to `1`, enabling debug output for -troubleshooting, and continues the previous conversation. - -### Available Claude options - -All Claude Code CLI options work through `docker sandbox run`: - -- `-c, --continue` - Continue the most recent conversation -- `-p, --prompt` - Read prompt from stdin (useful for piping) -- `--dangerously-skip-permissions` - Skip permission prompts (enabled by default in sandboxes) -- And more - see the [Claude Code documentation](https://docs.claude.com/en/docs/claude-code) for a complete list +This starts Claude and immediately processes the prompt. ## Authentication -Claude sandboxes support the following credential management strategies. +Claude Code needs an Anthropic API key to work. The recommended approach is to +set the `ANTHROPIC_API_KEY` environment variable in your shell configuration +file. -### Strategy 1: `sandbox` (Default) +Docker Sandboxes run through a daemon process that doesn't inherit environment +variables from your current shell session. To make your API key available to +sandboxes, you need to set it globally in your shell configuration file. -```console -$ docker sandbox run claude +Add the API key to your shell configuration file: + +```plaintext {title="~/.bashrc or ~/.zshrc"} +export ANTHROPIC_API_KEY=sk-ant-api03-xxxxx ``` -On first run, Claude prompts you to enter your Anthropic API key. The -credentials are stored in a persistent Docker volume named -`docker-claude-sandbox-data`. All future Claude sandboxes automatically use -these stored credentials, and they persist across sandbox restarts and deletion. +Then apply the changes: -Sandboxes mount this volume at `/mnt/claude-data` and create symbolic links in -the sandbox user's home directory. +1. Source your shell configuration: `source ~/.bashrc` (or `~/.zshrc`) +2. Restart Docker Desktop so the daemon picks up the new environment variable +3. Create and run your sandbox: -> [!NOTE] -> If your workspace contains a `.claude.json` file with a `primaryApiKey` -> field, you'll receive a warning about potential conflicts. You can choose to -> remove the `primaryApiKey` field from your `.claude.json` or proceed and -> ignore the warning. +```console +$ docker sandbox create claude ~/project +$ docker sandbox run +``` -### Strategy 2: `none` +The sandbox will detect the environment variable and use it automatically. -No automatic credential management. +### Interactive authentication -```console -$ docker sandbox run --credentials=none claude -``` +If no credentials are found, Claude Code prompts you to authenticate when it +starts. You'll need to authenticate for each workspace separately when using +this method. -Docker does not discover, inject, or store any credentials. You must -authenticate manually inside the container. Credentials are not shared with -other sandboxes but persist for the lifetime of the container. +To avoid repeated authentication, use the `ANTHROPIC_API_KEY` environment +variable method described above. ## Configuration Claude Code can be configured through CLI options. Any arguments you pass after -the agent name are passed directly to Claude Code inside the container. +the sandbox name and a `--` separator are passed directly to Claude Code. -Pass options after the agent name: +Pass options after the sandbox name: ```console -$ docker sandbox run claude [claude-options] +$ docker sandbox run -- [claude-options] ``` For example: ```console -$ docker sandbox run claude --continue +$ docker sandbox run -- --continue ``` See the [Claude Code CLI reference](https://docs.claude.com/en/docs/claude-code/cli-reference) -for a complete list of available options. +for available options. + +## Base image -## Advanced usage +The Claude Code sandbox template is a container image that runs inside the +sandbox VM. It includes: -For more advanced configurations including environment variables, volume mounts, -Docker socket access, and custom templates, see -[Advanced configurations](advanced-config.md). +- Ubuntu-based environment with Claude Code +- Development tools: Docker CLI, GitHub CLI, Node.js, Go, Python 3, Git, ripgrep, jq +- Non-root `agent` user with sudo access +- Private Docker daemon for running additional containers -## Base image +Claude launches with `--dangerously-skip-permissions` by default in sandboxes. -The `docker/sandbox-templates:claude-code` image includes Claude Code with -automatic credential management, plus development tools (Docker CLI, GitHub -CLI, Node.js, Go, Python 3, Git, ripgrep, jq). It runs as a non-root `agent` -user with `sudo` access and launches Claude with -`--dangerously-skip-permissions` by default. +You can build custom templates based on `docker/sandbox-templates:claude-code`. +See [Custom templates](templates.md) for details. -## Next Steps +## Next steps -- [Advanced configurations](advanced-config.md) +- [Using sandboxes effectively](workflows.md) +- [Custom templates](templates.md) +- [Network policies](network-policies.md) - [Troubleshooting](troubleshooting.md) - [CLI Reference](/reference/cli/docker/sandbox/) diff --git a/content/manuals/ai/sandboxes/get-started.md b/content/manuals/ai/sandboxes/get-started.md index 922818a94834..e947464c1880 100644 --- a/content/manuals/ai/sandboxes/get-started.md +++ b/content/manuals/ai/sandboxes/get-started.md @@ -7,57 +7,70 @@ weight: 20 {{< summary-bar feature_name="Docker Sandboxes" >}} -This guide will help you run Claude Code in a sandboxed environment for the first time. +This guide runs Claude Code in an isolated sandbox for the first time. + +> [!NOTE] +> Upgrading from an earlier version of Docker Desktop? See the +> [migration guide](migration.md) for information about the new microVM +> architecture. ## Prerequisites Before you begin, ensure you have: -- Docker Desktop 4.50 or later -- A Claude Code subscription +- Docker Desktop 4.58 or later +- macOS +- A Claude API key -## Run a sandboxed agent +## Run your first sandbox -Follow these steps to run Claude Code in a sandboxed environment: +Follow these steps to run Claude Code: -1. Navigate to Your Project +1. Set your Anthropic API key as an environment variable. - ```console - $ cd ~/my-project + Add the API key to your shell configuration file: + + ```plaintext {title="~/.bashrc or ~/.zshrc"} + export ANTHROPIC_API_KEY=sk-ant-api03-xxxxx ``` -2. Start Claude in a sandbox + Docker Sandboxes use a daemon process that runs independently of your + current shell session. This means setting the environment variable inline or + in your current session will not work. You must set it globally in your + shell configuration file to ensure the daemon can access it. + + Then apply the changes: + 1. Source your shell configuration. + 2. Restart Docker Desktop so the daemon picks up the new environment variable. + +2. Create and run a sandbox for Claude Code for your workspace: ```console - $ docker sandbox run claude + $ docker sandbox run claude ~/my-project ``` -3. Authenticate: on first run, Claude will prompt you to authenticate. - - Once you've authenticated, the credentials are stored in a persistent Docker - volume and reused for future sessions. + This creates a microVM sandbox. Docker assigns it a name automatically. -4. Claude Code launches inside the container. +3. Claude Code starts and you can begin working. The first run takes longer + while Docker initializes the microVM and pulls the template image. ## What just happened? -When you ran `docker sandbox run claude`: +When you ran `docker sandbox run`: -- Docker created a container from a template image -- Your current directory was mounted at the same path inside the container -- Your Git name and email were injected into the container -- Your API key was stored in a Docker volume (`docker-claude-sandbox-data`) -- Claude Code started with bypass permissions enabled +- Docker created a lightweight microVM with a private Docker daemon +- The sandbox was assigned a name based on the workspace path +- Your workspace synced into the VM +- Docker started the Claude Code agent as a container inside the sandbox VM -The container continues running in the background. Running `docker sandbox run -claude` again in the same directory reuses the existing container, allowing the -agent to maintain state (installed packages, temporary files) across sessions. +The sandbox persists until you remove it. Installed packages and configuration +remain available. Run `docker sandbox run ` again to reconnect. ## Basic commands -Here are a few essential commands to manage your sandboxes: +Here are essential commands to manage your sandboxes: -### List your sandboxes +### List sandboxes ```console $ docker sandbox ls @@ -65,30 +78,54 @@ $ docker sandbox ls Shows all your sandboxes with their IDs, names, status, and creation time. +> [!NOTE] +> Sandboxes don't appear in `docker ps` because they're microVMs, not +> containers. Use `docker sandbox ls` to see them. + +### Access a running sandbox + +```console +$ docker sandbox exec -it bash +``` + +Executes a command inside the container in the sandbox. Use `-it` to open an +interactive shell for debugging or installing additional tools. + ### Remove a sandbox ```console -$ docker sandbox rm +$ docker sandbox rm ``` -Deletes a sandbox when you're done with it. Get the sandbox ID from `docker sandbox ls`. +Deletes the sandbox VM and all installed packages inside it. You can remove +multiple sandboxes at once by specifying multiple names: + +```console +$ docker sandbox rm +``` +### Recreate a sandbox -### View sandbox details +To start fresh with a clean environment, remove and recreate the sandbox: ```console -$ docker sandbox inspect +$ docker sandbox rm +$ docker sandbox run claude ~/project ``` -Shows detailed information about a specific sandbox in JSON format. +Configuration like custom templates and workspace paths are set when you create +the sandbox. To change these settings, remove and recreate. -For a complete list of all commands and options, see the [CLI reference](/reference/cli/docker/sandbox/). +For a complete list of commands and options, see the +[CLI reference](/reference/cli/docker/sandbox/). -## Next Steps +## Next steps -Now that you have Claude running in a sandboxed environment, learn more about: +Now that you have Claude running in a sandbox, learn more about: -- [Authentication strategies](claude-code.md#authentication) -- [Configuration options](claude-code.md#configuration) -- [Advanced configurations](advanced-config.md) -- [Troubleshooting guide](troubleshooting.md) +- [Claude Code configuration](claude-code.md) +- [Supported agents](agents.md) +- [Using sandboxes effectively](workflows.md) +- [Custom templates](templates.md) +- [Network policies](network-policies.md) +- [Troubleshooting](troubleshooting.md) diff --git a/content/manuals/ai/sandboxes/migration.md b/content/manuals/ai/sandboxes/migration.md new file mode 100644 index 000000000000..2959681cc627 --- /dev/null +++ b/content/manuals/ai/sandboxes/migration.md @@ -0,0 +1,189 @@ +--- +title: Migrating from legacy sandboxes +description: Migrate from container-based sandboxes to microVM-based sandboxes +weight: 100 +--- + +{{< summary-bar feature_name="Docker Sandboxes" >}} + +Docker Desktop 4.58 introduces microVM-based sandboxes, replacing the previous +container-based implementation. This guide helps you migrate from legacy +sandboxes to the new architecture. + +## What changed + +Docker Sandboxes now run in lightweight microVMs instead of containers. Each +sandbox has a private Docker daemon, better isolation, and network filtering +policies. + +After upgrading to Docker Desktop 4.58: + +- Old sandboxes don't appear in `docker sandbox ls` +- They still exist as regular Docker containers and volumes +- You can see them with `docker ps -a` and `docker volume ls` +- Old sandboxes won't work with the new CLI commands +- Running `docker sandbox run` creates a new microVM-based sandbox + +## Migration options + +Choose the approach that fits your situation: + +### Option 1: Start fresh (recommended) + +This is the simplest approach for experimental features. You'll recreate your +sandbox with the new architecture. + +1. Note any important configuration or installed packages in your old sandbox. + +2. Remove the old sandbox containers: + + ```console + $ docker rm -f $(docker ps -q -a --filter="label=docker/sandbox=true") + ``` + +3. Remove the credential volume: + + ```console + $ docker volume rm docker-claude-sandbox-data + ``` + +4. Create a new microVM sandbox: + + ```console + $ docker sandbox create claude ~/project + $ docker sandbox run + ``` + +5. Reinstall dependencies. Ask the agent to install needed tools: + + ```plaintext + You: "Install all the tools needed to build and test this project" + Claude: [Installs tools] + ``` + +What you lose: + +- API keys (re-authenticate on first run, or set `ANTHROPIC_API_KEY`) +- Installed packages (reinstall via the agent) +- Custom configuration (reconfigure as needed) + +What you gain: + +- Better isolation (microVM versus container) +- Private Docker daemon for test containers +- Network filtering policies +- Improved security + +### Option 2: Migrate configuration + +If you have extensive customization, preserve your setup by creating a custom +template. + +1. Inspect your old sandbox to see what's installed: + + ```console + $ docker exec dpkg -l + ``` + +2. Create a custom template with your tools: + + ```dockerfile + FROM docker/sandbox-templates:claude-code + + USER root + + # Install your tools + RUN apt-get update && apt-get install -y \ + build-essential \ + nodejs \ + npm + + # Install language-specific packages + RUN npm install -g typescript eslint + + # Add any custom configuration + ENV EDITOR=vim + + USER agent + ``` + +3. Build your template: + + ```console + $ docker build -t my-sandbox-template:v1 . + ``` + +4. Create a new sandbox with your template: + + ```console + $ docker sandbox create --template my-sandbox-template:v1 \ + --load-local-template \ + claude ~/project + ``` + +5. Run the sandbox: + + ```console + $ docker sandbox run + ``` + +If you want to share this template with your team, push it to a registry. See +[Custom templates](templates.md) for details. + +## Cleanup old resources + +After migrating, clean up legacy containers and volumes: + +Remove specific sandbox: + +```console +$ docker rm -f +$ docker volume rm docker-claude-sandbox-data +``` + +Remove all stopped containers and unused volumes: + +```console +$ docker container prune +$ docker volume prune +``` + +> [!WARNING] +> `docker volume prune` removes ALL unused volumes, not just sandbox volumes. +> Make sure you don't have other important unused volumes before running this +> command. + +## Understanding the differences + +### Architecture + +Old (container-based): + +- Sandboxes were Docker containers +- Appeared in `docker ps` +- Mounted host Docker socket for container access +- Stored credentials in Docker volume + +New (microVM-based): + +- Sandboxes are lightweight microVMs +- Use `docker sandbox ls` to see them +- Private Docker daemon inside VM +- Credentials via `ANTHROPIC_API_KEY` environment variable or interactive auth + +### CLI changes + +Old command structure: + +```console +$ docker sandbox run ~/project +``` + +New command structure: + +```console +$ docker sandbox run claude ~/project +``` + +The agent name (`claude`, `codex`, `gemini`, `cagent`, `kiro`) is now a +required parameter when creating sandboxes, and you run the sandbox by name. diff --git a/content/manuals/ai/sandboxes/network-policies.md b/content/manuals/ai/sandboxes/network-policies.md new file mode 100644 index 000000000000..bc7aae314beb --- /dev/null +++ b/content/manuals/ai/sandboxes/network-policies.md @@ -0,0 +1,340 @@ +--- +title: Network policies +description: Configure network filtering policies to control outbound HTTP and HTTPS access from sandboxed agents. +weight: 55 +--- + +{{< summary-bar feature_name="Docker Sandboxes" >}} + +Network policies control what external resources a sandbox can access through +an HTTP/HTTPS filtering proxy. Use policies to prevent agents from accessing +internal networks, enforce compliance requirements, or restrict internet access +to specific services. + +Each sandbox has a filtering proxy that enforces policies for outbound HTTP and +HTTPS traffic. Connection to external services over other protocols, such as +raw TCP and UDP connections, are blocked. All agent communication must go +through the HTTP proxy or remain contained within the sandbox. + +The proxy runs on an ephemeral port on your host, but from the agent +container's perspective it is accessible at `host.docker.internal:3128`. + +### Security considerations + +Use network policies as one layer of security, not the only layer. The microVM +boundary provides the primary isolation. Network policies add an additional +control for HTTP/HTTPS traffic. + +The network filtering restricts which domains processes can connect to, but +doesn't inspect the traffic content. When configuring policies: + +- Allowing broad domains like `github.com` permits access to any content on + that domain, including user-generated content. Agents could use these as + channels for data exfiltration. +- Domain fronting techniques may bypass filters by routing traffic through + allowed domains. This is inherent to HTTPS proxying. + +Only allow domains you trust with your data. You're responsible for +understanding what your policies permit. + +## How network filtering works + +Each sandbox has an HTTP/HTTPS proxy running on your host. The proxy is +accessible from inside the sandbox at `host.docker.internal:3128`. + +When an agent makes HTTP or HTTPS requests, the proxy: + +1. Checks the policy rules against the host in the request. If the host is + blocked, the request is stopped immediately +2. Connects to the server. If the host was not explicitly allowed, checks the + server's IP address against BlockCIDR rules + +For example, `localhost` is not in the default allow-list, but it's allowed by the +default "allow" policy. Because it's not explicitly allowed, the proxy then checks +the resolved IP addresses (`127.0.0.1` or `::1`) against the BlockCIDR rules. +Since `127.0.0.1/8` and `::1/128` are both blocked by default, this catches any +DNS aliases for localhost like `ip6-localhost`. + +If an agent needs access to a service on localhost, include a port number in +the allow-list (e.g., `localhost:1234`). + +HTTP requests to `host.docker.internal` are rewritten to `localhost`, so only +the name `localhost` will work in the allow-list. + +## Monitor network activity + +View what your agent is accessing and whether requests are being blocked: + +```console +$ docker sandbox network log +``` + +Network logs help you understand agent behavior and define policies. + +## Applying policies + +Use `docker sandbox network proxy` to configure network policies for your +sandboxes. The sandbox must be running when you apply policy changes. Changes +take effect immediately and persist across sandbox restarts. + +### Example: Block internal networks + +Prevent agents from accessing your local network, Docker networks, and cloud +metadata services. It prevents accidental access to internal services while +allowing agents to install packages and access public APIs. + +```console +$ docker sandbox network proxy my-sandbox \ + --policy allow \ + --block-cidr 10.0.0.0/8 \ + --block-cidr 172.16.0.0/12 \ + --block-cidr 192.168.0.0/16 \ + --block-cidr 127.0.0.0/8 +``` + +This policy: + +- Allows internet access +- Blocks RFC 1918 private networks (10.x.x.x, 172.16-31.x.x, 192.168.x.x) +- Blocks localhost (127.x.x.x) + +> [!NOTE] +> These CIDR blocks are already blocked by default. The example above shows how +> to explicitly configure them if needed. The default policy blocks: +> +> - `10.0.0.0/8` +> - `127.0.0.0/8` +> - `169.254.0.0/16` +> - `172.16.0.0/12` +> - `192.168.0.0/16` +> - `::1/128` +> - `fc00::/7` +> - `fe80::/10` + +### Example: Restrict to package managers only + +For strict control, use a denylist policy that only allows package repositories: + +```console +$ docker sandbox network proxy my-sandbox \ + --policy deny \ + --allow-host "*.npmjs.org" \ + --allow-host "*.pypi.org" \ + --allow-host "files.pythonhosted.org" \ + --allow-host "*.rubygems.org" \ + --allow-host github.com +``` + +> [!NOTE] +> This policy would block the backend of your AI coding agent (e.g., for Claude +> Code: `xyz.anthropic.com`). Make sure you also include hostnames that the +> agent requires. + +The agent can install dependencies but can't access arbitrary internet +resources. This is useful for CI/CD environments or when running untrusted code. + +### Example: Allow AI APIs and development tools + +Combine AI service access with package managers and version control: + +```console +$ docker sandbox network proxy my-sandbox \ + --policy deny \ + --allow-host api.anthropic.com \ + --allow-host "*.npmjs.org" \ + --allow-host "*.pypi.org" \ + --allow-host github.com \ + --allow-host "*.githubusercontent.com" +``` + +This allows agents to call AI APIs, install packages, and fetch code from +GitHub while blocking other internet access. + +### Example: Allow specific APIs while blocking subdomains + +Use port-specific rules and subdomain patterns for fine-grained control: + +```console +$ docker sandbox network proxy my-sandbox \ + --policy deny \ + --allow-host api.example.com:443 \ + --allow-host cdn.example.com \ + --allow-host "*.storage.example.com:443" +``` + +This policy allows: + +- Requests to `api.example.com` on port 443 (typically + `https://api.example.com`) +- Requests to `cdn.example.com` on any port +- Requests to any subdomain of `storage.example.com` on port 443, like + `us-west.storage.example.com:443` or `eu-central.storage.example.com:443` + +Requests to `example.com` (any port), `www.example.com` (any port), or +`api.example.com:8080` would all be blocked because none match the specific +patterns. + +To allow both a domain and all its subdomains, specify both patterns: + +```console +$ docker sandbox network proxy my-sandbox \ + --policy deny \ + --allow-host example.com \ + --allow-host "*.example.com" +``` + +## Policy modes: allowlist versus denylist + +Policies have two modes that determine default behavior. + +### Allowlist mode + +Default: Allow all traffic, block specific destinations. + +```console +$ docker sandbox network proxy my-sandbox \ + --policy allow \ + --block-cidr 192.0.2.0/24 \ + --block-host example.com +``` + +Use allowlist mode when you want agents to access most resources but need to +block specific networks or domains. This is less restrictive and works well for +development environments where the agent needs broad internet access. + +### Denylist mode + +Default: Block all traffic, allow specific destinations. + +```console +$ docker sandbox network proxy my-sandbox \ + --policy deny \ + --allow-host api.anthropic.com \ + --allow-host "*.npmjs.org" +``` + +Use denylist mode when you want tight control over external access. This +requires explicitly allowing each service the agent needs, making it more +secure but also more restrictive. Good for production deployments, CI/CD +pipelines, or untrusted code. + +### Domain and CIDR matching + +Domain patterns support exact matches, wildcards, and port specifications: + +- `example.com` matches only that exact domain (any port) +- `example.com:443` matches requests to `example.com` on port 443 (the default + HTTPS port) +- `*.example.com` matches all subdomains like `api.example.com` or + `www.example.com` +- `*.example.com:443` matches requests to any subdomain on port 443 + +Important pattern behaviors: + +- `example.com` does NOT match subdomains. A request to `api.example.com` + won't match a rule for `example.com`. +- `*.example.com` does NOT match the root domain. A request to `example.com` + won't match a rule for `*.example.com`. +- To allow both a domain and its subdomains, specify both patterns: + `example.com` and `*.example.com`. + +When multiple patterns could match a request, the most specific pattern wins: + +1. Exact hostname and port: `api.example.com:443` +2. Exact hostname, any port: `api.example.com` +3. Wildcard patterns (longest match first): `*.api.example.com:443`, + `*.api.example.com`, `*.example.com:443`, `*.example.com` +4. Catch-all wildcards: `*:443`, `*` +5. Default policy (allow or deny) + +This specificity lets you block broad patterns while allowing specific +exceptions. For example, you can block `example.com` and `*.example.com` but +allow `api.example.com:443`. + +CIDR blocks match IP addresses after DNS resolution: + +- `192.0.2.0/24` blocks all 192.0.2.x addresses +- `198.51.100.0/24` blocks all 198.51.100.x addresses +- `203.0.113.0/24` blocks all 203.0.113.x addresses + +When you block or allow a domain, the proxy resolves it to IP addresses and +checks those IPs against CIDR rules. This means blocking a CIDR range affects +any domain that resolves to an IP in that range. + +## Bypass mode for HTTPS tunneling + +By default, the proxy acts as a man-in-the-middle for HTTPS connections, +terminating TLS and re-encrypting traffic with its own certificate authority. +This allows the proxy to enforce policies and inject authentication credentials +for certain services. The sandbox container trusts the proxy's CA certificate. + +Some applications use certificate pinning or other techniques that don't work +with MITM proxies. For these cases, use bypass mode to tunnel HTTPS traffic +directly without inspection: + +```console +$ docker sandbox network proxy my-sandbox \ + --bypass-host api.service-with-pinning.com +``` + +You can also bypass traffic to specific IP ranges: + +```console +$ docker sandbox network proxy my-sandbox \ + --bypass-cidr 203.0.113.0/24 +``` + +When traffic is bypassed, the proxy: + +- Acts as a simple TCP tunnel without inspecting content +- Cannot inject authentication credentials into requests +- Cannot detect domain fronting or other evasion techniques +- Still enforces domain and port matching based on the initial connection + +Use bypass mode only when necessary. Bypassed traffic loses the visibility and +security benefits of MITM inspection. If you bypass broad domains like +`github.com`, the proxy has no visibility into what the agent accesses on that +domain. + +## Policy persistence + +Network policies are stored in JSON configuration files. + +### Per-sandbox configuration + +When you run `docker sandbox network proxy my-sandbox`, the command updates the +configuration for that specific sandbox only. The policy is persisted to +`~/.docker/sandboxes/vm/my-sandbox/proxy-config.json`. + +The default policy (used when creating new sandboxes) remains unchanged unless +you modify it directly. + +### Default configuration + +The default network policy for new sandboxes is stored at +`~/.sandboxd/proxy-config.json`. This file is created automatically when the +first sandbox starts, but only if it doesn't already exist. + +The current default policy is `allow`, which permits all outbound connections +except to blocked CIDR ranges (private networks, localhost, and cloud metadata +services). This default will change to `deny` in a future release to provide +more restrictive defaults. + +You can modify the default policy: + +1. Edit `~/.sandboxd/proxy-config.json` directly +2. Or copy a sandbox policy to the default location: + + ```console + $ cp ~/.docker/sandboxes/vm/my-sandbox/proxy-config.json ~/.sandboxd/proxy-config.json + ``` + +Review and customize the default policy to match your security requirements +before creating new sandboxes. Once created, the default policy file won't be +modified by upgrades, preserving your custom configuration. + +## Next steps + +- [Architecture](architecture.md) +- [Using sandboxes effectively](workflows.md) +- [Custom templates](templates.md) diff --git a/content/manuals/ai/sandboxes/templates.md b/content/manuals/ai/sandboxes/templates.md new file mode 100644 index 000000000000..d2cd4c4ae4f0 --- /dev/null +++ b/content/manuals/ai/sandboxes/templates.md @@ -0,0 +1,161 @@ +--- +title: Custom templates +description: Create custom sandbox templates to standardize development environments with pre-installed tools and configurations. +weight: 45 +--- + +{{< summary-bar feature_name="Docker Sandboxes" >}} + +Custom templates let you create reusable sandbox environments with +pre-installed tools and configuration. Instead of asking the agent to install +packages each time, build a template with everything ready. + +## When to use custom templates + +Use custom templates when: + +- Multiple team members need the same environment +- You're creating many sandboxes with identical tooling +- Setup involves complex steps that are tedious to repeat +- You need specific versions of tools or libraries + +For one-off work or simple setups, use the default template and ask the agent +to install what's needed. + +## Building a template + +Start from Docker's official sandbox templates: + +```dockerfile +FROM docker/sandbox-templates:claude-code + +USER root + +# Install system packages +RUN apt-get update && apt-get install -y \ + build-essential \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +# Install development tools +RUN pip3 install --no-cache-dir \ + pytest \ + black \ + pylint + +USER agent +``` + +Official templates include the agent binary, Ubuntu base, development tools +(Git, Docker CLI, Node.js, Python, Go), and the non-root `agent` user with +sudo access. + +### The USER pattern + +Switch to `root` for system-level installations, then back to `agent` at the +end. The base template defaults to `USER agent`, so you need to explicitly +switch to root for package installations. Always switch back to `agent` before +the end of your Dockerfile so the agent runs with the correct permissions. + +### Using templates + +Build your template: + +```console +$ docker build -t my-template:v1 . +``` + +Then choose how to use it: + +Option 1: Load from local images (quick, for personal use) + +```console +$ docker sandbox create --template my-template:v1 \ + --load-local-template \ + claude ~/project +$ docker sandbox run +``` + +The `--load-local-template` flag loads the image from your local Docker daemon +into the sandbox VM. This works for quick iteration and personal templates. + +Option 2: Push to a registry (for sharing and persistence) + +```console +$ docker tag my-template:v1 myorg/my-template:v1 +$ docker push myorg/my-template:v1 +$ docker sandbox create --template myorg/my-template:v1 claude ~/project +$ docker sandbox run +``` + +Pushing to a registry makes templates available to your team and persists them +beyond your local machine. + +## Example: Node.js template + +```dockerfile +FROM docker/sandbox-templates:claude-code + +USER root + +RUN apt-get update && apt-get install -y curl \ + && rm -rf /var/lib/apt/lists/* + +# Install Node.js 20 LTS +RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ + && apt-get install -y nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Install common tools +RUN npm install -g \ + typescript@5.1.6 \ + eslint@8.46.0 \ + prettier@3.0.0 + +USER agent +``` + +Pin versions for reproducible builds. + +## Using standard images + +You can use standard Docker images (like `python:3.11` or `node:20`) as a +base, but they don't include agent binaries or sandbox configuration. + +Using a standard image directly creates the sandbox but fails at runtime: + +```console +$ docker sandbox create --template python:3-slim claude ~/project +✓ Created sandbox claude-sandbox-2026-01-16-170525 in VM claude-project + +$ docker sandbox run claude-project +agent binary "claude" not found in sandbox: verify this is the correct sandbox type +``` + +To use a standard image, you'd need to install the agent binary, add sandbox +dependencies, configure the shell, and set up the `agent` user. Building from +`docker/sandbox-templates:claude-code` is simpler. + +## Sharing with teams + +Push templates to a registry and version them: + +```console +$ docker build -t myorg/sandbox-templates:python-v1.0 . +$ docker push myorg/sandbox-templates:python-v1.0 +``` + +Team members can then use the template: + +```console +$ docker sandbox create --template myorg/sandbox-templates:python-v1.0 claude ~/project +``` + +Using version tags (`:v1.0`, `:v2.0`) instead of `:latest` ensures stability +across your team. + +## Next steps + +- [Using sandboxes effectively](workflows.md) +- [Architecture](architecture.md) +- [Network policies](network-policies.md) diff --git a/content/manuals/ai/sandboxes/troubleshooting.md b/content/manuals/ai/sandboxes/troubleshooting.md index a59d3d4e9882..121a160da819 100644 --- a/content/manuals/ai/sandboxes/troubleshooting.md +++ b/content/manuals/ai/sandboxes/troubleshooting.md @@ -50,21 +50,7 @@ ask your administrator to [allow beta features](/enterprise/security/hardened-de Claude can't authenticate, or you see API key errors. -The API key is likely invalid, expired, or not configured correctly. How to fix depends on your credential mode: - -If using `--credentials=sandbox` (the default): - -1. Remove the stored credentials: - - ```console - $ docker volume rm docker-claude-sandbox-data - ``` - -2. Start a new sandbox and complete the authentication workflow: - - ```console - $ docker sandbox run claude - ``` +The API key is likely invalid, expired, or not configured correctly. ## Workspace contains API key configuration diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md new file mode 100644 index 000000000000..b6e13856fb24 --- /dev/null +++ b/content/manuals/ai/sandboxes/workflows.md @@ -0,0 +1,157 @@ +--- +title: Using sandboxes effectively +linkTitle: Workflows +description: Best practices and common workflows for Docker Sandboxes including dependency management, testing, and multi-project setups. +weight: 35 +--- + +{{< summary-bar feature_name="Docker Sandboxes" >}} + +This guide covers practical patterns for working with sandboxed agents. + +## Basic workflow + +Create a sandbox for your project: + +```console +$ cd ~/my-project +$ docker sandbox run claude . +``` + +The sandbox persists. Stop and restart it without losing installed packages or +configuration: + +```console +$ docker sandbox run # Reconnect later +``` + +## Installing dependencies + +Ask the agent to install what's needed: + +```plaintext +You: "Install pytest and black" +Claude: [Installs packages via pip] + +You: "Install build-essential" +Claude: [Installs via apt] +``` + +The agent has sudo access. Installed packages persist for the sandbox lifetime. +This works for system packages, language packages, and development tools. + +For teams or repeated setups, use [Custom templates](templates.md) to +pre-install tools. + +## Docker inside sandboxes + +Agents can build images, run containers, and use Docker Compose. Everything +runs inside the sandbox's private Docker daemon. + +### Testing containerized apps + +```plaintext +You: "Build the Docker image and run the tests" + +Claude: *runs* + docker build -t myapp:test . + docker run myapp:test npm test +``` + +Containers started by the agent run inside the sandbox, not on your host. They +don't appear in your host's `docker ps`. + +### Multi-container stacks + +```plaintext +You: "Start the application with docker-compose and run integration tests" + +Claude: *runs* + docker-compose up -d + docker-compose exec api pytest tests/integration + docker-compose down +``` + +Remove the sandbox, and all images, containers, and volumes are deleted. + +## What persists + +While a sandbox exists: + +- Installed packages (apt, pip, npm, etc.) +- Docker images and containers inside the sandbox +- Configuration changes +- Command history + +When you remove a sandbox: + +- Everything inside is deleted +- Your workspace files remain on your host (synced back) + +To preserve a configured environment, create a [Custom template](templates.md). + +## Named sandboxes + +Use meaningful names for sandboxes you'll reuse: + +```console +$ docker sandbox run --name myproject claude ~/project +``` + +Create multiple sandboxes for the same workspace: + +```console +$ docker sandbox create --name dev claude ~/project +$ docker sandbox create --name staging claude ~/project +$ docker sandbox run dev +``` + +Each maintains separate packages, Docker images, and state, but share the +workspace files. + +## Debugging + +Access the sandbox directly with an interactive shell: + +```console +$ docker sandbox exec -it bash +``` + +Inside the shell, you can inspect the environment, manually install packages, +or check Docker containers: + +```console +agent@sandbox:~$ docker ps +agent@sandbox:~$ docker images +``` + +List all sandboxes: + +```console +$ docker sandbox ls +``` + +## Managing multiple projects + +Create sandboxes for different projects: + +```console +$ docker sandbox create claude ~/project-a +$ docker sandbox create claude ~/project-b +$ docker sandbox create claude ~/work/client-project +``` + +Each sandbox is completely isolated. Switch between them by running the +appropriate sandbox name. + +Remove unused sandboxes to reclaim disk space: + +```console +$ docker sandbox rm +``` + +## Next steps + +- [Custom templates](templates.md) +- [Architecture](architecture.md) +- [Network policies](network-policies.md) diff --git a/data/summary.yaml b/data/summary.yaml index 6a094df9f637..8fd6147eaa16 100644 --- a/data/summary.yaml +++ b/data/summary.yaml @@ -189,7 +189,7 @@ Docker Projects: availability: Beta Docker Sandboxes: availability: Experimental - requires: Docker Desktop [4.50](/manuals/desktop/release-notes.md#4500) or later + requires: Docker Desktop [4.58](/manuals/desktop/release-notes.md#4580) or later Docker Scout exceptions: availability: Experimental requires: Docker Scout CLI [1.15.0](/manuals/scout/release-notes/cli.md#1150) and later