# zidane/contexts/docker

> An execution context that runs commands and file operations inside a local Docker container.

Import: `import { … } from 'zidane/contexts/docker'`. Source: [src/contexts/docker.ts](https://github.com/Tahul/zidane/blob/main/src/contexts/docker.ts).

Use `createDockerContext` when you want a disposable environment on your machine. Each spawn starts a container through `dockerode`, an optional peer dependency, and destroy removes it. The helpers here build bind mounts and pack files into tar archives for container transfers.

```ts
import { createDockerContext } from 'zidane/contexts/docker'

const context = createDockerContext({ image: 'node:22', cwd: '/workspace', limits: { memory: 512, cpu: '1.0' } })
const handle = await context.spawn()
const result = await context.exec(handle, 'node --version')
console.log(result.stdout)
await context.destroy(handle)
```

## Functions

### `buildBindSpecs`

Function.

Assemble dockerode `HostConfig.Binds` from the context's `mounts`.

```ts
function buildBindSpecs(mounts: ContextMount[]): string[]
```

**Parameters**

- `mounts` (`ContextMount[]`): Mounts to convert. Throws when a source or target is missing or a mount is both read-only and shared.

**Returns** `string[]`

Source: [src/contexts/docker-spawn.ts:28](https://github.com/Tahul/zidane/blob/main/src/contexts/docker-spawn.ts#L28)

### `createDockerContext`

Function.

Creates an execution context that runs commands and file operations inside a Docker container.
Each `spawn` starts a container through `dockerode`, an optional peer dependency, and `destroy` removes it. Resource limits, mounts and hardening come from the spawn config.

```ts
function createDockerContext(config?: SpawnConfig): ExecutionContext
```

**Parameters**

- `config?` (`SpawnConfig`): Default spawn settings, such as `image`, `cwd`, `mounts` and `limits`.

**Returns** `ExecutionContext`

**Example**

```ts
import { createAgent } from 'zidane'
import { createDockerContext } from 'zidane/contexts/docker'
import { basic } from 'zidane/presets'
import { anthropic } from 'zidane/providers/anthropic'

const agent = createAgent({
  ...basic,
  provider: anthropic(),
  execution: createDockerContext({ image: 'node:22', cwd: '/workspace' }),
})
```

Source: [src/contexts/docker.ts:54](https://github.com/Tahul/zidane/blob/main/src/contexts/docker.ts#L54)

### `hostWorkspaceMounts`

Function.

Path-equal bind mounts that make a HOST working directory usable inside a
container: the enclosing git worktree (or `cwd` itself outside git) at the
same absolute path, plus the git common dir when it lives outside that
tree (a linked worktree's `.git` file points there — without it, git fails
in the container). Path-equal keeps host-side features (diffs, artifacts,
`@`-paths) valid for the same absolute paths the agent sees.

The git dir's `hooks/` and `config` (plus `config.worktree` when present or
enabled) are overlaid read-only — created empty first if absent: host-side git
(zidane's own diff/workspace calls included) would otherwise run hooks or
`core.fsmonitor` / `core.hooksPath` planted from inside the container.
Deliberate cost: git commands that WRITE config fail inside the container —
`git push -u` / `--set-upstream`, `git branch --set-upstream-to`,
`git remote add`, `git config …`. Commits, fetches and a plain
`git push <remote> <branch>` work; environments that publish a branch must
push without recording an upstream.

Returns `[]` when `cwd` is not an existing host directory, so a
container-only path (`--cwd /workspace`) stays a path inside the container, and
when the tree to mount is `/`, `$HOME`, or an ancestor of `$HOME` (too broad
to hand a container read-write). A git root that is too broad falls back to
`cwd` alone (no git dir), so a dotfiles repo at `$HOME` doesn't blank every
project under it.

```ts
function hostWorkspaceMounts(cwd: string): ContextMount[]
```

**Parameters**

- `cwd` (`string`): Absolute host directory the agent works in.

**Returns** `ContextMount[]`

Source: [src/contexts/docker.ts:169](https://github.com/Tahul/zidane/blob/main/src/contexts/docker.ts#L169)

### `packTarFile`

Function.

Pack a single file into an in-memory tar archive for `putArchive`, via
`tar-stream` (the same battle-tested packer the dockerode ecosystem uses
for build contexts). Optional peer dependency, loaded lazily like
dockerode itself so the module graph stays lean for non-docker users.

```ts
function packTarFile(name: string, data: Buffer): Promise<Buffer<ArrayBufferLike>>
```

**Parameters**

- `name` (`string`): Entry name inside the archive.
- `data` (`Buffer`): File contents.

**Returns** `Promise<Buffer<ArrayBufferLike>>`

Source: [src/contexts/docker-files.ts:151](https://github.com/Tahul/zidane/blob/main/src/contexts/docker-files.ts#L151)

## Constants

### `READ_FILE_MAX_BUFFER`

Constant.

`readFile` transport cap: headroom above the whole-read tool ceiling
(256MB in tools/whole-read-guard.ts) so tool policy — not the docker
transport — decides read limits, keeping refusal behavior consistent
across contexts. Still bounded: a probe-failure path can't buffer
more than this into host memory.

```ts
const READ_FILE_MAX_BUFFER: number
```

Source: [src/contexts/docker-files.ts:23](https://github.com/Tahul/zidane/blob/main/src/contexts/docker-files.ts#L23)
