본문으로 건너뛰기

도커샌드박스

로컬 머신의 Docker 컨테이너 내에서 명령을 실행합니다. 다음과 같은 수명이 긴 컨테이너를 사용합니다.docker exec명령 실행을 위해. 클라우드 샌드박스가 불필요한 로컬 개발, CI/CD, 에어 갭 배포 및 비용에 민감한 시나리오를 대상으로 합니다. 인터페이스에 대한 자세한 내용은 다음을 참조하세요.WorkspaceSandbox 인터페이스.

설치
설치에 대한 직접 링크

npm install @mastra/docker

호스트 시스템에서 Docker Engine이 실행 중이어야 합니다.

용법
용법에 대한 직접 링크

Workspace에 DockerSandbox를 추가하고 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?:

string
= 자동 생성
이 Sandbox 인스턴스의 고유 식별자입니다. 레이블 기반 재연결에 사용됩니다.

name?:

string
= Sandbox `id`
--name으로 Docker에 전달되는 컨테이너 표시 이름입니다. [a-zA-Z0-9_.-]에 포함되지 않는 문자는 -로 대체되며, 결과가 영숫자로 시작하지 않으면 접두사가 추가됩니다.

image?:

string
= 'node:22-slim'
컨테이너에 사용할 Docker 이미지입니다.

command?:

string[]
= ['sleep', 'infinity']
컨테이너 진입점 명령입니다. exec 기반 명령을 실행할 수 있도록 컨테이너를 계속 실행 상태로 유지해야 합니다.

env?:

Record<string, string>
컨테이너에 설정할 환경 변수입니다.

volumes?:

Record<string, string>
호스트와 컨테이너 간 바인드 마운트입니다. 키는 호스트 경로이고 값은 컨테이너 경로입니다.

network?:

string
연결할 Docker 네트워크입니다.

privileged?:

boolean
= false
권한 모드로 실행합니다.

memory?:

number
바이트 단위 Memory 제한입니다. Docker는 0을 무제한으로 처리합니다. Docker HostConfig.Memory에 매핑됩니다.

memorySwap?:

number
바이트 단위의 총 Memory 및 스왑 용량입니다. Docker HostConfig.MemorySwap에 매핑됩니다.

cpuShares?:

number
CPU 공유의 상대적 가중치입니다. Docker HostConfig.CpuShares에 매핑됩니다.

cpuQuota?:

number
주기당 마이크로초 단위 CPU 할당량입니다. Docker HostConfig.CpuQuota에 매핑됩니다.

cpuPeriod?:

number
마이크로초 단위 CPU 주기입니다. Docker HostConfig.CpuPeriod에 매핑됩니다.

pidsLimit?:

number
컨테이너 내 프로세스 ID의 최대 개수입니다. Docker HostConfig.PidsLimit에 매핑됩니다.

readonlyRootfs?:

boolean
컨테이너의 루트 파일 시스템을 읽기 전용으로 마운트합니다. Docker HostConfig.ReadonlyRootfs에 매핑됩니다.

capDrop?:

string[]
제거할 Linux capability입니다. 특정 capability를 추가하기 전에 모든 capability를 제거하려면 ['ALL']을 사용합니다. Docker HostConfig.CapDrop에 매핑됩니다.

capAdd?:

string[]
제거 후 다시 추가할 NET_BIND_SERVICE와 같은 Linux capability입니다. Docker HostConfig.CapAdd에 매핑됩니다.

securityOpt?:

string[]
['no-new-privileges:true']와 같은 Docker 보안 옵션입니다. Docker HostConfig.SecurityOpt에 매핑됩니다.

ulimits?:

Array<{ name: string; soft: number; hard: number }>
컨테이너의 Ulimit 항목입니다. Docker HostConfig.Ulimits에 매핑됩니다.

tmpfs?:

Record<string, string>
tmpfs 마운트 경로 및 옵션입니다. Docker HostConfig.Tmpfs에 매핑됩니다.

workingDir?:

string
= '/workspace'
컨테이너 내부의 작업 디렉터리입니다.

labels?:

Record<string, string>
추가 컨테이너 레이블입니다. Mastra 레이블(mastra.sandbox, mastra.sandbox.id)은 항상 포함됩니다.

timeout?:

number
= 300000(5분)
밀리초 단위의 기본 명령 제한 시간입니다.

dockerOptions?:

Docker.DockerOptions
사용자 지정 소켓 경로, 원격 호스트 또는 TLS 인증서를 위한 dockerode 연결 옵션을 그대로 전달합니다.

