---
title: 자체 호스팅 Claude Managed Agents 업그레이드
url: https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade
description: Kubernetes 또는 Docker Compose에서 자체 호스팅 Claude Managed Agents 배포를 업그레이드하고, 새 릴리스가 작동하지 않으면 롤백합니다.
---

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

이 페이지에서는 Kubernetes 또는 Docker Compose에서 배포를 업그레이드하는 방법과 롤백하는 방법을 설명합니다. Kubernetes에서 다운타임은 업그레이드의 범위에 따라 달라집니다:

| 업그레이드                                                       | 먼저 데이터베이스 백업                | Kubernetes에서의 다운타임                                 |
| ----------------------------------------------------------- | --------------------------- | -------------------------------------------------- |
| 패치: 세 번째 숫자만 바뀜                                             | 아니요. 데이터베이스 스키마는 그대로 유지됩니다. | 없음                                                 |
| 마이너: 두 번째 숫자가 1 올라감(예: `1.2.0`에서 `1.3.0`으로)                 | 예. 스키마가 변경됩니다.              | 없음. 단, `CHANGELOG.md` 섹션에서 서버를 중지해야 한다고 명시한 경우는 제외 |
| 마이너 릴리스를 건너뛰는 경우(예: `1.1.0`에서 `1.3.0`으로) 또는 첫 번째 숫자가 바뀌는 경우 | 예. 스키마가 변경됩니다.              | 이전 서버를 중지한 시점부터 새 서버가 준비될 때까지                      |

Docker Compose 스택은 모든 종류의 업그레이드에서 재시작하는 동안 중단됩니다.

## 업그레이드 전에

압축을 푼 아카이브의 최상위에 있는 `CHANGELOG.md`에서 새 릴리스의 섹션을 읽으세요. 이 섹션은 해당 릴리스에 특화된 업그레이드 단계로 시작합니다. 릴리스를 건너뛰는 경우, 현재 버전보다 새로운 모든 섹션을 가장 오래된 것부터 차례로 따르세요.

