Docker (선택 사항)

Docker는 선택 사항입니다. 컨테이너화된 Gateway를 원하거나 Docker 플로우를 검증하려는 경우에만 사용하세요.

Docker가 나에게 적합한가요?

  • : 격리된 일회용 Gateway 환경을 원하거나 로컬 설치 없이 호스트에서 OpenClaw를 실행하려는 경우.
  • 아니오: 자신의 머신에서 실행하고 가장 빠른 개발 루프를 원하는 경우. 대신 일반 설치 플로우를 사용하세요.
  • Sandboxing 참고: agent sandboxing도 Docker를 사용하지만 전체 Gateway를 Docker에서 실행할 필요는 없습니다. Sandboxing을 참조하세요.

이 가이드는 다음을 다룹니다:

  • 컨테이너화된 Gateway (Docker의 전체 OpenClaw)
  • 세션별 Agent Sandbox (호스트 Gateway + Docker 격리 agent 도구)

Sandboxing 세부사항: Sandboxing

요구 사항

  • Docker Desktop (또는 Docker Engine) + Docker Compose v2
  • 이미지 + 로그를 위한 충분한 디스크

컨테이너화된 Gateway (Docker Compose)

빠른 시작 (권장)

저장소 루트에서:

./docker-setup.sh

이 스크립트는:

  • Gateway 이미지 빌드
  • 온보딩 마법사 실행
  • 선택적 provider 설정 힌트 출력
  • Docker Compose를 통해 Gateway 시작
  • Gateway 토큰 생성 및 .env에 작성

선택적 환경 변수:

  • OPENCLAW_DOCKER_APT_PACKAGES — 빌드 중 추가 apt 패키지 설치
  • OPENCLAW_EXTRA_MOUNTS — 추가 호스트 바인드 마운트 추가
  • OPENCLAW_HOME_VOLUME — 명명된 볼륨에 /home/node 유지

완료 후:

  • 브라우저에서 http://127.0.0.1:18789/를 엽니다.
  • Control UI에 토큰을 붙여넣습니다(Settings → token).

호스트에 config/workspace를 작성합니다:

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

VPS에서 실행하시나요? Hetzner (Docker VPS)를 참조하세요.

수동 플로우 (compose)

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

추가 마운트 (선택 사항)

컨테이너에 추가 호스트 디렉토리를 마운트하려면 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과 공유되어야 합니다.
  • OPENCLAW_EXTRA_MOUNTS를 편집한 경우 docker-setup.sh를 다시 실행하여 추가 compose 파일을 재생성하세요.
  • docker-compose.extra.yml은 생성됩니다. 수동으로 편집하지 마세요.

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

컨테이너 재생성 시 /home/node를 유지하려면 OPENCLAW_HOME_VOLUME을 통해 명명된 볼륨을 설정하세요. 이것은 Docker 볼륨을 생성하고 /home/node에 마운트하면서 표준 config/workspace 바인드 마운트를 유지합니다. 여기서는 명명된 볼륨을 사용하세요 (바인드 경로가 아님); 바인드 마운트의 경우 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

참고:

  • OPENCLAW_HOME_VOLUME을 변경한 경우 docker-setup.sh를 다시 실행하여 추가 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를 다시 실행하여 이미지를 다시 빌드하세요.

더 빠른 재빌드 (권장)

재빌드 속도를 높이려면 의존성 레이어가 캐시되도록 Dockerfile을 정렬하세요. 이렇게 하면 lockfile이 변경되지 않는 한 pnpm install 재실행을 방지합니다:

FROM node:22-bookworm

# Bun 설치 (빌드 스크립트에 필요)
RUN curl -fsSL https://bun.sh/install | bash
ENV PATH="/root/.bun/bin:${PATH}"

RUN corepack enable

WORKDIR /app

# 패키지 메타데이터가 변경되지 않는 한 의존성 캐시
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"]

Channel 설정 (선택 사항)

CLI 컨테이너를 사용하여 채널을 구성한 다음 필요한 경우 Gateway를 재시작하세요.

WhatsApp (QR):

docker compose run --rm openclaw-cli channels login

Telegram (bot token):

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

Discord (bot token):

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

문서: WhatsApp, Telegram, Discord

Health check

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

E2E smoke test (Docker)

scripts/e2e/onboard-docker.sh

QR import smoke test (Docker)

pnpm test:docker:qr

참고사항

  • Gateway 바인드는 컨테이너 사용을 위해 기본적으로 lan입니다.
  • Gateway 컨테이너는 세션(~/.openclaw/agents/<agentId>/sessions/)의 신뢰할 수 있는 소스입니다.

Agent Sandbox (호스트 Gateway + Docker 도구)

심층 분석: Sandboxing

기능