instructions?:

string | function
getInstructions()가 반환하는 기본 지침을 재정의하는 사용자 지정 지침입니다. 지침을 표시하지 않으려면 빈 문자열을 전달합니다.

속성
속성에 대한 직접 링크

id:

string
Sandbox 인스턴스 식별자입니다.

name:

string
Provider 이름입니다('DockerSandbox').

provider:

string
Provider 식별자입니다('docker').

status:

ProviderStatus
'pending' | 'starting' | 'running' | 'stopping' | 'stopped' | 'destroying' | 'destroyed' | 'error'

container:

Container
기본 dockerode Container 인스턴스입니다. Sandbox가 시작되지 않았으면 SandboxNotReadyError를 발생시킵니다.

processes:

DockerProcessManager
백그라운드 프로세스 관리자입니다. SandboxProcessManager 레퍼런스를 참조하세요.

백그라운드 프로세스
백그라운드 프로세스에 대한 직접 링크

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',
},
})

바인드 마운트
바인드 마운트에 대한 직접 링크

다음을 사용하여 호스트 디렉터리를 컨테이너에 마운트합니다.volumes option:

const sandbox = new DockerSandbox({
image: 'node:22-slim',
volumes: {
'/my/project': '/workspace/project',
'/shared/data': '/data',
},
})

바인드 마운트는 컨테이너 생성 시 적용됩니다. 샌드박스가 시작되기 전에 호스트 경로가 존재해야 합니다.

경화
경화에 대한 직접 링크

Docker 전용 리소스 및 강화 옵션을 사용하여 Sandbox 컨테이너를 제한합니다. 다음 예에서는 일치하는 cpuPeriodcpuQuota 값을 사용하여 CPU를 단일 코어로 제한하는 동시에 Memory와 프로세스 수를 제한합니다. 또한 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 또는 볼륨을 마운트하세요.
  • capDrop: 모든 capability를 제거하면 ping 및 마운트 작업을 비롯해 Linux capability가 필요한 명령이 비활성화됩니다. FUSE 기반 Tool도 비활성화됩니다. 워크로드에 필요한 capability만 다시 추가하세요.
  • memory: Docker는 0을 무제한으로 처리합니다. Memory 제한이 필요하지 않은 경우에만 memory를 생략하거나 0을 전달하세요.
  • memorySwap: Docker Memory 및 스왑 동작은 호스트와 Docker 데몬 구성에 따라 달라집니다. memorySwap 없이 memory를 설정하면 Docker는 기본적으로 Memory 제한의 최대 두 배까지 스왑을 허용합니다. 컨테이너의 스왑을 비활성화하려면 memorySwapmemory와 동일하게 설정하세요. Docker는 무제한 스왑을 뜻하는 -1도 허용합니다.
  • pidsLimit: 값이 너무 낮으면 장기 실행 컨테이너 내부에서 각 명령이 추가 프로세스를 시작하므로 docker exec 워크로드가 제대로 작동하지 않을 수 있습니다.
  • privileged: 권한 있는 컨테이너는 capability 및 보안 옵션 제어를 우회합니다. 워크로드에 필요한 경우가 아니면 privileged: true를 capability 또는 보안 옵션과 함께 사용하지 마세요.
  • 재연결: DockerSandbox는 Sandbox ID가 일치하면 기존 컨테이너를 재사용하며, 검사된 HostConfig 강화 값이 다르면 경고합니다. 변경된 강화 옵션을 적용하려면 Sandbox를 제거하고 다시 생성하세요. Docker는 검사된 값을 정규화할 수 있으며, 기존 컨테이너가 Docker의 기본 스왑 동작을 사용한 경우 재연결 시 memorySwap을 변경하면 경고가 발생할 수 있습니다.
  • Docker Desktop: 리소스 제한은 macOS 및 Windows의 Docker Desktop 가상 머신 내부에 적용되므로, VM에 할당된 리소스에 따라 컨테이너가 사용할 수 있는 리소스가 제한될 수 있습니다.

재연결
재연결에 대한 직접 링크

DockerSandbox는 레이블을 일치시켜 기존 컨테이너에 다시 연결할 수 있습니다. start()를 호출하면 Sandbox ID와 일치하는 mastra.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 호스트에 연결하거나 다음을 통해 사용자 정의 소켓 경로를 사용하십시오.dockerOptions:

// 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',
},
})