에이전트 워크로드 빌드하기

에이전트 워크로드 빌드하기 (Build an agent workload)

직접 고른 Linux 기본 이미지 위에서 Claude Code를 실행하는 키트를 만드는 방법을 알아볼게요.

출처: 문서

본문

원하는 Linux 기본 이미지 위에서 Claude Code를 실행하는 키트를 만들어 봅시다. 에이전트를 설치하고, Anthropic API에 접근할 수 있게 하고, 팀을 위한 모델 설정과 지침을 추가할 거예요. 결과물은 v3 워크로드 키트가 되어서 로컬에서 실행하거나 다른 사람이 쓸 수 있게 배포할 수 있어요. 다른 에이전트나 조직의 자체 기본 이미지에도 같은 절차를 적용할 수 있어요.

이 튜토리얼은 시스템 패키지부터 에이전트를 시작하는 명령까지 환경 전체를 준비해요. 이미 적절한 에이전트 이미지가 있다면, 기존 에이전트 이미지 패키징 문서를 보세요. 배포된 에이전트 키트를 도구와 결합하려면, 키트 세트 작성 문서를 보세요.

키트가 처음이라면 Author kits 문서를 먼저 읽고 만들 파일들을 파악해 보세요. 필드 정의는 upstream v3 사양에 있어요.

참고 (Note): 이 기능은 Early Access 상태예요.

키트 디렉터리 준비하기

sbx, Docker with Buildx, 그리고 Anthropic API 키가 필요해요. 에이전트로 작업할 프로젝트 옆에 디렉터리를 만드세요:

$ mkdir claude-team

완성된 디렉터리에는 세 파일이 들어 있어요:

claude-team/
├── claude-team.yaml
├── claude-team.dockerfile
└── context.md

Dockerfile은 에이전트를 설치하고 실행 명령을 정해요. descriptor라고 부르는 YAML 파일은 Docker Sandboxes에 에이전트가 실행되기 위해 필요한 것(네트워크 접근, 자격 증명 등)을 알려줘요. Markdown 파일에는 에이전트를 위한 지침이 담겨 있어요. 빌드가 두 파일을 모두 찾을 수 있도록 YAML 파일과 Dockerfile에 확장자 앞부분을 같은 이름으로 지어 주세요.

이 키트는 v3를 사용하며, v2를 쓰는 내장 claude 키트와는 독립적이에요. 추가하는 모든 mixin도 v3를 써야 해요. 내장 키트를 커스터마이즈하려면 Kits v2 문서를 보세요.

직접 고른 기본 이미지 사용하기

이 튜토리얼은 Red Hat Universal Base Image (UBI) 9에서 시작해요. 다음 단계들은 샌드박스에 필요한 도구, 사용자 계정, 인증서를 추가해요. 조직이 관리하는 이미지를 포함해 다른 Linux 이미지를 써도 돼요. 그 이미지에 맞게 패키지와 계정 명령을 조정하고, 같은 기본 이미지 요구사항을 따라 주세요.

시스템 패키지 설치하기

기본 이미지와 패키지가 있는 claude-team/claude-team.dockerfile을 만드세요:

FROM registry.access.redhat.com/ubi9/ubi:9.8

USER root
RUN dnf install -y bash ca-certificates curl-minimal git shadow-utils tar gzip \
    && dnf clean all

Bash는 셸 명령을 실행하고, Git은 소스 저장소에 접근하며, curl은 CA 인증서로 HTTPS 요청을 만들어요. 나머지 패키지들은 에이전트의 사용자 계정을 만들고 설치 프로그램의 압축을 푸는 데 쓰여요. 프로젝트에 필요한 컴파일러, 라이브러리, 기타 도구가 있다면 여기에 추가하세요.

에이전트 계정 만들기

샌드박스에는 UID 1000과 홈 디렉터리 /home/agent를 가진 비-root agent 사용자가 필요해요. 그 계정과 에이전트의 워크스페이스·설정·상태를 위한 쓰기 가능 디렉터리를 만들려면 다음을 Dockerfile에 추가하세요:

RUN groupadd --gid 1000 agent \
    && useradd --uid 1000 --gid 1000 --create-home --shell /bin/bash agent \
    && mkdir -p /home/agent/workspace /home/agent/.local/bin \
    /home/agent/.local/share /home/agent/.local/state \
    /home/agent/.config/claude-team /home/agent/.docker/sandbox/locks \
    && chown -R agent:agent /home/agent

이 디렉터리들을 빌드 중에 만들어 두면, Docker Sandboxes가 워크스페이스와 스토리지를 마운트하기 전에 에이전트가 소유자가 되어요. 이 예시에서 에이전트는 sudo 없이 실행되므로 시스템 패키지는 Dockerfile에 설치하는 거예요. 개별 샌드박스에 의존하는 설정은 install hooks를 사용하세요.

