zidane/ contexts/ docker
An execution context that runs commands and file operations inside a local Docker container.
import { … } from 'zidane/contexts/docker'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.
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#
buildBindSpecsFunction#
Assemble dockerode HostConfig.Binds from the context's mounts.
function buildBindSpecs(mounts: ContextMount[]): string[]Parameters
| Name | Type | Description |
|---|---|---|
| mounts | ContextMount[] | Mounts to convert. Throws when a source or target is missing or a mount is both read-only and shared. |
Returns
string[]createDockerContextFunction#
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.
function createDockerContext(config?: SpawnConfig): ExecutionContextParameters
| Name | Type | Description |
|---|---|---|
| config? | SpawnConfig | Default spawn settings, such as |
Returns
Example
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' }),
})hostWorkspaceMountsFunction#
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.
function hostWorkspaceMounts(cwd: string): ContextMount[]Parameters
| Name | Type | Description |
|---|---|---|
| cwd | string | Absolute host directory the agent works in. |
Returns
packTarFileFunction#
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.
function packTarFile(name: string, data: Buffer): Promise<Buffer<ArrayBufferLike>>Parameters
| Name | Type | Description |
|---|---|---|
| name | string | Entry name inside the archive. |
| data | Buffer | File contents. |
Returns
Promise<Buffer<ArrayBufferLike>>Constants#
READ_FILE_MAX_BUFFERConstant#
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.
const READ_FILE_MAX_BUFFER: number