agents.defaults.sandbox가 활성화되면 non-main 세션은 Docker 컨테이너 내부에서 도구를 실행합니다. Gateway는 호스트에 유지되지만 도구 실행은 격리됩니다:

  • scope: 기본적으로 "agent" (agent당 하나의 컨테이너 + workspace)
  • scope: 세션별 격리를 위한 "session"
  • scope별 workspace 폴더가 /workspace에 마운트됨
  • 선택적 agent workspace 액세스 (agents.defaults.sandbox.workspaceAccess)
  • 도구 정책 허용/거부 (거부가 우선)
  • 인바운드 미디어는 활성 sandbox workspace(media/inbound/*)에 복사되어 도구가 읽을 수 있습니다(workspaceAccess: "rw"의 경우 agent workspace에 저장됨)

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

Agent별 sandbox 프로필 (multi-agent)

multi-agent 라우팅을 사용하는 경우 각 agent는 sandbox + 도구 설정을 재정의할 수 있습니다: agents.list[].sandboxagents.list[].tools (plus agents.list[].tools.sandbox.tools). 이를 통해 하나의 Gateway에서 혼합 액세스 수준을 실행할 수 있습니다:

  • 전체 액세스 (개인 agent)
  • 읽기 전용 도구 + 읽기 전용 workspace (가족/업무 agent)
  • 파일 시스템/셸 도구 없음 (공개 agent)

예제, 우선순위 및 문제 해결은 Multi-Agent Sandbox & Tools를 참조하세요.

기본 동작

  • 이미지: openclaw-sandbox:bookworm-slim
  • agent당 하나의 컨테이너
  • Agent workspace 액세스: workspaceAccess: "none" (기본값)은 ~/.openclaw/sandboxes 사용
    • "ro"는 sandbox workspace를 /workspace에 유지하고 agent workspace를 /agent에 읽기 전용으로 마운트 (write/edit/apply_patch 비활성화)
    • "rw"는 agent workspace를 /workspace에 읽기/쓰기로 마운트
  • 자동 정리: 유휴 > 24h 또는 나이 > 7일
  • 네트워크: 기본적으로 none (필요한 경우 egress 명시적으로 선택)
  • 기본 허용: exec, process, read, write, edit, sessions_list, sessions_history, sessions_send, sessions_spawn, session_status
  • 기본 거부: browser, canvas, nodes, cron, discord, gateway

Sandboxing 활성화

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

  • 기본 docker.network"none" (egress 없음)입니다.
  • readOnlyRoot: true는 패키지 설치를 차단합니다.
  • userapt-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가 기본값)
        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은 유휴 정리를 비활성화
          maxAgeDays: 7  // 0은 최대 나이 정리를 비활성화
        }
      }
    }
  },
  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.

Multi-agent: agents.list[].sandbox.{docker,browser,prune}.*를 통해 agent당 agents.defaults.sandbox.{docker,browser,prune}.* 재정의 (agents.defaults.sandbox.scope / agents.list[].sandbox.scope"shared"일 때 무시됨).

기본 sandbox 이미지 빌드

scripts/sandbox-setup.sh

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

Sandbox 공통 이미지 (선택 사항)

공통 빌드 도구(Node, Go, Rust 등)가 포함된 sandbox 이미지를 원하면 공통 이미지를 빌드하세요:

scripts/sandbox-common-setup.sh

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

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

Sandbox 브라우저 이미지

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

scripts/sandbox-browser-setup.sh

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

참고:

  • Headful (Xvfb)은 headless 대비 봇 차단을 줄입니다.
  • agents.defaults.sandbox.browser.headless=true를 설정하여 headless를 계속 사용할 수 있습니다.
  • 전체 데스크톱 환경(GNOME)은 필요하지 않습니다; Xvfb가 디스플레이를 제공합니다.

구성 사용:

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

사용자 정의 브라우저 이미지:

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

활성화되면 agent는 다음을 받습니다:

  • sandbox 브라우저 제어 URL (browser 도구용)
  • noVNC URL (활성화되고 headless=false인 경우)

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

사용자 정의 sandbox 이미지

자체 이미지를 빌드하고 구성에서 가리키세요:

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

도구 정책 (허용/거부)

  • denyallow보다 우선합니다.
  • allow가 비어 있으면: 모든 도구(거부 제외)를 사용할 수 있습니다.
  • allow가 비어 있지 않으면: allow의 도구만 사용할 수 있습니다(거부 제외).

정리 전략

두 가지 노브:

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

예:

  • 바쁜 세션을 유지하되 수명 제한: idleHours: 24, maxAgeDays: 7
  • 절대 정리하지 않음: idleHours: 0, maxAgeDays: 0

보안 참고사항

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

문제 해결

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