인증서 신뢰 준비하기

샌드박스의 HTTPS 요청은 프록시를 거쳐요. Docker Sandboxes는 시작할 때 프록시의 인증 기관(CA)을 샌드박스의 신뢰하는 인증서에 추가해요. UBI는 sbx가 쓰는 경로와 다른 경로에 인증서를 보관해요. 인증서를 기대하는 경로로 복사한 뒤 도구가 그 파일을 쓰도록 하면 공용 인증서와 프록시를 모두 신뢰하게 돼요:

RUN update-ca-trust \
    && mkdir -p /usr/local/share/ca-certificates /etc/ssl/certs \
    && cp /etc/pki/tls/certs/ca-bundle.crt /etc/ssl/certs/ca-certificates.crt

ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt \
    CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
    REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt \
    NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt

빌드 중에 기업 CA 인증서를 추가한다면, update-ca-trust를 실행하고 번들을 복사하기 전에 /etc/pki/ca-trust/source/anchors/에 넣어 주세요. 다른 배포판을 쓴다면 그쪽의 인증서 관리 명령과 소스 번들 경로를 사용하세요.

셸 환경 준비하기

한 셸에서 export한 환경 변수는 다른 셸에서 자동으로 쓸 수 없어요. 에이전트가 나중 셸 세션을 위해 변수를 저장할 파일을 하나 만들어 주세요. 다음 줄들은 그 파일을 만들고, login·interactive·non-interactive Bash 셸이 모두 읽도록 설정해요:

RUN touch /etc/sandbox-persistent.sh \
    && chown agent:agent /etc/sandbox-persistent.sh \
    && chmod 0644 /etc/sandbox-persistent.sh \
    && printf '%s\n' '. /etc/sandbox-persistent.sh' \
    > /etc/profile.d/sandbox-persistent.sh \
    && printf '%s\n' '. /etc/sandbox-persistent.sh' >> /home/agent/.bashrc

ENV HOME=/home/agent \
    PATH="/home/agent/.local/bin:${PATH}" \
    BASH_ENV=/etc/sandbox-persistent.sh

BASH_ENV는 non-interactive Bash에게 그 파일을 읽으라고 알려줘요. 튜토리얼에서 나중에 에이전트에게 이를 사용하는 지침을 넣게 돼요.

에이전트를 이미지에 빌드하기

Claude Code를 agent로 설치하고 시작 명령을 정하려면 다음을 Dockerfile에 추가하세요:

USER agent
ENV CLAUDE_ENV_FILE=/etc/sandbox-persistent.sh \
    IS_SANDBOX=1
ARG CLAUDE_VERSION
RUN curl -fsSL https://claude.ai/install.sh -o /tmp/install-claude.sh \
    && bash /tmp/install-claude.sh "${CLAUDE_VERSION}" \
    && rm /tmp/install-claude.sh

WORKDIR /home/agent/workspace
ENTRYPOINT ["claude", "--settings", "/home/agent/.config/claude-team/settings.json"]
CMD []

agent로 설치하면 Claude Code가 /home/agent/ 아래에 들어가 그 사용자가 접근할 수 있어요. CLAUDE_ENV_FILE은 지속 환경 변수를 위해 준비한 파일을 Claude Code가 가리키게 해요. 다음 단계에서 descriptor에 CLAUDE_VERSION을 설정하게 돼요.

Dockerfile은 사용자, 작업 디렉터리, 환경 변수, 시작 명령도 설정해요. CMD []는 기본 이미지에서 상속한 인자를 모두 지워요. --settings 옵션은 각 샌드박스에서 고른 모델을 불러와요. 그 설정 파일은 모델 설정 작성하기 단계에서 만들 거예요.

이 이미지에서 만든 각 샌드박스는 같은 Claude Code 바이너리를 얻게 돼요. 다음 단계들에서 Docker Sandboxes가 그것을 어떻게 실행하는지 구성해요. 추가하는 모든 mixin은 v3를 써야 하고, 이 워크로드의 운영체제와 아키텍처와 호환되는 도구만 담아야 해요.

워크로드와 입력값 설명하기

claude-team/claude-team.yaml을 만드세요. 워크로드를 식별하고 두 argument를 선언하는 것으로 시작해요:

version은 이미지 빌드 중에 설치할 Claude Code 버전을 선택해요.

model은 샌드박스를 만들 때 사용할 모델을 선택해요.

# syntax=docker/sandbox-kit:3
schemaVersion: "3"
kind: workload
displayName: Team Claude Code
description: Claude Code with team defaults and API-key authentication

