Docker (선택사항)

Docker는 선택사항입니다. 컨테이너화된 게이트웨이가 필요하거나 Docker 플로우를 검증하고 싶을 때만 사용하세요.

Docker가 적합한가요?

  • 적합: 격리된 일회용 게이트웨이 환경이 필요하거나, 로컬 설치 없이 호스트에서 OpenClaw를 실행하고 싶은 경우.
  • 부적합: 자신의 머신에서 가장 빠른 개발 루프를 원하는 경우. 일반 설치 방법을 사용하세요.
  • 샌드박싱 참고: 에이전트 샌드박싱도 Docker를 사용하지만, 게이트웨이 전체를 Docker에서 실행할 필요는 없습니다. 샌드박싱을 참고하세요.

이 가이드에서 다루는 내용:

  • 컨테이너화된 게이트웨이 (Docker 안에서 전체 OpenClaw 실행)
  • 세션별 에이전트 샌드박스 (호스트 게이트웨이 + Docker 격리 에이전트 도구)

샌드박싱 상세: 샌드박싱

요구사항

  • Docker Desktop(또는 Docker Engine) + Docker Compose v2
  • 이미지 빌드를 위해 최소 2 GB RAM (pnpm install은 1 GB 호스트에서 exit 137로 OOM 발생 가능)
  • 이미지 + 로그를 위한 충분한 디스크 공간
  • VPS/퍼블릭 호스트에서 실행하는 경우, 네트워크 노출을 위한 보안 강화, 특히 Docker DOCKER-USER 방화벽 정책을 확인하세요.

컨테이너화된 게이트웨이 (Docker Compose)

빠른 시작 (권장)

참고: 여기서 Docker 기본값은 바인드 모드(lan/loopback)를 사용하며, 호스트 별칭은 사용하지 않습니다. gateway.bind에는 바인드 모드 값(예: lan 또는 loopback)을 사용하세요. 0.0.0.0이나 localhost 같은 호스트 별칭은 사용하지 마세요.

저장소 루트에서:

./docker-setup.sh

이 스크립트가 하는 일:

  • 게이트웨이 이미지를 로컬에서 빌드합니다(OPENCLAW_IMAGE가 설정되면 원격 이미지를 풀링)
  • 온보딩 마법사를 실행합니다
  • 선택적 프로바이더 설정 힌트를 출력합니다
  • Docker Compose로 게이트웨이를 시작합니다
  • 게이트웨이 토큰을 생성하고 .env에 기록합니다

