DockerSandbox
在本机的 Docker 容器中执行命令。使用长期运行的容器,并通过 docker exec 执行命令。适用于本地开发、CI/CD、隔离网络部署,以及无需云端 Sandbox、对成本敏感的场景。有关接口详情,请参阅 WorkspaceSandbox 接口。
安装安装的直接链接
- npm
- pnpm
- Yarn
- Bun
npm install @mastra/docker
pnpm add @mastra/docker
yarn add @mastra/docker
bun add @mastra/docker
要求宿主机上运行 Docker Engine。
用法用法的直接链接
将 DockerSandbox 添加到 Workspace,并将其分配给 Agent:
import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { DockerSandbox } from '@mastra/docker'
const workspace = new Workspace({
sandbox: new DockerSandbox({
image: 'node:22-slim',
}),
})
const agent = new Agent({
id: 'dev-agent',
name: 'dev-agent',
model: 'anthropic/claude-opus-4-7',
workspace,
})
构造函数参数构造函数参数的直接链接
id?:
name?:
--name 传给 Docker 的容器显示名称。[a-zA-Z0-9_.-] 之外的字符会替换为 -;如果结果不是以字母或数字开头,则会为其添加前缀。image?:
command?:
env?:
volumes?:
network?:
privileged?:
memory?:
memorySwap?:
cpuQuota?:
cpuPeriod?:
pidsLimit?:
readonlyRootfs?:
capDrop?:
capAdd?:
securityOpt?:
ulimits?:
tmpfs?:
workingDir?:
labels?:
timeout?:
dockerOptions?:
instructions?:
属性属性的直接链接
id:
name:
provider:
status:
container:
processes:
后台进程后台进程的直接链接
DockerSandbox 内置了用于生成和管理后台进程的进程管理器。进程使用 docker exec 在容器内运行。
const sandbox = new DockerSandbox({ id: 'dev-sandbox' })
await sandbox._start()
// Spawn a background process
const handle = await sandbox.processes.spawn('node server.js', {
env: { PORT: '3000' },
onStdout: data => console.log(data),
})
// Interact with the process
console.log(handle.stdout)
await handle.sendStdin('input\n')
await handle.kill()
有关完整 API,请参阅 SandboxProcessManager 参考。
环境变量环境变量的直接链接
使用 env 在容器级别设置环境变量。生成进程时也可以传入每个命令专属的环境变量:
const sandbox = new DockerSandbox({
image: 'node:22-slim',
env: {
NODE_ENV: 'production',
DATABASE_URL: 'postgres://localhost:5432/mydb',
},
})
Bind mountBind mount的直接链接
使用 volumes 选项将宿主目录挂载到容器中:
const sandbox = new DockerSandbox({
image: 'node:22-slim',
volumes: {
'/my/project': '/workspace/project',
'/shared/data': '/data',
},
})
Bind mount 会在创建容器时应用。宿主路径必须在 Sandbox 启动前存在。
安全强化安全强化的直接链接
使用 Docker 专属资源和安全强化选项来限制 Sandbox 容器。以下示例对内存和进程数量设置上限,同时通过相同的 cpuPeriod 和 cpuQuota 值将 CPU 限制为一个核心。它还会移除 Linux capability,并将根文件系统设为只读,同时把 /tmp 挂载为可写的临时空间:
const sandbox = new DockerSandbox({
image: 'node:22-slim',
memory: 512 * 1024 * 1024,
memorySwap: 512 * 1024 * 1024,
cpuPeriod: 100_000,
cpuQuota: 100_000,
pidsLimit: 256,
readonlyRootfs: true,
capDrop: ['ALL'],
capAdd: ['NET_BIND_SERVICE'],
securityOpt: ['no-new-privileges:true'],
ulimits: [{ name: 'nofile', soft: 1024, hard: 2048 }],
tmpfs: {
'/tmp': 'rw,noexec,nosuid,size=64m',
},
})
这些选项会直接映射到 Docker HostConfig 字段,并且只有在传入时才会设置。
启用安全强化前,请考虑以下权衡:
readonlyRootfs:容器内的软件包安装,以及写入挂载路径之外位置的 Tool 可能会失败。请为/tmp等可写临时路径添加tmpfs条目;如有需要,也可为~/.npm等软件包管理器缓存挂载 tmpfs 或 volume。capDrop:移除所有 capability 会禁用需要 Linux capability 的命令,包括ping和 mount 操作。基于 FUSE 的 Tool 也会被禁用。请仅重新添加工作负载需要的 capability。memory:Docker 将0视为无限制。只有在不需要内存上限时,才应省略memory或传入0。memorySwap:Docker 的内存和 swap 行为取决于宿主和 Docker daemon 配置。如果设置memory而未设置memorySwap,Docker 默认允许使用最多为内存限制两倍的 swap。如果要禁用容器 swap,请将memorySwap设为与memory相同的值;Docker 也接受-1,表示 swap 不受限制。pidsLimit:过低的值可能会破坏docker exec工作负载,因为每个命令都会在长期运行的容器内启动额外进程。privileged:Privileged 容器会绕过 capability 和安全选项控制。除非工作负载需要,否则不要将privileged: true与 capability 或安全选项结合使用。- 重新连接:当 Sandbox ID 匹配时,
DockerSandbox会复用现有容器;如果检查到的HostConfig安全强化值不同,则发出警告。要应用更改后的安全强化选项,请销毁并重新创建 Sandbox。Docker 可能会规范化检查到的值;如果原始容器采用 Docker 默认 swap 行为,重新连接时更改memorySwap可能会触发警告。 - Docker Desktop:在 macOS 和 Windows 上,资源限制应用于 Docker Desktop 虚拟机内部,因此 VM 分配的资源可能会限制容器实际可用的资源。
重新连接重新连接的直接链接
DockerSandbox 可以通过匹配 label 重新连接到现有容器。调用 start() 时,它会检查是否存在 mastra.sandbox.id label 与 Sandbox ID 匹配的容器。如果找到:
- 正在运行的容器会被直接复用。
- 已停止的容器会重新启动。
// First run — creates a new container
const sandbox = new DockerSandbox({ id: 'persistent-sandbox' })
await sandbox._start()
// Later — reconnects to the existing container
const sandbox2 = new DockerSandbox({ id: 'persistent-sandbox' })
await sandbox2._start()
Docker 连接选项Docker 连接选项的直接链接
通过 dockerOptions 连接到远程 Docker host 或使用自定义 socket 路径:
// Remote Docker host
const sandbox = new DockerSandbox({
dockerOptions: {
host: '192.168.1.100',
port: 2376,
ca: fs.readFileSync('ca.pem'),
cert: fs.readFileSync('cert.pem'),
key: fs.readFileSync('key.pem'),
},
})
// Custom socket path
const sandbox = new DockerSandbox({
dockerOptions: {
socketPath: '/var/run/docker.sock',
},
})