args:
  version:
    default: "2.1.278"
    pattern: '^[0-9]+\.[0-9]+\.[0-9]+$'
    buildArg: CLAUDE_VERSION
  model:
    default: sonnet
    enum: [sonnet, opus, haiku]

provides: ["claude@${{ kit.args.version }}"]

version은 Dockerfile의 CLAUDE_VERSION 빌드 argument를 설정해요. 빌드는 버전을 pattern과 대조해 확인한 뒤 provides에 포함해서, 다른 키트가 어떤 Claude Code 버전이 설치됐는지 확인할 수 있게 해요.

model은 각 샌드박스를 만들 때 모델을 고를 수 있게 해요. 선택값은 설정 파일에 들어가므로 설치된 에이전트는 바뀌지 않아요.

API 접근 허용하기

에이전트를 설치했으니 이제 Anthropic API에 접근할 수 있게 해요. claude-team.yaml의 최상위, provides 다음에 capabilities 목록을 추가하세요:

capabilities:
  - type: com.docker.sandbox/sbx@1
  - type: com.docker.sandbox/network-policy@1
    config:
      runtime:
        allow:
          - api.anthropic.com:443

이 네트워크 규칙은 샌드박스가 실행되는 동안 Anthropic API에 대한 HTTPS 요청을 허용해요. Dockerfile에서 Claude Code를 다운로드하는 것은 빌더의 네트워크를 쓰므로 여기 규칙이 필요 없어요.

sbx@1 항목은 이 워크로드가 sbx가 에이전트의 실행을 관리할 준비가 됐다는 뜻이에요. 여기서 요구하는 셸과 사용자 계정은 에이전트 실행 계약 선언하기 문서를 보세요.

자격 증명 선언하기

Claude Code는 API에 닿지만 인증도 필요해요. 자격 증명 capability를 추가해서 Docker Sandboxes에 어떤 키를 쓸지, 요청에 어떻게 넣을지 알려주세요. 키는 키트 밖인 호스트에 저장하게 돼요.

같은 capabilities 목록에 이 항목을 추가하세요:

  - type: com.docker.sandbox/credential@1
    description: Anthropic API access
    config:
      service: anthropic
      phase: runtime
      apiKey:
        name: ANTHROPIC_API_KEY
        proxyManaged: true
        inject:
          - domain: api.anthropic.com
            header: x-api-key
            format: "%s"

샌드박스는 ANTHROPIC_API_KEY에 자리표시자(placeholder)를 받아요. Claude Code가 api.anthropic.com에 요청을 보내면, 호스트 프록시가 실제 API 키를 x-api-key 헤더에 넣어 줘요. 키는 호스트에 남아 있어요. 키트를 실행할 때 그 값을 제공하고 사용을 승인하게 돼요.

모델 설정 작성하기

Dockerfile의 실행 명령은 /home/agent/.config/claude-team/settings.json을 읽어요. lifecycle capability로 샌드박스에서 고른 모델을 담은 파일을 만들어 봅시다.

capabilities에 이 항목을 추가하세요:

  - type: com.docker.sandbox/lifecycle@1
    config:
      files:
        - path: /home/agent/.config/claude-team/settings.json
          content: |
            {"model": "${{ kit.args.model }}"}
          mode: "0644"

Docker Sandboxes는 고른 model을 채우고 Claude Code가 시작되기 전에 파일을 써요. 이 시점에서 파일을 만들면 각 샌드박스가 같은 이미지로 다른 모델을 쓸 수 있어요.

Docker Sandboxes는 install hooks를 실행한 뒤 UID 1000으로 이 파일들을 써요. 이 예시처럼 에이전트가 쓸 수 있는 절대 경로를 사용하세요. $HOME 같은 셸 변수는 경로에서 확장되지 않아요.

에이전트 지침 추가하기

키트는 Claude Code에 환경에 관한 지침도 줄 수 있어요. 다음 Markdown을 descriptor와 Dockerfile 옆에 저장하세요:

## Team workflow

Read the project's README before changing code. Run the project's checks
before reporting a task complete, and report any checks you couldn't run.

Claude Code is installed in this sandbox. Its additional settings are at
/home/agent/.config/claude-team/settings.json.

Use /etc/sandbox-persistent.sh for environment exports needed by later
Bash commands. Keep shell completion scripts out of that file because
non-interactive commands also source it.

이 지침을 포함하려면 capabilities에 agent-context 항목을 추가하세요:

  - type: com.docker.sandbox/agent-context@1
    config:
      filename: CLAUDE.md
      contentFile: ./context.md