선택적 환경 변수:

  • OPENCLAW_IMAGE — 로컬 빌드 대신 원격 이미지 사용 (예: ghcr.io/openclaw/openclaw:latest)
  • OPENCLAW_DOCKER_APT_PACKAGES — 빌드 시 추가 apt 패키지 설치
  • OPENCLAW_EXTENSIONS — 빌드 시 확장 의존성 사전 설치 (공백으로 구분된 확장 이름, 예: diagnostics-otel matrix)
  • OPENCLAW_EXTRA_MOUNTS — 추가 호스트 바인드 마운트 추가
  • OPENCLAW_HOME_VOLUME — 네임드 볼륨으로 /home/node 유지
  • OPENCLAW_SANDBOX — Docker 게이트웨이 샌드박스 부트스트랩 옵트인. 명시적 참 값만 활성화: 1, true, yes, on
  • OPENCLAW_INSTALL_DOCKER_CLI — 로컬 이미지 빌드용 빌드 인자 전달(1이면 이미지에 Docker CLI 설치). docker-setup.sh는 로컬 빌드 시 OPENCLAW_SANDBOX=1이면 자동으로 설정합니다.
  • OPENCLAW_DOCKER_SOCKET — Docker 소켓 경로 재정의 (기본값: DOCKER_HOST=unix://... 경로, 없으면 /var/run/docker.sock)
  • OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 — 긴급 조치: CLI/온보딩 클라이언트 경로에서 신뢰된 사설 네트워크 ws:// 대상 허용 (기본값은 루프백 전용)
  • OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0 — WebGL/3D 호환이 필요할 때 컨테이너 브라우저 보안 강화 플래그 --disable-3d-apis, --disable-software-rasterizer, --disable-gpu 비활성화
  • OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0 — 브라우저 플로우에 확장 프로그램이 필요할 때 확장 프로그램 활성화 유지 (기본값은 샌드박스 브라우저에서 확장 비활성화)
  • OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=<N> — Chromium 렌더러 프로세스 제한 설정; 0으로 설정하면 플래그를 건너뛰고 Chromium 기본 동작 사용

완료 후:

  • 브라우저에서 http://127.0.0.1:18789/을 엽니다.
  • Control UI에 토큰을 붙여넣습니다(설정 → 토큰).
  • URL이 다시 필요하면 docker compose run --rm openclaw-cli dashboard --no-open을 실행하세요.

Docker 게이트웨이에서 에이전트 샌드박스 활성화 (옵트인)

docker-setup.sh는 Docker 배포를 위해 agents.defaults.sandbox.*도 부트스트랩할 수 있습니다.

활성화 방법:

export OPENCLAW_SANDBOX=1
./docker-setup.sh

커스텀 소켓 경로(예: 루트리스 Docker):

export OPENCLAW_SANDBOX=1
export OPENCLAW_DOCKER_SOCKET=/run/user/1000/docker.sock
./docker-setup.sh

참고:

  • 스크립트는 샌드박스 사전 조건을 통과한 후에만 docker.sock을 마운트합니다.
  • 샌드박스 설정을 완료할 수 없으면, 스크립트가 agents.defaults.sandbox.modeoff로 재설정하여 재실행 시 잘못된 샌드박스 설정을 방지합니다.
  • Dockerfile.sandbox가 없으면 경고를 출력하고 계속 진행합니다. 필요하면 scripts/sandbox-setup.shopenclaw-sandbox:bookworm-slim을 빌드하세요.
  • 외부 OPENCLAW_IMAGE 값을 사용하는 경우, 해당 이미지에 샌드박스 실행을 위한 Docker CLI가 이미 포함되어 있어야 합니다.

자동화/CI (비대화형, TTY 노이즈 없음)

스크립트와 CI에서는 Compose 의사 TTY 할당을 -T로 비활성화하세요:

docker compose run -T --rm openclaw-cli gateway probe
docker compose run -T --rm openclaw-cli devices list --json

자동화에서 Claude 세션 변수를 내보내지 않으면, docker-compose.yml에서 빈 값으로 해석되어 반복되는 “variable is not set” 경고가 발생하지 않습니다.

공유 네트워크 보안 참고 (CLI + 게이트웨이)

openclaw-clinetwork_mode: "service:openclaw-gateway"를 사용하므로 Docker 내에서 CLI 명령이 127.0.0.1로 안정적으로 게이트웨이에 접근할 수 있습니다.

이것은 공유 신뢰 경계로 간주하세요: 루프백 바인딩은 두 컨테이너 간의 격리가 아닙니다. 더 강한 분리가 필요하면 번들된 openclaw-cli 서비스 대신 별도의 컨테이너/호스트 네트워크 경로에서 명령을 실행하세요.

CLI 프로세스가 침해될 경우의 영향을 줄이기 위해, compose 설정에서 openclaw-cliNET_RAW/NET_ADMIN을 제거하고 no-new-privileges를 활성화합니다.

호스트에 설정/워크스페이스를 기록합니다:

  • ~/.openclaw/
  • ~/.openclaw/workspace

VPS에서 실행 중이라면 Hetzner (Docker VPS)를 참고하세요.

원격 이미지 사용 (로컬 빌드 건너뛰기)

공식 사전 빌드 이미지가 다음에서 제공됩니다:

이미지 이름은 ghcr.io/openclaw/openclaw을 사용하세요(Docker Hub의 유사한 이름의 이미지가 아닙니다).

일반적인 태그:

  • mainmain의 최신 빌드
  • <version> — 릴리스 태그 빌드 (예: 2026.2.26)
  • latest — 최신 stable 릴리스 태그

베이스 이미지 메타데이터

메인 Docker 이미지는 현재 다음을 사용합니다:

  • node:24-bookworm

Docker 이미지는 이제 OCI 베이스 이미지 어노테이션을 퍼블리시합니다(sha256은 예시이며, 해당 태그의 고정된 멀티 아키텍처 매니페스트 목록을 가리킵니다):

  • org.opencontainers.image.base.name=docker.io/library/node:24-bookworm
  • org.opencontainers.image.base.digest=sha256:3a09aa6354567619221ef6c45a5051b671f953f0a1924d1f819ffb236e520e6b
  • org.opencontainers.image.source=https://github.com/openclaw/openclaw
  • org.opencontainers.image.url=https://openclaw.ai
  • org.opencontainers.image.documentation=https://docs.openclaw.ai/install/docker
  • org.opencontainers.image.licenses=MIT
  • org.opencontainers.image.title=OpenClaw
  • org.opencontainers.image.description=OpenClaw gateway and CLI runtime container image
  • org.opencontainers.image.revision=<git-sha>
  • org.opencontainers.image.version=<tag-or-main>
  • org.opencontainers.image.created=<rfc3339 timestamp>

참고: OCI image annotations

릴리스 맥락: 이 저장소의 태그 이력은 v2026.2.22 및 이전 2026 태그(예: v2026.2.21, v2026.2.9)에서 이미 Bookworm을 사용합니다.

기본적으로 셋업 스크립트는 소스에서 이미지를 빌드합니다. 사전 빌드된 이미지를 대신 풀링하려면 스크립트 실행 전에 OPENCLAW_IMAGE를 설정하세요:

export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
./docker-setup.sh

스크립트는 OPENCLAW_IMAGE가 기본값 openclaw:local이 아닌 것을 감지하면 docker build 대신 docker pull을 실행합니다. 나머지(온보딩, 게이트웨이 시작, 토큰 생성)는 동일하게 작동합니다.

docker-setup.sh는 로컬 docker-compose.yml과 헬퍼 파일을 사용하므로 여전히 저장소 루트에서 실행됩니다. OPENCLAW_IMAGE는 로컬 이미지 빌드 시간만 건너뛸 뿐, compose/설정 워크플로우를 대체하지 않습니다.

Shell 헬퍼 (선택사항)

일상적인 Docker 관리를 쉽게 하려면 ClawDock을 설치하세요:

mkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/shell-helpers/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh

쉘 설정에 추가 (zsh):

echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc

이후 clawdock-start, clawdock-stop, clawdock-dashboard 등을 사용할 수 있습니다. 모든 명령어는 clawdock-help로 확인하세요.

자세한 내용은 ClawDock 헬퍼 README를 참고하세요.

수동 플로우 (compose)

docker build -t openclaw:local -f Dockerfile .
docker compose run --rm openclaw-cli onboard
docker compose up -d openclaw-gateway

참고: docker compose ...는 저장소 루트에서 실행하세요. OPENCLAW_EXTRA_MOUNTSOPENCLAW_HOME_VOLUME을 활성화한 경우, 셋업 스크립트가 docker-compose.extra.yml을 생성합니다. 다른 곳에서 Compose를 실행할 때 포함하세요:

docker compose -f docker-compose.yml -f docker-compose.extra.yml <command>

Control UI 토큰 + 페어링 (Docker)

“unauthorized” 또는 “disconnected (1008): pairing required”가 표시되면, 새 대시보드 링크를 가져와 브라우저 기기를 승인하세요:

docker compose run --rm openclaw-cli dashboard --no-open
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>

자세한 내용: 대시보드, 기기.

추가 마운트 (선택사항)

추가 호스트 디렉토리를 컨테이너에 마운트하려면 docker-setup.sh 실행 전에 OPENCLAW_EXTRA_MOUNTS를 설정하세요. 쉼표로 구분된 Docker 바인드 마운트 목록을 받아 docker-compose.extra.yml을 생성하여 openclaw-gatewayopenclaw-cli 모두에 적용합니다.

예시:

export OPENCLAW_EXTRA_MOUNTS="$HOME/.codex:/home/node/.codex:ro,$HOME/github:/home/node/github:rw"
./docker-setup.sh

참고:

  • 경로는 macOS/Windows에서 Docker Desktop과 공유되어야 합니다.
  • 각 항목은 공백, 탭, 줄바꿈 없이 source:target[:options] 형식이어야 합니다.
  • OPENCLAW_EXTRA_MOUNTS를 수정하면 docker-setup.sh를 다시 실행하여 extra compose 파일을 재생성하세요.
  • docker-compose.extra.yml은 자동 생성됩니다. 수동으로 편집하지 마세요.

컨테이너 홈 전체 유지 (선택사항)

컨테이너 재생성 후에도 /home/node를 유지하려면 OPENCLAW_HOME_VOLUME으로 네임드 볼륨을 설정하세요. Docker 볼륨을 생성하고 /home/node에 마운트하면서 표준 설정/워크스페이스 바인드 마운트는 유지합니다. 여기에는 네임드 볼륨을 사용하세요(바인드 경로가 아님). 바인드 마운트는 OPENCLAW_EXTRA_MOUNTS를 사용하세요.

예시:

export OPENCLAW_HOME_VOLUME="openclaw_home"
./docker-setup.sh

추가 마운트와 함께 사용할 수 있습니다:

export OPENCLAW_HOME_VOLUME="openclaw_home"
export OPENCLAW_EXTRA_MOUNTS="$HOME/.codex:/home/node/.codex:ro,$HOME/github:/home/node/github:rw"
./docker-setup.sh

참고:

  • 네임드 볼륨은 ^[A-Za-z0-9][A-Za-z0-9_.-]*$와 일치해야 합니다.
  • OPENCLAW_HOME_VOLUME을 변경하면 docker-setup.sh를 다시 실행하여 extra compose 파일을 재생성하세요.
  • 네임드 볼륨은 docker volume rm <name>으로 삭제할 때까지 유지됩니다.

추가 apt 패키지 설치 (선택사항)

이미지 내에 시스템 패키지가 필요한 경우(예: 빌드 도구나 미디어 라이브러리), docker-setup.sh 실행 전에 OPENCLAW_DOCKER_APT_PACKAGES를 설정하세요. 이미지 빌드 시 패키지를 설치하므로 컨테이너가 삭제되어도 유지됩니다.

예시:

export OPENCLAW_DOCKER_APT_PACKAGES="ffmpeg build-essential"
./docker-setup.sh

참고:

  • 공백으로 구분된 apt 패키지 이름 목록을 받습니다.
  • OPENCLAW_DOCKER_APT_PACKAGES를 변경하면 docker-setup.sh를 다시 실행하여 이미지를 다시 빌드하세요.

확장 의존성 사전 설치 (선택사항)

자체 package.json을 가진 확장 프로그램(예: diagnostics-otel, matrix, msteams)은 첫 로드 시 npm 의존성을 설치합니다. 이러한 의존성을 이미지에 미리 포함하려면 docker-setup.sh 실행 전에 OPENCLAW_EXTENSIONS를 설정하세요:

export OPENCLAW_EXTENSIONS="diagnostics-otel matrix"
./docker-setup.sh

직접 빌드할 때:

docker build --build-arg OPENCLAW_EXTENSIONS="diagnostics-otel matrix" .

참고:

  • 공백으로 구분된 확장 디렉토리 이름 목록을 받습니다(extensions/ 하위).
  • package.json이 있는 확장만 영향을 받습니다. package.json이 없는 경량 플러그인은 무시됩니다.
  • OPENCLAW_EXTENSIONS를 변경하면 docker-setup.sh를 다시 실행하여 이미지를 다시 빌드하세요.

파워 유저 / 풀 기능 컨테이너 (옵트인)

기본 Docker 이미지는 보안 우선이며 비루트 node 사용자로 실행됩니다. 공격 표면은 작지만, 다음과 같은 제한이 있습니다:

  • 런타임에 시스템 패키지 설치 불가
  • 기본적으로 Homebrew 없음
  • 번들된 Chromium/Playwright 브라우저 없음

더 풍부한 기능의 컨테이너가 필요하다면 다음 옵트인 옵션을 사용하세요:

  1. /home/node 유지로 브라우저 다운로드와 도구 캐시 보존:
export OPENCLAW_HOME_VOLUME="openclaw_home"
./docker-setup.sh
  1. 시스템 의존성을 이미지에 포함 (반복 가능 + 영구적):
export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq"
./docker-setup.sh
  1. npx 없이 Playwright 브라우저 설치 (npm 재정의 충돌 방지):
docker compose run --rm openclaw-cli \
  node /app/node_modules/playwright-core/cli.js install chromium

Playwright가 시스템 의존성을 설치해야 하는 경우, 런타임에 --with-deps를 사용하는 대신 OPENCLAW_DOCKER_APT_PACKAGES로 이미지를 다시 빌드하세요.

  1. Playwright 브라우저 다운로드 유지:
  • docker-compose.yml에서 PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwright를 설정하세요.
  • OPENCLAW_HOME_VOLUME으로 /home/node를 유지하거나, OPENCLAW_EXTRA_MOUNTS/home/node/.cache/ms-playwright를 마운트하세요.

권한 + EACCES

이미지는 node (uid 1000)로 실행됩니다. /home/node/.openclaw에서 권한 오류가 발생하면 호스트 바인드 마운트의 소유자가 uid 1000인지 확인하세요.

예시 (Linux 호스트):

sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace

편의를 위해 root로 실행하기로 선택했다면, 보안상의 트레이드오프를 감수하는 것입니다.

빠른 리빌드 (권장)

리빌드를 가속하려면 Dockerfile에서 의존성 레이어가 캐시되도록 순서를 정하세요. 락파일이 변경되지 않으면 pnpm install 재실행을 방지합니다:

FROM node:24-bookworm

# Install Bun (required for build scripts)
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"

RUN corepack enable

WORKDIR /app

# Cache dependencies unless package metadata changes
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY ui/package.json ./ui/package.json
COPY scripts ./scripts

RUN pnpm install --frozen-lockfile

COPY . .
RUN pnpm build
RUN pnpm ui:install
RUN pnpm ui:build

ENV NODE_ENV=production

CMD ["node","dist/index.js"]

채널 설정 (선택사항)

CLI 컨테이너로 채널을 설정한 뒤, 필요하면 게이트웨이를 재시작하세요.

WhatsApp (QR):

docker compose run --rm openclaw-cli channels login

Telegram (봇 토큰):

docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>"

Discord (봇 토큰):

docker compose run --rm openclaw-cli channels add --channel discord --token "<token>"

문서: WhatsApp, Telegram, Discord

OpenAI Codex OAuth (헤드리스 Docker)

마법사에서 OpenAI Codex OAuth를 선택하면 브라우저 URL을 열고 http://127.0.0.1:1455/auth/callback에서 콜백을 캡처하려 합니다. Docker나 헤드리스 환경에서는 해당 콜백이 브라우저 오류를 표시할 수 있습니다. 도착한 전체 리다이렉트 URL을 복사해서 마법사에 붙여넣으면 인증이 완료됩니다.

헬스 체크

컨테이너 프로브 엔드포인트 (인증 불필요):

curl -fsS http://127.0.0.1:18789/healthz
curl -fsS http://127.0.0.1:18789/readyz

별칭: /health/ready.

/healthz는 “게이트웨이 프로세스가 살아있는지”를 확인하는 얕은 활성 프로브입니다. /readyz는 시작 유예 기간 동안 준비 상태를 유지하다가, 유예 기간 후에도 필요한 관리 채널이 연결되지 않았거나 이후 연결이 끊어지면 503을 반환합니다.

Docker 이미지에는 백그라운드에서 /healthz를 핑하는 내장 HEALTHCHECK가 포함되어 있습니다. 간단히 말해: Docker가 OpenClaw가 여전히 응답하는지 지속적으로 확인합니다. 체크가 계속 실패하면 Docker가 컨테이너를 unhealthy로 표시하고, 오케스트레이션 시스템(Docker Compose 재시작 정책, Swarm, Kubernetes 등)이 자동으로 재시작하거나 교체할 수 있습니다.

인증된 심층 헬스 스냅샷 (게이트웨이 + 채널):

docker compose exec openclaw-gateway node dist/index.js health --token "$OPENCLAW_GATEWAY_TOKEN"

E2E 스모크 테스트 (Docker)

scripts/e2e/onboard-docker.sh

QR 가져오기 스모크 테스트 (Docker)

pnpm test:docker:qr

LAN vs 루프백 (Docker Compose)

docker-setup.shOPENCLAW_GATEWAY_BIND=lan을 기본값으로 설정하여 Docker 포트 퍼블리싱으로 호스트에서 http://127.0.0.1:18789에 접근할 수 있습니다.

  • lan (기본값): 호스트 브라우저 + 호스트 CLI가 퍼블리시된 게이트웨이 포트에 접근 가능.
  • loopback: 컨테이너 네트워크 네임스페이스 내부의 프로세스만 게이트웨이에 직접 접근 가능. 호스트 퍼블리시 포트 접근이 실패할 수 있습니다.

셋업 스크립트는 온보딩 후 gateway.mode=local도 고정하여 Docker CLI 명령어가 기본적으로 로컬 루프백을 대상으로 합니다.

레거시 설정 참고: gateway.bind에는 바인드 모드 값(lan / loopback / custom / tailnet / auto)을 사용하세요. 호스트 별칭(0.0.0.0, 127.0.0.1, localhost, ::, ::1)은 사용하지 마세요.

Docker CLI 명령에서 Gateway target: ws://172.x.x.x:18789 또는 반복되는 pairing required 오류가 나타나면:

docker compose run --rm openclaw-cli config set gateway.mode local
docker compose run --rm openclaw-cli config set gateway.bind lan
docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789

참고사항

  • 게이트웨이 바인드는 컨테이너 사용을 위해 기본적으로 lan입니다(OPENCLAW_GATEWAY_BIND).
  • Dockerfile CMD는 --allow-unconfigured를 사용합니다. gateway.modelocal이 아닌 마운트된 설정도 시작됩니다. 가드를 강제하려면 CMD를 재정의하세요.
  • 게이트웨이 컨테이너가 세션의 정본입니다(~/.openclaw/agents/<agentId>/sessions/).

스토리지 모델

  • 영구 호스트 데이터: Docker Compose가 OPENCLAW_CONFIG_DIR/home/node/.openclaw에, OPENCLAW_WORKSPACE_DIR/home/node/.openclaw/workspace에 바인드 마운트하므로 컨테이너 교체 후에도 유지됩니다.
  • 임시 샌드박스 tmpfs: agents.defaults.sandbox가 활성화되면 샌드박스 컨테이너는 /tmp, /var/tmp, /runtmpfs를 사용합니다. 이 마운트는 최상위 Compose 스택과 별도이며 샌드박스 컨테이너와 함께 사라집니다.
  • 디스크 증가 핫스팟: media/, agents/<agentId>/sessions/sessions.json, 트랜스크립트 JSONL 파일, cron/runs/*.jsonl, /tmp/openclaw/(또는 설정된 logging.file) 아래의 롤링 파일 로그를 주시하세요. Docker 외부에서 macOS 앱도 실행하는 경우 서비스 로그가 별도입니다: ~/.openclaw/logs/gateway.log, ~/.openclaw/logs/gateway.err.log, /tmp/openclaw/openclaw-gateway.log.

에이전트 샌드박스 (호스트 게이트웨이 + Docker 도구)

심층 분석: 샌드박싱

동작 방식

agents.defaults.sandbox가 활성화되면 비메인 세션이 Docker 컨테이너 내에서 도구를 실행합니다. 게이트웨이는 호스트에 남지만 도구 실행은 격리됩니다:

  • scope: 기본값 "agent" (에이전트당 컨테이너 1개 + 워크스페이스 1개)
  • scope: "session" — 세션별 격리
  • 스코프별 워크스페이스 폴더가 /workspace에 마운트됨
  • 선택적 에이전트 워크스페이스 접근 (agents.defaults.sandbox.workspaceAccess)
  • 허용/거부 도구 정책 (거부가 우선)
  • 인바운드 미디어가 활성 샌드박스 워크스페이스에 복사됨 (media/inbound/*) — 도구가 읽을 수 있음 (workspaceAccess: "rw"일 때 에이전트 워크스페이스에 저장됨)

경고: scope: "shared"는 세션 간 격리를 비활성화합니다. 모든 세션이 하나의 컨테이너와 하나의 워크스페이스를 공유합니다.

에이전트별 샌드박스 프로필 (멀티 에이전트)

멀티 에이전트 라우팅을 사용하는 경우 각 에이전트가 샌드박스 + 도구 설정을 재정의할 수 있습니다: agents.list[].sandboxagents.list[].tools (+ agents.list[].tools.sandbox.tools). 하나의 게이트웨이에서 다양한 접근 수준을 실행할 수 있습니다:

  • 전체 접근 (개인 에이전트)
  • 읽기 전용 도구 + 읽기 전용 워크스페이스 (가족/업무 에이전트)
  • 파일시스템/쉘 도구 없음 (공개 에이전트)

예시, 우선순위, 문제 해결은 멀티 에이전트 샌드박스 및 도구를 참고하세요.

기본 동작

  • 이미지: openclaw-sandbox:bookworm-slim
  • 에이전트당 컨테이너 1개
  • 에이전트 워크스페이스 접근: workspaceAccess: "none" (기본값)은 ~/.openclaw/sandboxes 사용
    • "ro"는 샌드박스 워크스페이스를 /workspace에 유지하고 에이전트 워크스페이스를 읽기 전용으로 /agent에 마운트 (write/edit/apply_patch 비활성화)
    • "rw"는 에이전트 워크스페이스를 읽기/쓰기로 /workspace에 마운트
  • 자동 정리: 유휴 > 24시간 또는 수명 > 7일
  • 네트워크: 기본값 none (이그레스가 필요하면 명시적으로 옵트인)
    • host는 차단됨.
    • container:<id>는 기본적으로 차단됨 (네임스페이스 합류 위험).
  • 기본 허용: exec, process, read, write, edit, sessions_list, sessions_history, sessions_send, sessions_spawn, session_status
  • 기본 거부: browser, canvas, nodes, cron, discord, gateway

샌드박싱 활성화

setupCommand에서 패키지를 설치할 계획이라면:

  • 기본 docker.network"none" (이그레스 없음).
  • docker.network: "host"는 차단됨.
  • docker.network: "container:<id>"는 기본적으로 차단됨.
  • 긴급 조치 재정의: agents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true.
  • readOnlyRoot: true는 패키지 설치를 차단합니다.
  • apt-get에는 root 사용자가 필요합니다(user를 생략하거나 user: "0:0" 설정). OpenClaw는 setupCommand(또는 docker 설정)가 변경되면 컨테이너를 자동 재생성합니다. 단, 컨테이너가 최근 사용된 경우(약 5분 이내)에는 예외입니다. 활성 컨테이너는 정확한 openclaw sandbox recreate ... 명령어와 함께 경고를 로그합니다.
{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main", // off | non-main | all
        scope: "agent", // session | agent | shared (agent is default)
        workspaceAccess: "none", // none | ro | rw
        workspaceRoot: "~/.openclaw/sandboxes",
        docker: {
          image: "openclaw-sandbox:bookworm-slim",
          workdir: "/workspace",
          readOnlyRoot: true,
          tmpfs: ["/tmp", "/var/tmp", "/run"],
          network: "none",
          user: "1000:1000",
          capDrop: ["ALL"],
          env: { LANG: "C.UTF-8" },
          setupCommand: "apt-get update && apt-get install -y git curl jq",
          pidsLimit: 256,
          memory: "1g",
          memorySwap: "2g",
          cpus: 1,
          ulimits: {
            nofile: { soft: 1024, hard: 2048 },
            nproc: 256,
          },
          seccompProfile: "/path/to/seccomp.json",
          apparmorProfile: "openclaw-sandbox",
          dns: ["1.1.1.1", "8.8.8.8"],
          extraHosts: ["internal.service:10.0.0.5"],
        },
        prune: {
          idleHours: 24, // 0 disables idle pruning
          maxAgeDays: 7, // 0 disables max-age pruning
        },
      },
    },
  },
  tools: {
    sandbox: {
      tools: {
        allow: [
          "exec",
          "process",
          "read",
          "write",
          "edit",
          "sessions_list",
          "sessions_history",
          "sessions_send",
          "sessions_spawn",
          "session_status",
        ],
        deny: ["browser", "canvas", "nodes", "cron", "discord", "gateway"],
      },
    },
  },
}

보안 강화 옵션은 agents.defaults.sandbox.docker 아래에 있습니다: network, user, pidsLimit, memory, memorySwap, cpus, ulimits, seccompProfile, apparmorProfile, dns, extraHosts, dangerouslyAllowContainerNamespaceJoin (긴급 조치 전용).

멀티 에이전트: agents.defaults.sandbox.{docker,browser,prune}.*를 에이전트별로 agents.list[].sandbox.{docker,browser,prune}.*로 재정의 가능 (agents.defaults.sandbox.scope / agents.list[].sandbox.scope"shared"이면 무시됨).

기본 샌드박스 이미지 빌드

scripts/sandbox-setup.sh

Dockerfile.sandbox를 사용하여 openclaw-sandbox:bookworm-slim을 빌드합니다.

샌드박스 공통 이미지 (선택사항)

일반적인 빌드 도구(Node, Go, Rust 등)가 포함된 샌드박스 이미지가 필요하면 공통 이미지를 빌드하세요:

scripts/sandbox-common-setup.sh

openclaw-sandbox-common:bookworm-slim을 빌드합니다. 사용하려면:

{
  agents: {
    defaults: {
      sandbox: { docker: { image: "openclaw-sandbox-common:bookworm-slim" } },
    },
  },
}

샌드박스 브라우저 이미지

샌드박스 내에서 브라우저 도구를 실행하려면 브라우저 이미지를 빌드하세요:

scripts/sandbox-browser-setup.sh

Dockerfile.sandbox-browser를 사용하여 openclaw-sandbox-browser:bookworm-slim을 빌드합니다. 컨테이너는 CDP가 활성화된 Chromium과 선택적 noVNC 관찰자(Xvfb를 통한 헤드풀)로 실행됩니다.

참고:

  • 헤드풀(Xvfb)은 헤드리스보다 봇 차단을 줄입니다.
  • agents.defaults.sandbox.browser.headless=true를 설정하면 여전히 헤드리스를 사용할 수 있습니다.
  • 완전한 데스크톱 환경(GNOME)은 필요 없습니다. Xvfb가 디스플레이를 제공합니다.
  • 브라우저 컨테이너는 글로벌 bridge 대신 전용 Docker 네트워크(openclaw-sandbox-browser)를 기본으로 사용합니다.
  • 선택적 agents.defaults.sandbox.browser.cdpSourceRange로 CIDR별 컨테이너 에지 CDP 인그레스를 제한할 수 있습니다(예: 172.21.0.1/32).
  • noVNC 관찰자 접근은 기본적으로 비밀번호로 보호됩니다. OpenClaw는 로컬 부트스트랩 페이지를 제공하고 비밀번호를 URL 프래그먼트에 유지하는(URL 쿼리가 아닌) 단기 관찰자 토큰 URL을 제공합니다.
  • 브라우저 컨테이너 시작 기본값은 공유/컨테이너 워크로드를 위해 보수적으로 설정되어 있습니다:
    • --remote-debugging-address=127.0.0.1
    • --remote-debugging-port=<derived from OPENCLAW_BROWSER_CDP_PORT>
    • --user-data-dir=${HOME}/.chrome
    • --no-first-run
    • --no-default-browser-check
    • --disable-3d-apis
    • --disable-software-rasterizer
    • --disable-gpu
    • --disable-dev-shm-usage
    • --disable-background-networking
    • --disable-features=TranslateUI
    • --disable-breakpad
    • --disable-crash-reporter
    • --metrics-recording-only
    • --renderer-process-limit=2
    • --no-zygote
    • --disable-extensions
    • agents.defaults.sandbox.browser.noSandbox가 설정되면 --no-sandbox--disable-setuid-sandbox도 추가됩니다.
    • 위의 세 가지 그래픽 보안 강화 플래그는 선택사항입니다. 워크로드에 WebGL/3D가 필요하면 OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0을 설정하여 --disable-3d-apis, --disable-software-rasterizer, --disable-gpu 없이 실행하세요.
    • 확장 동작은 --disable-extensions로 제어되며 OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0으로 비활성화(확장 활성화)할 수 있습니다. 확장 의존 페이지나 확장이 많은 워크플로우에 사용하세요.
    • --renderer-process-limit=2OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT으로 설정 가능합니다. 0으로 설정하면 브라우저 동시성 튜닝이 필요할 때 Chromium이 기본 프로세스 제한을 선택하게 합니다.

기본값은 번들된 이미지에 적용됩니다. 다른 Chromium 플래그가 필요하면 커스텀 브라우저 이미지를 사용하고 자체 엔트리포인트를 제공하세요.

설정 사용:

{
  agents: {
    defaults: {
      sandbox: {
        browser: { enabled: true },
      },
    },
  },
}

커스텀 브라우저 이미지:

{
  agents: {
    defaults: {
      sandbox: { browser: { image: "my-openclaw-browser" } },
    },
  },
}

활성화되면 에이전트가 다음을 수신합니다:

  • 샌드박스 브라우저 제어 URL (browser 도구용)
  • noVNC URL (활성화되고 headless=false일 때)

도구에 허용 목록을 사용한다면 browser를 추가하고(거부에서 제거) 그렇지 않으면 도구가 차단된 상태로 유지됩니다. 정리 규칙(agents.defaults.sandbox.prune)은 브라우저 컨테이너에도 적용됩니다.

커스텀 샌드박스 이미지

자체 이미지를 빌드하고 설정에서 지정하세요:

docker build -t my-openclaw-sbx -f Dockerfile.sandbox .
{
  agents: {
    defaults: {
      sandbox: { docker: { image: "my-openclaw-sbx" } },
    },
  },
}

도구 정책 (허용/거부)

  • denyallow보다 우선합니다.
  • allow가 비어 있으면: deny를 제외한 모든 도구가 사용 가능합니다.
  • allow가 비어 있지 않으면: allow에 있는 도구만 사용 가능합니다(deny 차감).

정리 전략

두 가지 설정:

  • prune.idleHours: X시간 동안 사용하지 않은 컨테이너 제거 (0 = 비활성화)
  • prune.maxAgeDays: X일보다 오래된 컨테이너 제거 (0 = 비활성화)

예시:

  • 활발한 세션은 유지하되 수명 제한: idleHours: 24, maxAgeDays: 7
  • 정리하지 않음: idleHours: 0, maxAgeDays: 0

보안 참고

  • 하드 월은 도구(exec/read/write/edit/apply_patch)에만 적용됩니다.
  • browser/camera/canvas 같은 호스트 전용 도구는 기본적으로 차단됩니다.
  • 샌드박스에서 browser를 허용하면 격리가 깨집니다 (브라우저가 호스트에서 실행됨).

문제 해결

  • 이미지 누락: scripts/sandbox-setup.sh로 빌드하거나 agents.defaults.sandbox.docker.image를 설정하세요.
  • 컨테이너 미실행: 세션 요청 시 자동으로 생성됩니다.
  • 샌드박스의 권한 오류: docker.user를 마운트된 워크스페이스 소유권과 일치하는 UID:GID로 설정하세요(또는 워크스페이스 폴더의 소유자를 변경하세요).
  • 커스텀 도구를 찾을 수 없음: OpenClaw는 sh -lc(로그인 쉘)로 명령을 실행하며, /etc/profile을 소스하여 PATH를 재설정할 수 있습니다. docker.env.PATH로 커스텀 도구 경로를 앞에 추가하거나(예: /custom/bin:/usr/local/share/npm-global/bin), Dockerfile에서 /etc/profile.d/ 아래에 스크립트를 추가하세요.