---
title: 자체 호스팅 Claude Managed Agents 시작하기
url: https://platform.claude.com/docs/ko/managed-agents/self-hosted/quickstart
description: Docker Compose를 사용하여 한 대의 머신에서 자체 호스팅 Claude Managed Agents를 시작하고, 샌드박스 컨테이너에서 첫 세션을 실행합니다.
---

<Note>
  자체 호스팅 Claude Managed Agents에 대한 접근 권한을 요청하려면 Anthropic 계정 팀에 문의하세요.
</Note>

이 빠른 시작 가이드에서는 Docker Compose를 사용하여 한 대의 머신에서 자체 호스팅 Claude Managed Agents를 시작합니다. Compose 스택은 서버, 서버의 PostgreSQL 데이터베이스, 그리고 각 세션을 자체 샌드박스 컨테이너에서 실행하는 워커 집합으로 구성됩니다. 그런 다음 터미널에서 에이전트와 대화하고, 에이전트의 도구 호출이 샌드박스 컨테이너에서 실행되었는지 확인합니다. 그런 다음 [서버의 콘솔](https://platform.claude.com/docs/ko/managed-agents/self-hosted/console)에서 세션을 열 수 있습니다.

<Warning>
  Compose 스택은 개발용이며 프로덕션용이 아닙니다. 일반 HTTP로 서비스하며, 기본적으로 포트 8400을 Docker 호스트의 loopback 주소인 `127.0.0.1`에만 게시합니다. 28.3.3 이전의 일부 Docker Engine 릴리스에서는 호스트의 로컬 네트워크에 있는 머신도 해당 포트에 접근할 수 있습니다. 에이전트 도구는 해당 호스트의 컨테이너에서 실행되므로, 보호해야 할 데이터가 없는 머신을 사용하세요.
</Warning>

프로덕션의 경우 Anthropic은 릴리스에 포함된 두 개의 Helm 차트를 권장합니다. [Kubernetes에 배포하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/kubernetes)를 참조하세요.

Claude Code가 이 빠른 시작 가이드를 대신 실행하도록 하기

```text
https://platform.claude.com/docs/en/managed-agents/self-hosted/quickstart.md 를 따라 이 머신에 자체 호스팅 Claude Managed Agents를 설정해 주세요. 릴리스 아카이브는 이미 다운로드했습니다.
```

사람을 대신하여 이 단계를 실행하는 에이전트라면:

* **릴리스 아카이브:** 아카이브가 어디에 있는지 사용자에게 물어보세요. 아카이브는 사용자만 다운로드할 수 있습니다.
* **Claude API 키:** 사용자가 직접 `.env`를 편집하도록 하세요. 키를 요청하지 말고, `.env`를 출력하지 마세요.
* **변수:** 셸이 명령 간에 변수를 유지하지 않는다면 각 `ant` 명령에서 `ANTHROPIC_BASE_URL`과 `ANTHROPIC_API_KEY`를 다시 설정하세요. 이 변수가 없으면 `ant`는 호스팅 서비스를 호출합니다.
* **Compose:** 셸의 값이 서버에 전달되지 않도록 각 `docker compose` 명령 앞에 `env -u ANTHROPIC_BASE_URL -u ANTHROPIC_API_KEY -u ANTHROPIC_AUTH_TOKEN`을 붙이세요.
* **채팅:** `ant beta:sessions connect`에는 대화형 터미널이 필요합니다. 대화형 터미널이 없다면 `ant beta:sessions:events send`로 메시지를 보내고, `ant beta:sessions:events list`로 응답을 읽으세요. [이벤트 보내기](https://platform.claude.com/docs/ko/managed-agents/events-and-streaming#send-events)와 [과거 이벤트 목록 조회](https://platform.claude.com/docs/ko/managed-agents/events-and-streaming#list-past-events)에 예제가 있습니다.
* **콘솔:** "서버에서 콘솔 사용해 보기" 섹션은 사용자가 요청한 경우에만 수행하세요. 셸이 명령 간에 변수를 유지하지 않는다면, 해당 섹션부터는 각 `docker compose` 명령 앞에 `COMPOSE_FILE=docker-compose.yml:docker-compose.oidc.yml`도 붙이세요.

## 사전 요구 사항

* **릴리스 아카이브:** 다운로드 접근 권한을 요청하려면 Anthropic 계정 팀에 문의하세요.
* **Claude API 키:** 서버가 모델 호출에 사용합니다. [Claude Console](https://platform.claude.com/settings/keys)에서 생성하세요.
* **Docker:** [Docker Engine 최신 버전](https://docs.docker.com/engine/install/)과 Compose 플러그인(이전 버전의 `docker-compose`가 아닌 `docker compose`).
* **CPU가 2개 이상인 호스트:** x86-64 또는 Arm. 더 작은 호스트에서는 `.env`를 생성할 때 `CMA_SANDBOX_CPUS`를 해당 호스트의 CPU 수로 설정하세요.
* **첫 시작 시 네트워크 접근:** 첫 빌드에서는 Docker Hub, Alpine 패키지 저장소, GitHub 릴리스에서 항목을 가져옵니다.
* **도구:** Docker를 실행하는 머신에 `openssl`과 [`ant` CLI](https://platform.claude.com/docs/ko/cli-sdks-libraries/cli/quickstart#installation)가 필요합니다.

## 스택 시작하기

<Steps>
  <Step title="아카이브 압축 해제">
    아카이브를 압축 해제하고, 해당 아카이브의 `compose` 디렉터리에서 작업하세요. 명령에서 `<archive>`를 `.tar.gz`를 제외한 아카이브 이름으로 바꾸세요.

    ```bash
    tar -xzf <archive>.tar.gz && cd <archive>/compose
    ```

    umask가 `022`보다 엄격하면 바이너리가 다른 사용자에 대한 실행 권한을 잃어 서버 컨테이너가 바이너리를 시작할 수 없습니다. 이 경우 umask를 `022`로 설정하고 아카이브를 다시 압축 해제하세요.
  </Step>

  <Step title=".env 파일 생성">
    Compose는 `docker-compose.yml`과 같은 위치에 있는 `.env` 파일에서 스택의 시크릿을 읽습니다. 파일을 생성하세요:

    ```bash
    cat > .env <<EOF
    CMA_PG_PASSWORD=$(openssl rand -hex 32)
    ANTHROPIC_API_KEY=sk-ant-...
    CMA_SERVER__API_KEY=$(openssl rand -hex 32)
    CMA_STORE__CREDENTIALS_ENCRYPTION_KEY=$(openssl rand -base64 32)
    EOF
    chmod 600 .env
    ```

    편집기에서 `.env`를 열고 `sk-ant-...`를 Claude API 키로 바꾸세요. 나머지는 이 블록이 생성합니다: 데이터베이스 비밀번호, 애플리케이션이 보내는 서버 API 키, 그리고 서버에 저장된 시크릿을 암호화하는 키입니다.
  </Step>

  <Step title="컨테이너 시작">
    스택을 빌드하고 시작한 다음 서버의 로그를 추적하세요:

    ```bash
    docker compose up --build -d
    docker compose logs -f cma-server
    ```

    로그에 `msg="cma-server listening"`이 포함된 줄이 표시되면 Ctrl+C를 눌러 로그 추적을 중지하세요.
  </Step>

  <Step title="서버 준비 상태 확인">
    ```bash
    curl -s http://127.0.0.1:8400/cma-server/readyz
    ```

    준비된 서버는 `"status":"ready"`로 응답합니다. 시작 직후에는 첫 검사가 실행되는 몇 초 동안 `"status":"degraded"`로 응답할 수 있습니다. 계속 `degraded` 상태로 남아 있거나 `"status":"not_ready"`로 응답하면 [문제 해결](https://platform.claude.com/docs/ko/managed-agents/self-hosted/quickstart#troubleshooting)을 참조하세요.
  </Step>
</Steps>

## 첫 세션 실행

`ant` CLI를 사용하여 터미널에서 에이전트를 생성하고 대화합니다.

<Steps>
  <Step title="CLI가 서버를 가리키도록 설정하기">
    같은 디렉터리에서 두 번째 터미널을 열고 `ant` 전용으로 사용하세요. [자체 호스팅 서버에서 API 호출하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/call-the-api)에서 설명하는 것처럼, 다음 명령은 `ANTHROPIC_API_KEY`를 Claude API 키가 아닌 서버 API 키로 설정합니다:

    ```bash
    export ANTHROPIC_BASE_URL=http://127.0.0.1:8400
    export ANTHROPIC_API_KEY=$(grep '^CMA_SERVER__API_KEY=' .env | cut -d= -f2)
    ```

    `docker compose` 명령은 첫 번째 터미널에서 실행하세요. 이 터미널에서 `docker compose up`을 실행하면 Compose가 이 변수들을 서버에 전달하며, 서버는 Claude API 대신 자기 자신을 호출합니다.
  </Step>

  <Step title="에이전트 생성">
    명령 다음에 나오는 파일을 `quickstart-agent.md`로 저장한 다음 명령을 실행하세요. 이 파일은 에이전트에게 내장 도구를 제공하고, 먼저 사용자에게 묻지 않고 도구를 실행할 수 있도록 합니다.

    <CodeGroup>
      <CodeGroupItem>
        ```bash CLI
        ant apply --yes quickstart-agent.md
        ```

        <File filename="quickstart-agent.md">
          ```markdown
          ---
          name: Quickstart agent
          model: claude-opus-5-5
          tools:
            - type: agent_toolset_20260401
          ---

          You are a helpful assistant.
          ```
        </File>
      </CodeGroupItem>
    </CodeGroup>

    이 명령은 먼저 `404` 오류와 함께 `could not determine the organization and workspace`라는 경고를 출력한 다음 에이전트를 생성합니다. 자체 서버에서는 예상된 동작입니다.
  </Step>

  <Step title="세션 시작">
    다음 명령은 에이전트와 스택의 환경을 찾아 세션을 시작하고, 세션의 ID를 `SESSION_ID`에 저장합니다. 스택은 환경 이름을 `compose-sandbox`로 지정합니다.

    ```bash
    AGENT_ID=$(ant beta:agents list --format raw \
      --transform 'data.#(name=="Quickstart agent").id' --raw-output)
    ENVIRONMENT_ID=$(ant beta:environments list --format raw \
      --transform 'data.#(name=="compose-sandbox").id' --raw-output)
    SESSION_ID=$(ant beta:sessions create --agent "$AGENT_ID" \
      --environment-id "$ENVIRONMENT_ID" --transform id --raw-output)
    ```
  </Step>

  <Step title="에이전트에게 명령 실행 요청">
    터미널을 세션에 연결하세요:

    ```bash
    ant beta:sessions connect "$SESSION_ID"
    ```

    이 명령은 세션의 [채팅 뷰](https://platform.claude.com/docs/ko/cli-sdks-libraries/cli/sessions-connect)를 엽니다. 다음 메시지를 보내세요:

    ```text wrap
    Run `hostname` with the bash tool and tell me the output.
    ```

    에이전트는 `cma-sandbox-`로 시작하는 호스트 이름으로 응답합니다. 이는 명령을 실행한 샌드박스 컨테이너의 이름으로, 도구가 사용자의 머신이 아닌 샌드박스에서 실행되었음을 확인해 줍니다.
  </Step>

  <Step title="샌드박스 컨테이너 찾기">
    채팅은 열어 두세요. 첫 번째 터미널에서 샌드박스 컨테이너 목록을 확인하세요:

    ```bash
    docker ps --filter label=cma-server.sandbox
    ```

    목록에 에이전트가 보고한 컨테이너가 표시됩니다. 컨테이너는 턴이 끝나고 약 1분 후에 종료되며, 세션의 다음 메시지는 새 컨테이너를 시작합니다. 목록이 비어 있으면 에이전트에게 `hostname`을 다시 실행하도록 요청하고, 에이전트가 응답하는 동안 컨테이너 목록을 다시 확인하세요.

    채팅을 종료하려면 해당 터미널에서 Ctrl+C를 누르세요. 세션은 계속 실행됩니다.
  </Step>
</Steps>

## 서버에서 콘솔 사용해 보기

이 섹션은 선택 사항입니다. 콘솔에는 single sign-on이 필요합니다. 콘솔을 사용해 보려면 릴리스의 모의 로그인 공급자로 스택을 다시 시작하세요. 머신의 포트 8080이 사용 중이 아니어야 합니다.

<Warning>
  모의 공급자는 버려도 되는 데이터에만 사용하세요. 모의 공급자는 접근하는 누구에게나 관리자의 토큰을 제공합니다. Docker Desktop에서는 샌드박스 컨테이너도 여기에 포함됩니다. 28.3.3 이전의 일부 Docker Engine 릴리스에서는 네트워크에 있는 머신도 포함됩니다.
</Warning>

<Steps>
  <Step title="모의 로그인 공급자로 스택 다시 시작">
    첫 번째 터미널에서 다음 명령을 실행하세요:

    ```bash
    export COMPOSE_FILE=docker-compose.yml:docker-compose.oidc.yml
    docker compose up --build -d
    ```

    `export` 줄은 첫 번째 터미널에만 적용되므로, `docker compose`를 위해 새로 여는 모든 터미널에서 이 줄을 다시 실행하세요. 이 스택에서 서버의 설정을 변경하려면 `compose.config.yaml`이 아니라 `compose.config.oidc.yaml`을 편집한 다음 `docker compose restart cma-server`를 실행하세요.
  </Step>

  <Step title="세션 열기">
    같은 머신의 브라우저에서 `http://127.0.0.1:8400/`을 열고 **Continue with SSO**를 클릭한 다음 데모 관리자인 **alice**를 선택하세요. 사이드바에서 **Sessions**를 선택한 다음 세션을 선택하세요.

    페이지는 에이전트가 작업하는 동안 업데이트되며, 이 페이지에서 에이전트에게 메시지를 보낼 수 있습니다.
  </Step>
</Steps>

콘솔에서도 에이전트를 생성하고 세션을 시작하려면 [콘솔에서 에이전트 실행하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/console#run-an-agent-from-the-console)를 참조하세요.

## 스택 중지하기

첫 번째 터미널에서 다음 명령을 실행하세요:

```bash
docker compose down --remove-orphans
```

이 명령은 컨테이너를 삭제하고 데이터베이스는 유지합니다. 데이터베이스와 그 안의 모든 에이전트, 세션, 세션 기록까지 삭제하려면 `docker compose down --remove-orphans -v`를 실행하세요.

## 문제 해결

* **아카이브에 `compose` 디렉터리가 없는 경우:** 아카이브에 이전 릴리스가 들어 있으며, 이 페이지의 명령이 해당 릴리스와 맞지 않습니다. Anthropic 계정 팀에 현재 릴리스를 요청하세요. 실행 중인 배포를 현재 릴리스로 옮기려면 [자체 호스팅 Claude Managed Agents 업그레이드](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade)를 참조하세요.

* **서버가 시작되지 않는 경우:** `docker compose logs migrate`를 실행하세요. 일회성 `migrate` 컨테이너가 데이터베이스 테이블을 생성합니다. 서버가 시작되기 전에 이 컨테이너가 상태 `0`으로 종료되어야 합니다.

* **준비 상태 검사가 계속 `degraded`로 남아 있거나 모든 턴이 실패하는 경우:** `ANTHROPIC_BASE_URL`이 `http://127.0.0.1:8400`인 터미널에서 `docker compose up`을 실행했다면, 서버는 Claude API 대신 자기 자신을 호출합니다. 해당 변수가 설정되지 않은 첫 번째 터미널에서 `docker compose up -d`를 다시 실행하세요. 그렇지 않다면 서버 로그에 무엇이 실패했는지 표시됩니다. 로그를 읽으려면 `docker compose logs -f cma-server`를 다시 실행하세요.

* **준비 상태 검사가 `not_ready`로 응답하는 경우:** 응답에서 상태가 `failed`인 검사를 찾으세요:

  * **`upstream`:** Claude API가 Claude API 키를 거부했습니다. `.env`에서 `ANTHROPIC_API_KEY`를 수정한 다음 첫 번째 터미널에서 `docker compose up -d`를 다시 실행하세요. 셸에서도 `ANTHROPIC_API_KEY`를 설정하고 있다면 Compose는 셸의 값을 사용하므로, 먼저 `unset ANTHROPIC_API_KEY`를 실행하세요.
  * **`database`:** 데이터베이스가 서버의 로그인을 거부했거나(예를 들어 비밀번호가 잘못된 경우), 데이터베이스에 대한 열린 연결이 끊어졌습니다. 어느 쪽인지 확인하려면 `docker compose logs -f cma-server`를 다시 실행하세요.

* **에이전트는 응답하지만 도구 호출이 끝나지 않는 경우:** 해당 환경을 폴링하는 워커가 없는 것입니다. `docker compose logs sandbox`로 워커 로그를 확인하세요. Docker 데몬의 소켓에 연결할 수 없는 워커는 `CMA_DOCKER_SOCKET`을 언급하는 메시지와 함께 종료됩니다. `.env`에서 해당 변수를 데몬의 소켓 경로로 설정한 다음 첫 번째 터미널에서 `docker compose up -d`를 다시 실행하세요.

* **워커가 실행 중인데도 도구 호출이 끝나지 않는 경우:** 스택은 10개의 워커를 시작하며, 각 워커는 한 번에 한 세션의 컨테이너를 실행합니다. 세션은 생성될 때 유휴 워커를 하나 차지하며, 메시지를 한 번도 받지 않은 세션은 최대 1시간 동안 워커를 유지합니다. 10개가 모두 사용 중이면 다른 세션의 도구 호출은 워커를 기다립니다. "샌드박스 컨테이너 찾기" 단계의 `docker ps` 명령이 10개의 컨테이너를 표시한다면, 사용하지 않는 세션을 보관하세요:

  1. 첫 번째 터미널에서 `docker ps --filter label=cma-server.sandbox --format '{{.Label "cma-server.session"}}'`를 실행하세요. 각 컨테이너에 해당하는 세션의 ID가 출력됩니다. 대기 중인 세션은 아직 컨테이너가 없으므로 목록에 나타나지 않습니다.
  2. 두 번째 터미널에서 Ctrl+C를 눌러 채팅을 종료하고, 목록에 있는 세션 중 사용하지 않는 각 세션에 대해 `ant beta:sessions archive --session-id <session-id>`를 실행하세요.
  3. `ant beta:sessions connect "$SESSION_ID"`를 다시 실행하세요. 워커가 해당 세션을 차지하면 도구 호출이 완료됩니다.

## 다음 단계

<CardGroup cols={2}>
  <Card title="API 호출하기" icon="code-brackets" href="https://platform.claude.com/docs/ko/managed-agents/self-hosted/call-the-api">
    SDK와 `ant` CLI가 서버를 가리키도록 설정합니다.
  </Card>

  <Card title="호스팅 서비스와의 차이점" icon="arrows-left-right" href="https://platform.claude.com/docs/ko/managed-agents/self-hosted/differences">
    어떤 기능이 다르게 동작하거나 사용할 수 없는지 확인합니다.
  </Card>

  <Card title="서버의 콘솔" icon="browser" href="https://platform.claude.com/docs/ko/managed-agents/self-hosted/console">
    로그인을 설정하고, 브라우저에서 에이전트를 생성하고 세션을 실행합니다.
  </Card>
</CardGroup>