빌드는 context.md를 이미지에 포함해요. 샌드박스가 실행되면 sbx가 마운트된 워크스페이스의 상위 디렉터리에 CLAUDE.md 파일을 써요. 그 파일은 Claude Code를 여러분의 context.md로 안내해요. 프로젝트 안의 CLAUDE.md는 그대로 남아요.

이 예시처럼 contentFile을 쓰면 긴 지침을 별도의 Markdown 파일에 보관할 수 있어요. 지침을 워크로드 descriptor에 직접 쓰고 싶다면 contentFile 대신 content를 쓰면 돼요. 여러 키트의 지침이 어떻게 함께 동작하는지는 런타임 접근과 지침 문서를 보세요.

키 저장하고 실행하기

Anthropic API 키를 호스트에 저장하세요:

$ sbx secret set anthropic

claude-team이 있는 디렉터리에서 키트를 실행하세요:

$ sbx run --name claude-team ./claude-team

sbx는 키트를 빌드하고, 현재 디렉터리를 워크스페이스로 마운트하고, Claude Code를 실행해요. 다른 프로젝트에서 작업하려면 명령에 그 경로를 추가하세요. 프롬프트가 뜨면 저장한 키를 쓰는 키트의 요청을 승인하고, Claude Code의 첫 실행 프롬프트를 따라가세요. 에이전트는 저장한 키와 사용 승인 둘 다 필요해요. Credential bindings 문서를 보세요.

샌드박스를 만들 때 다른 모델을 고를 수도 있어요:

$ sbx run --name claude-team-opus ./claude-team \
    --kit-arg claude-team.model=opus

claude-team 접두사는 로컬 키트 디렉터리 이름과 일치해요. Docker Sandboxes는 opus가 enum의 선택지 중 하나인지 확인한 뒤, Claude Code가 시작되기 전에 설정 파일에 써요.

반복하고 배포하기

descriptor, Dockerfile, 또는 context 파일을 수정하고 다른 이름으로 새 샌드박스를 만들어 변경을 테스트하세요:

$ sbx run --name claude-team-test-2 ./claude-team

기존 샌드박스를 다시 시작해도 수정 사항은 반영되지 않아요. 다른 에이전트 버전을 로컬에서 시험해 보려면 descriptor의 args.version.default를 바꾸고 새 샌드박스를 만드세요.

sbx는 소스 파일과 키트 argument가 바뀌지 않으면 로컬 빌드를 재사용해요. 둘 중 하나라도 바뀌면, model처럼 샌드박스 설정에만 영향을 주는 argument라도 빌드를 다시 할 수 있어요. BuildKit은 바뀌지 않은 이미지 레이어를 여전히 재사용해요.

워크로드 배포하기

키트를 공유할 준비가 되면 Docker Hub에 로그인하고 Docker Buildx로 빌드·푸시하세요. <NAMESPACE>를 푸시할 수 있는 Docker Hub 네임스페이스로 바꾸세요:

$ docker login
$ docker buildx build ./claude-team \
    --file ./claude-team/claude-team.yaml \
    --tag docker.io/<NAMESPACE>/claude-team:1.0.0 \
    --push

--file 옵션은 Buildx가 descriptor를 읽게 해요. 그 syntax 줄은 키트 frontend를 선택하는데, 이 frontend는 동반 Dockerfile을 읽고 descriptor를 배포된 이미지에 포함시켜요. 다른 에이전트 버전을 배포하려면 --build-arg version=<CLAUDE_VERSION>을 추가하세요. 이 플래그는 키트 argument 이름인 version을 쓰며, descriptor는 이를 Dockerfile의 CLAUDE_VERSION에 매핑해요.

배포된 키트를 이미지 참조로 실행하세요:

$ sbx run --name claude-team-shared docker.io/<NAMESPACE>/claude-team:1.0.0

멀티 플랫폼 이미지와 배포 세부사항은 키트 빌드 및 배포하기 문서를 보세요. 도구를 워크로드와 별도로 패키징하는 방법은 도구 믹스인 만들기 문서를 보세요. 그 튜토리얼도 Claude Code를 패키징하므로, 그 mixin은 셸 워크로드와 함께 쓰세요. 이 워크로드와 결합하면 claude를 제공하는 키트가 둘이 되어 Docker Sandboxes가 거절해요.

배포된 워크로드를 키트 세트에 넣고 거기서 설정과 지침을 추가할 수도 있어요. 워크로드는 여전히 기본 이미지 준비, 에이전트 설치, 실행 방법을 정의해요.

더 알아보기 (Learn more)

  • 기본 이미지 요구사항, 에이전트 실행 계약, 런타임 접근과 지침, Credential bindings, 키트 빌드 및 배포하기, Kits v2, 도구 믹스인 만들기, 키트 세트 작성 문서를 참고하세요.