그런 다음 [확인할 설정 및 경로](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#settings-and-paths-to-check)를 살펴보세요.

마이너 또는 메이저 업그레이드에는 데이터베이스 백업이 포함됩니다. 덤프에는 모든 대화가 평문으로 담겨 있으므로, 이 페이지의 명령은 [age 암호화 도구](https://age-encryption.org)로 덤프를 암호화합니다. 키 쌍을 한 번 생성하고, 개인 키인 `cma-backup.agekey`는 백업과 분리하여 보관하세요:

```bash
age-keygen -o cma-backup.agekey
age-keygen -y cma-backup.agekey > cma-backup.agepub
```

## Kubernetes에서 업그레이드

이 페이지의 `kubectl` 명령은 셸 변수에서 서버 Deployment의 이름을 읽습니다. 명령을 실행하는 각 터미널에서 다음 두 줄을 실행하세요. 첫 번째 줄은 이름을 조회하고, 두 번째 줄은 이름을 출력합니다:

```bash
server=$(kubectl -n cma-server get deployment -l anthropic.com/role=server -o jsonpath='{.items[*].metadata.name}')
echo "$server"
```

두 번째 줄에서 `cma-server`가 출력되면 계속 진행하세요. 다른 이름이 출력되면 업그레이드하기 전에 [객체의 이름](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#object-names)을 읽으세요. 아무것도 출력되지 않으면 `kubectl`이 올바른 클러스터를 가리키는지 확인하고 두 줄을 다시 실행하세요.

<Steps>
  <Step title="새 이미지 빌드 및 푸시">
    새 아카이브의 압축을 푸세요. [이미지 빌드 및 푸시](https://platform.claude.com/docs/ko/managed-agents/self-hosted/kubernetes#build-and-push-the-images)에서와 같이 세 개의 이미지를 새 버전으로 빌드하여 푸시하세요. [egress gateway](https://platform.claude.com/docs/ko/managed-agents/self-hosted/agent-identity#environment-variable-credentials)(이그레스 게이트웨이)를 실행하는 경우, 해당 이미지도 빌드하여 푸시하세요.

    자체 샌드박스 이미지를 빌드하는 경우, 그 이미지도 새 버전으로 다시 빌드하여 푸시하세요. 해당 Dockerfile을 새 아카이브의 `kubernetes/sandbox/Dockerfile`과 비교하고, [자체 이미지에 필요한 사항](https://platform.claude.com/docs/ko/managed-agents/self-hosted/call-the-api#what-an-image-of-your-own-needs)을 참조하세요.
  </Step>

  <Step title="values 파일에 새 버전 설정">
    values 파일에서 `image.tag`를 설정했다면 새 버전으로 변경하세요.
  </Step>

  <Step title="업그레이드에 필요한 경우 모든 서버 중지">
    다음 경우에만 이 단계를 수행하세요:

    * 실행 중인 서버가 새 릴리스보다 두 개 이상의 마이너 릴리스만큼 뒤처져 있는 경우.
    * 첫 번째 숫자인 메이저 버전이 올라가는 경우.
    * 실행 중인 릴리스보다 새로운 `CHANGELOG.md` 섹션에서 서버를 중지해야 한다고 명시한 경우.

    이 단계부터 새 서버가 준비될 때까지 클라이언트가 배포에 접근할 수 없으므로, 유지 관리 기간을 계획하세요.

    ```bash
    kubectl -n cma-server scale deployment/$server --replicas=0
    kubectl -n cma-server wait --for=delete pod -l anthropic.com/role=server --timeout=90s
    ```
  </Step>

  <Step title="데이터베이스 백업">
    마이너 또는 메이저 업그레이드 전에, 또는 서버를 중지한 경우 이 작업을 수행하세요. 이전 릴리스가 변경된 스키마에서 실행될 수 없다면, 이 백업이 되돌아갈 유일한 방법입니다.

    데이터베이스 서버와 같은 메이저 버전의 PostgreSQL에 포함된 `pg_dump`를 사용하세요. `<role>`과 `<database>`에는 `cma-server-values.yaml`에 있는 `database.url`의 `user` 및 `dbname` 값을 사용하세요. `pg_dump`는 역할의 비밀번호를 묻습니다.

    ```bash
    set -o pipefail
    PGSSLMODE=require pg_dump -h <database-host> -U <role> -d <database> -Fc \
      | age -r "$(cat cma-backup.agepub)" -o cma_server-<old-version>.dump.age
    ```

    두 명령 중 하나라도 오류를 출력하면, 남겨진 파일은 백업이 아닙니다. 원인을 해결하고 명령을 다시 실행한 후에 진행하세요.

    서버가 실행 중이면 백업에는 덤프가 시작되기 전에 클라이언트가 기록한 내용만 담깁니다.
  </Step>

  <Step title="서버를 업그레이드한 다음 샌드박스 업그레이드">
    설치 시 사용한 values 파일을 사용하여, 새 아카이브의 최상위 디렉터리에서 다음 명령을 실행하세요:

    ```bash
    helm upgrade cma-server kubernetes/server/chart --namespace cma-server -f cma-server-values.yaml --wait
    helm upgrade cma kubernetes/chart --namespace cma -f cma-values.yaml --wait
    ```

    둘 이상의 환경을 실행하는 경우, 각 샌드박스 릴리스에 대해 해당 릴리스의 이름, 네임스페이스, values 파일을 사용하여 두 번째 명령을 실행하세요.

    서버를 중지한 경우, 첫 번째 명령은 스키마를 마이그레이션하고, 서버 수를 복원하며, 새 서버가 준비되면 완료됩니다.
  </Step>
</Steps>

서버가 실행 중인 경우, Helm은 이전 서버를 중지하기 전에 각 새 서버를 시작하므로, 준비된 서버의 수가 줄어들지 않습니다. 마이너 업그레이드에서 첫 번째 명령은 이전 서버가 계속 서비스하는 동안 스키마를 변경한 다음, 이전 서버를 교체합니다. 교체 중인 서버의 열린 이벤트 스트림은 정상적으로 종료되므로, 스트림을 따라가는 클라이언트는 다시 연결해야 합니다.

명령이 실패하면 [업그레이드가 실패하는 경우](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#if-the-upgrade-fails)를 참조하세요.

## Docker Compose에서 업그레이드

단계는 모든 종류의 업그레이드에서 동일합니다. 각 `docker compose` 명령은 릴리스의 Compose 디렉터리, 즉 `docker-compose.yml`이 있는 디렉터리에서 실행하세요. 압축을 푼 아카이브에서 이 디렉터리는 `compose`입니다. Compose는 셸에 설정된 `ANTHROPIC_BASE_URL`, `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN` 변수의 값을 서버에 전달하므로, 이 변수들이 설정되지 않은 터미널을 사용하세요.

<Steps>
  <Step title="데이터베이스 백업">
    마이너 또는 메이저 업그레이드 전에, 이전 릴리스의 Compose 디렉터리에서 이 작업을 수행하세요:

    ```bash
    set -o pipefail
    docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \
      | age -r "$(cat cma-backup.agepub)" -o cma_server-<old-version>.dump.age
    ```

    명령에서 `$POSTGRES_USER`와 `$POSTGRES_DB`는 그대로 두세요. 작은따옴표 안의 텍스트는 `postgres` 컨테이너 내부에서 실행되며, 이 컨테이너는 해당 변수에 자신의 역할 이름과 데이터베이스 이름을 담고 있습니다.

    백업하는 동안에도 스택이 계속 서비스하므로, 덤프에는 덤프가 시작된 후 클라이언트가 기록한 내용이 포함되지 않습니다. 두 명령 중 하나라도 오류를 출력하면, 남겨진 파일은 백업이 아닙니다. 원인을 해결하고 명령을 다시 실행한 후에 진행하세요.
  </Step>

  <Step title="새 아카이브 압축 풀기">
    새 릴리스를 계속 둘 수 있는 디렉터리(예: 이전 릴리스의 상위 디렉터리)에 새 아카이브를 두세요. 명령은 그곳에서 아카이브의 압축을 풀며, 새 스택은 압축을 푼 파일에서 실행됩니다.

    umask가 `022`보다 엄격하면 먼저 `umask 022`를 실행하세요. 그런 다음 이전 릴리스의 Compose 디렉터리에서 다음을 실행하세요. `<directory>` 자리에는 새 아카이브가 있는 디렉터리의 전체 경로를 쓰세요. `<archive>` 자리에는 `.tar.gz`를 뺀 아카이브의 이름을 쓰세요.

    ```bash
    releases="<directory>"
    tar -xzf "$releases/<archive>.tar.gz" -C "$releases" && cp .env compose.config.yaml "$releases/<archive>/compose/"
    ```

    두 번째 줄은 `.env`와 `compose.config.yaml`도 압축을 푼 `compose` 디렉터리로 복사합니다. 두 줄이 실행되는 동안 이전 스택은 계속 실행됩니다. 어느 줄에서든 오류가 출력되면 원인을 해결하고 두 줄을 모두 다시 실행하세요.
  </Step>

  <Step title="다른 변경 사항 다시 적용">
    `.env`와 `compose.config.yaml`만 새 릴리스로 이어집니다. 다른 변경 사항은 새 릴리스의 Compose 디렉터리에서 다시 적용하세요:

    * **추가한 파일:** 복사하세요.
    * **수정한 제공 파일:** 새 릴리스의 사본에 같은 수정을 적용하세요. 이전 파일을 그 위에 복사하지 마세요. 그러면 릴리스에서 해당 파일에 적용한 변경 사항이 취소됩니다.
    * **에이전트 ID:** `agent-identity` 디렉터리를 `cp -a`로 복사하고(root가 소유한 경우 `sudo` 사용), `docker-compose.yml`의 `volumes:` 블록을 다시 수정하세요.
    * **직접 만든 Compose 파일:** 복사한 다음 상대 경로를 확인하세요.

    그런 다음 [확인할 설정 및 경로](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#settings-and-paths-to-check)의 Docker Compose 변경 사항을 적용하세요.
  </Step>

  <Step title="이전 스택 중지 및 새 스택 시작">
    이 줄들은 아카이브의 압축을 푼 터미널의 `$releases` 변수를 사용하므로, 해당 터미널에서 실행하세요. 이전 릴리스의 Compose 디렉터리에 있는 상태로, `<archive>` 자리에 같은 이름을 쓰세요. 이전 스택에 대해 `COMPOSE_FILE`을 export했다면 먼저 같은 값을 export하세요.

    ```bash
    ls "$releases/<archive>/compose/.env" && docker compose down
    cd "$releases/<archive>/compose" && docker compose up --build -d
    ```

    첫 번째 줄은 새 릴리스의 `.env`가 제자리에 있는 경우에만 이전 스택을 중지합니다. `docker compose down`은 데이터베이스를 유지합니다. 데이터베이스를 삭제하는 `-v`는 추가하지 마세요. 새 스택은 데이터베이스를 이어받으며, 새 스택의 `migrate` 컨테이너가 서버가 시작되기 전에 스키마를 업데이트합니다.
  </Step>
</Steps>

명령이 실패하면 [업그레이드가 실패하는 경우](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#if-the-upgrade-fails)를 참조하세요.

## 업그레이드가 실패하는 경우

롤백하기 전에 로그에서 원인을 찾으세요:

* **Kubernetes:** 마이그레이션 Job이 실패하면 `helm upgrade`는 Job이 재시도하는 동안 몇 분간 기다린 후 실패합니다. 그 대기 시간 동안 [Kubernetes에서 업그레이드](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#upgrade-on-kubernetes)에서와 같이 `$server`를 설정한 두 번째 터미널에서 `kubectl -n cma-server logs job/$server-migrate`를 실행하세요. Job이 재시도를 멈추면 Kubernetes가 로그를 삭제합니다. 로그를 놓쳤다면 `helm upgrade`를 다시 실행하세요. 그러면 Job이 다시 시작됩니다.
* **Docker Compose:** `docker compose up --build -d`의 출력에 원인이 표시되지 않을 수 있습니다. `docker compose logs`를 실행해 원인을 찾으세요.

| 로그에 표시되는 내용                                                                                      | 의미                                                                               | 조치 방법                                                                                                                                                                                                                                  |
| ------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `refusing to migrate: servers of another release are still running against this database`가 포함된 줄 | 일부 업그레이드에서는 먼저 모든 서버를 중지해야 하는데, 이전 릴리스의 서버가 아직 실행 중입니다. 마이그레이션은 아무것도 변경하지 않았습니다. | [Kubernetes에서 업그레이드](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#upgrade-on-kubernetes)에서와 같이 모든 서버를 중지하고 `helm upgrade`를 다시 실행하세요. 서버가 정상적으로 종료되지 않았다면 먼저 20초를 기다리세요. 그때까지 마이그레이션은 해당 서버를 실행 중인 것으로 간주합니다. |
| 이전 릴리스를 다시 배포할 때 `cannot downgrade`가 포함된 줄                                                       | 이전 릴리스가 변경된 스키마에서 실행될 수 없습니다.                                                    | [롤백](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#roll-back)에서와 같이 백업을 복원하세요.                                                                                                                                |
| 마이그레이션의 다른 오류                                                                                    | 롤백할 필요가 없습니다. Kubernetes에서는 마이그레이션이 성공할 때까지 서버가 그대로 유지됩니다.                       | 원인을 해결하고 `helm upgrade` 또는 `docker compose up --build -d`를 다시 실행하세요.                                                                                                                                                                   |

마이그레이션은 성공했지만 새 서버가 준비 상태가 되지 않을 수 있습니다. 원인을 찾으려면 서버의 로그를 읽으세요:

* **Kubernetes:** `kubectl -n cma-server logs -l anthropic.com/role=server --prefix --tail=20`
* **Docker Compose:** `docker compose logs cma-server`

예를 들어 Kubernetes에서 `has invalid keys`가 포함된 줄은 새 릴리스가 허용하지 않는 `server.config` 아래의 설정을 가리킵니다. 복원하면 데이터가 손실되므로 복원을 고려하기 전에 원인을 해결하고 업그레이드 명령을 다시 실행하세요. Kubernetes에서는 스키마가 변경된 후에도 실행 중인 이전 릴리스의 서버는 계속 서비스하지만, 중지되면 다시 시작되지 않을 수 있습니다.

## 롤백

이 섹션의 `kubectl` 명령은 [Kubernetes에서 업그레이드](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#upgrade-on-kubernetes)의 `$server` 변수를 사용합니다. 롤백하기 전에 [업그레이드가 실패하는 경우](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#if-the-upgrade-fails)를 확인하세요. 그런 다음 업그레이드 종류에 따라 롤백하세요:

* **패치 업그레이드 후:** [이전 릴리스를 다시 배포하세요](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#deploy-the-old-release-again). 두 릴리스는 같은 스키마를 사용합니다.

* **마이너 또는 메이저 업그레이드 후:** 새 아카이브의 `CHANGELOG.md`를 여세요. 되돌아가려는 릴리스 이후에 나온 모든 릴리스의 섹션을 읽으세요.

  * 어느 섹션에서든 이전 릴리스가 마이그레이션된 데이터베이스에서 시작할 수 없다고 하면, 백업을 복원하세요.
  * 그렇지 않으면 이전 릴리스를 다시 배포하세요. 이 작업이 `cannot downgrade`로 실패하면 백업을 복원하세요.

<Warning>
  백업을 복원하면 백업이 시작된 이후 클라이언트가 기록한 모든 내용이 사라집니다.
</Warning>

### 이전 릴리스 다시 배포하기

* **Kubernetes:** 이전 아카이브의 최상위 디렉터리로 이동하세요. 해당 릴리스 당시의 values 파일로 [Kubernetes에서 업그레이드](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#upgrade-on-kubernetes)의 두 `helm upgrade` 명령을 실행하세요. 예를 들어 업그레이드를 위해 `earlierNames`를 추가했다면 제거하세요. 두 번째 명령은 첫 번째 명령이 성공한 경우에만 실행하세요.
* **Docker Compose:** 새 릴리스의 Compose 디렉터리에서 `docker compose down`을 실행한 다음, 이전 릴리스의 Compose 디렉터리에서 `docker compose up --build -d`를 실행하세요.

이전 릴리스가 변경된 스키마에서 실행될 수 없으면 로그에 `cannot downgrade`가 표시됩니다:

* **Kubernetes:** 마이그레이션 Job이 실패하고 서버는 그대로 유지됩니다. Job의 로그를 읽는 방법은 [업그레이드가 실패하는 경우](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#if-the-upgrade-fails)에 설명되어 있습니다.
* **Docker Compose:** 서버가 시작되지 않습니다. `docker compose logs migrate`로 로그를 읽으세요.

Docker Compose에서는 `docker compose logs`의 출력에 대신 `stored value is encrypted but no encryption key is configured`가 표시될 수 있습니다. 이 경우 이전 릴리스의 `.env`에 `CMA_STORE__CREDENTIALS_ENCRYPTION_KEY` 줄이 없는 것입니다. 새 릴리스의 `.env`에서 해당 줄을 복사한 다음 `docker compose up --build -d`를 다시 실행하세요.

### Kubernetes에서 백업 복원하기

데이터베이스 서버에 데이터베이스의 두 번째 사본을 저장할 공간이 필요합니다. `<role>`과 `<database>`에는 `cma-server-values.yaml`에 있는 `database.url`의 `user` 및 `dbname` 값을 사용하세요.

<Steps>
  <Step title="새 데이터베이스에 백업 복원">
    관리자로 데이터베이스 서버의 `postgres` 데이터베이스에 연결하고 다음을 실행하세요:

    ```sql
    CREATE DATABASE <database>_restored OWNER <role>;
    ```

    그런 다음 백업이 있는 머신에서 키와 백업 파일의 경로를 넣어 이 명령을 실행하세요. 데이터베이스 서버와 같은 메이저 버전의 `pg_restore`를 사용하세요. 이 명령은 역할의 비밀번호를 묻고, 성공하면 아무것도 출력하지 않습니다.

    ```bash
    age -d -i cma-backup.agekey cma_server-<old-version>.dump.age \
      | PGSSLMODE=require pg_restore -h <database-host> -U <role> -d <database>_restored --no-owner --exit-on-error
    ```

    오류가 출력되면 중단하세요. 데이터베이스는 변경되지 않았습니다. 관리자로 `DROP DATABASE <database>_restored;`를 실행한 다음 이 단계를 다시 시작하세요.
  </Step>

  <Step title="모든 서버 중지">
    ```bash
    kubectl -n cma-server scale deployment/$server --replicas=0
    kubectl -n cma-server wait --for=delete pod -l anthropic.com/role=server --timeout=90s
    ```
  </Step>

  <Step title="복원된 데이터베이스로 전환">
    관리자로 `postgres` 데이터베이스에 연결하고 다음을 실행하세요:

    ```sql
    ALTER DATABASE <database> RENAME TO <database>_upgraded;
    ALTER DATABASE <database>_restored RENAME TO <database>;
    ```

    첫 번째 문에서 다른 세션이 데이터베이스를 사용 중이라고 표시되면, 해당 세션을 닫고 두 문을 모두 다시 실행하세요. 연결 풀러가 이러한 세션을 유지하고 있을 수 있습니다.
  </Step>

  <Step title="이전 릴리스 배포">
    [이전 릴리스 다시 배포하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#deploy-the-old-release-again)의 Kubernetes 항목을 따르세요. 첫 번째 명령은 서버 수도 원래대로 되돌립니다. 명령이 실패했지만 `kubectl -n cma-server get pods`에서 이전 서버가 준비된 것으로 표시되면 [키 확인이 실패하는 경우](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#if-the-key-check-fails)를 참조하세요.
  </Step>

  <Step title="따로 보관해 둔 데이터베이스 삭제">
    해당 데이터베이스에는 백업 이후 클라이언트가 쓴 내용이 여전히 남아 있습니다. 이전 릴리스가 작동하면 `DROP DATABASE <database>_upgraded;`로 삭제하세요.
  </Step>
</Steps>

#### 키 확인이 실패하는 경우

"이전 릴리스 배포" 단계에서 첫 번째 `helm upgrade` 명령은 이전 서버가 준비될 때까지 기다립니다. 그런 다음 샌드박스가 연결에 사용하는 키를 확인합니다. 명령이 실패했지만 `kubectl -n cma-server get pods`에서 이전 서버가 준비된 것으로 표시되면, 해당 확인이 실패한 것입니다.

데이터는 복원되었고 서버는 작동하지만, 샌드박스가 아직 서버에 연결할 수 없습니다. 샌드박스는 자체 네임스페이스인 `cma`에 있는 `cma-environment` Secret의 키로 연결합니다. 이 키가 백업보다 최신이므로, 복원된 데이터베이스가 이 키를 인식하지 못합니다.

원인을 확인하려면 첫 번째 명령을 다시 실행하세요. 명령이 대기하는 동안 두 번째 터미널을 열고 그곳에서도 `$server`를 설정하세요. 그런 다음 `default` 대신 환경 이름을 넣어 `kubectl -n cma-server logs job/$server-environment-default`를 실행하세요. `Secret cma/cma-environment records key`가 포함된 줄을 찾으세요. 로그에 다른 오류가 표시되면 해당 오류가 가리키는 문제를 해결하세요.

로그에 해당 줄이 표시되면 `kubectl -n cma delete secret cma-environment`로 Secret을 삭제하고 첫 번째 명령을 다시 실행하세요. 이 명령은 새 키로 Secret을 다시 생성합니다. 그런 다음 두 번째 명령을 실행하세요.

### Docker Compose에서 백업 복원하기

<Steps>
  <Step title="데이터베이스만 시작">
    새 릴리스의 Compose 디렉터리에서 `docker compose down`을 실행하세요. 그런 다음 이전 릴리스의 Compose 디렉터리에서 `docker compose up -d --wait postgres`를 실행하세요. 다음 단계에서도 해당 디렉터리에 머무르세요.
  </Step>

  <Step title="새 데이터베이스에 백업 복원">
    이전 릴리스의 Compose 디렉터리에서 키와 백업 파일의 경로를 넣어 다음을 실행하세요:

    ```bash
    docker compose exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d postgres \
        -c "DROP DATABASE IF EXISTS ${POSTGRES_DB}_restored" -c "CREATE DATABASE ${POSTGRES_DB}_restored"' \
      && age -d -i cma-backup.agekey cma_server-<old-version>.dump.age \
      | docker compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "${POSTGRES_DB}_restored" --no-owner --exit-on-error'
    ```

    `DROP DATABASE`와 `CREATE DATABASE`가 출력되고 오류가 없으면 성공한 것입니다.

    여기와 다음 단계에서 `$POSTGRES_USER`와 `$POSTGRES_DB`는 그대로 두세요. 작은따옴표 안의 텍스트는 `postgres` 컨테이너 내부에서 실행되며, 이 컨테이너는 해당 변수에 자신의 역할 이름과 데이터베이스 이름을 담고 있습니다.

    오류가 출력되면 데이터베이스는 변경되지 않았으므로 전체 명령을 다시 실행할 수 있습니다. 백업을 복원할 수 없으면 새 릴리스의 Compose 디렉터리에서 `docker compose up --build -d`를 실행해 해당 릴리스를 다시 시작하세요.
  </Step>

  <Step title="복원된 데이터베이스로 전환">
    ```bash
    docker compose exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d postgres \
        -c "ALTER DATABASE $POSTGRES_DB RENAME TO ${POSTGRES_DB}_upgraded" \
        -c "ALTER DATABASE ${POSTGRES_DB}_restored RENAME TO $POSTGRES_DB"'
    ```
  </Step>

  <Step title="이전 릴리스 시작">
    `docker compose up --build -d`를 실행하세요.
  </Step>

  <Step title="따로 보관해 둔 데이터베이스 삭제">
    해당 데이터베이스에는 백업 이후 클라이언트가 쓴 내용이 여전히 남아 있습니다. 이전 릴리스가 작동하면 해당 데이터베이스를 삭제하세요:

    ```bash
    docker compose exec -T postgres sh -c 'psql -U "$POSTGRES_USER" -d postgres -c "DROP DATABASE ${POSTGRES_DB}_upgraded"'
    ```
  </Step>
</Steps>

### 복원 후

복원하면 환경 키가 백업 시점의 상태로 돌아갑니다:

* **백업 이후 폐기한 키:** 다시 작동합니다. 다시 폐기하세요.
* **백업 이후 생성한 키:** 사라집니다. 해당 키를 사용하던 워커를 위해 새 키를 생성하세요.

[자체 워커용 환경 키 교체하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/kubernetes#replace-an-environment-key-for-your-own-workers)에 명령이 있으며, 이 명령은 Docker Compose에서도 작동합니다. Docker Compose 스택이 시작하는 샌드박스는 스택이 시작될 때 키를 교체하므로 별도의 조치가 필요하지 않습니다.

폐기된 키를 포함해 환경의 키를 나열하려면 다음과 같이 `list-keys`를 실행하세요:

* [자체 호스팅 서버에서 API 호출하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/call-the-api)에서 설정한 터미널을 사용하세요. `docker compose`를 실행하는 터미널은 사용하지 마세요.
* Kubernetes에서는 먼저 다른 터미널에서 그곳에서도 `$server`를 설정한 다음 `kubectl -n cma-server port-forward svc/$server 8400:8400`을 실행하세요.
* 아카이브의 최상위 디렉터리에서 각 환경마다 해당 환경의 ID를 넣어 명령을 한 번씩 실행하세요.

```bash
echo "$ANTHROPIC_API_KEY" | ./cma-server-admin list-keys \
  -base-url http://127.0.0.1:8400 -env env_01595EKxaaTTGwwY3kyXdtbs \
  -key-file - -all
```

### 백업 테스트하기

덤프가 복원되는지 확인하려면 "새 데이터베이스에 백업 복원" 단계만 실행하세요. 이 단계는 [Kubernetes에서 백업 복원하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#restore-the-backup-on-kubernetes)와 [Docker Compose에서 백업 복원하기](https://platform.claude.com/docs/ko/managed-agents/self-hosted/upgrade#restore-the-backup-on-docker-compose)에 있습니다. 이 단계는 사용 중인 데이터베이스를 변경하지 않습니다. 그런 다음 새 데이터베이스를 삭제하세요. Docker Compose에서 새 데이터베이스의 이름은 데이터베이스 이름 끝에 `_restored`를 붙인 것입니다.

## 확인할 설정 및 경로

업그레이드 명령을 실행하기 전에 이 섹션을 읽으세요.

[설정 파일](https://platform.claude.com/docs/ko/managed-agents/self-hosted/configuration-reference#where-settings-go)의 `web_tools` 섹션을 확인하세요. 파일에 해당 섹션이 없거나 섹션에 설정된 키가 없으면, 업그레이드 후 `web_search` 및 `web_fetch` 도구가 꺼집니다. 그러면 기본 도구 세트를 사용하는 에이전트는 오류 없이 이 도구들 없이 실행됩니다. 도구 세트에서 두 도구 중 하나를 켜는 에이전트는 세션을 시작할 수 없습니다. 도구를 유지하려면 [웹 도구에는 서버 설정이 필요합니다](https://platform.claude.com/docs/ko/managed-agents/self-hosted/differences#web-tools-need-a-server-setting)를 참조하세요.

Kubernetes에서는 `cma-values.yaml`과 같은 각 샌드박스 values 파일에서 `egress.mode`를 설정하는지 확인하세요. 샌드박스의 공용 인터넷 접근을 유지하려면 `egress` 아래에 `mode: publicInternet`을 추가하세요. 파일에 모드가 지정되어 있지 않으면, 차트는 기본 모드인 `closed`를 적용합니다. 그러면 샌드박스 차트의 `helm upgrade` 명령은 `egress.mode is closed and egress.closed.hosts is empty`와 같은 오류와 함께 중단되며, 아무것도 변경하지 않습니다.

같은 파일에서 `sandbox.idleTimeout`을 확인하세요. 파일에서 이를 설정하지 않으면, 에이전트의 턴이 끝나고 약 5분 후에 세션의 파드가 사라집니다. 에이전트가 실행 상태로 남겨 둔 프로세스는 파드와 함께 중지됩니다. 기본적으로 `/workspace`의 파일은 유지됩니다. 파드를 30분 동안 유지하려면 `sandbox` 아래에 `idleTimeout: 30m`을 추가하세요.

설정 파일에서 `inference.attribution`을, 서버 환경에서 `CMA_INFERENCE__ATTRIBUTION`을 확인하세요. 해당 줄이 있으면 삭제하세요. 업그레이드하려는 릴리스에는 이 설정이 없으며, 둘 중 하나라도 설정되어 있으면 해당 릴리스의 서버가 시작되지 않습니다.

Claude API가 추론 공급자인 경우, 업그레이드 후 각 모델 호출에는 해당 세션의 ID와 그 세션의 에이전트 및 환경의 ID가 포함됩니다. [서버가 추론 공급자에 보내는 내용](https://platform.claude.com/docs/ko/managed-agents/self-hosted-data-and-access#what-the-server-sends-to-its-inference-provider)을 참조하세요.

### Kubernetes: 객체의 이름

`cma-server-values.yaml`은 `earlierNames` 설정에서 설치에 어떤 이름이 사용되는지 명시해야 합니다. 서버 Deployment의 이름을 찾으려면 `kubectl -n cma-server get deployment -l anthropic.com/role=server`를 실행하세요.

| Deployment의 이름 | `cma-server-values.yaml`의 줄 |
| -------------- | --------------------------- |
| `cma-onprem`   | `earlierNames: true`        |
| `cma-server`   | `earlierNames: false`       |

파일에 이 줄이 없으면 업그레이드하기 전에 추가하고, 이후의 모든 업그레이드에서도 유지하세요. 이 줄이 없으면 서버 차트의 `helm upgrade` 명령은 `earlierNames`를 언급하는 오류와 함께 중단되며, 아무것도 변경하지 않습니다.

`earlierNames: true`를 사용하면 차트의 객체는 `cma-onprem` 이름을 유지하고, 서버는 해당 이름으로 생성한 Secret을 계속 찾을 수 있습니다. 이 페이지들은 가운데 열의 이름을 사용합니다. `earlierNames: true`를 사용하는 경우 대신 마지막 열의 이름을 사용하세요:

| 객체                         | 이 페이지들에서 사용하는 이름                | `earlierNames: true`를 사용할 때의 이름 |
| -------------------------- | ------------------------------- | ------------------------------- |
| 서버의 Deployment 및 Service   | `cma-server`                    | `cma-onprem`                    |
| 마이그레이션 Job                 | `cma-server-migrate`            | `cma-onprem-migrate`            |
| 각 환경의 Job                  | `cma-server-environment-<name>` | `cma-onprem-environment-<name>` |
| 데이터베이스 비밀번호가 담긴 Secret     | `cma-server-db`                 | `cma-onprem-db`                 |
| 추론 공급자의 자격 증명이 담긴 Secret   | `cma-server-upstream`           | `cma-onprem-upstream`           |
| 서버 API 키와 암호화 키가 담긴 Secret | `cma-server-keys`               | `cma-onprem-server`             |

`earlierNames`의 값과 관계없이 네임스페이스 이름은 `cma-server`이고, 서버 이미지 이름은 `cma-server-image`입니다.

`egress.mode: gateway`를 설정하는 각 샌드박스 values 파일은 `egress.gateway` 아래에 서버의 두 Service 이름을 지정해야 합니다. 파일에 이름이 없으면 두 줄을 모두 추가하세요. 이 예에는 `earlierNames: true`를 사용하는 설치의 이름이 들어 있습니다:

```yaml
egress:
  gateway:
    serverService: cma-onprem
    serverEgressService: cma-onprem-egress
```

### Docker Compose: 아카이브의 구성 및 경로

업그레이드하기 전의 릴리스에 `compose` 디렉터리가 없으면, 해당 릴리스의 `docker-compose.yml`은 아카이브의 최상위에 `bin` 옆에 있습니다. 새 아카이브에서는 이 파일이 한 단계 더 깊은 `compose`에 있습니다.

"다른 변경 사항 다시 적용" 단계에서 다음 변경 사항도 적용하세요:

* **직접 만든 Compose 파일:** 이전 아카이브에 `compose` 디렉터리가 없었다면 파일도 한 단계 더 깊은 곳으로 이동합니다. 파일 안의 `./bin`과 같은 경로는 `../bin`이 됩니다. 파일에서 `cma-onprem` 서비스를 지정하고 있다면 해당 이름을 `cma-server`로 변경하세요.
* **`/etc/cma-onprem/` 또는 `/run/cma-onprem/` 아래의 경로:** 각 경로가 `/etc/cma-server/` 또는 `/run/cma-server/`로 시작하도록 변경하세요. 새 릴리스의 `.env`와 `compose.config.yaml`, 직접 만든 Compose 파일, 그리고 추가한 각 `volumes:` 줄을 확인하세요. `volumes:` 줄에서는 첫 번째 콜론 뒤의 부분, 즉 컨테이너 내부의 경로만 변경하세요.
