> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Compose 파일에서 샌드박스 생성

> 샌드박스 API에 도커 Compose 파일을 업로드하여 다중 컨테이너 샌드박스를 시작합니다.

`POST /v1/sandboxes:createFromFile`는 업로드된 파일에서 샌드박스를 시작합니다. 파일 유형과 파일 바이트를 전송하면, 샌드박스 게이트웨이가 문서를 샌드박스 사양으로 변환하고 `POST /v1/sandboxes`와 동일한 생성 경로를 실행합니다.

도커 Compose(`SANDBOX_FILE_TYPE_COMPOSE`)가 유일하게 허용되는 파일 유형입니다. 파일의 모든 서비스는 단일 샌드박스의 컨테이너가 되며, 사용자가 지정한 하나의 서비스가 샌드박스 주 서비스가 됩니다. 게이트웨이는 파일 바이트를 저장하지 않습니다. `GET /v1/sandboxes/{sandboxId}`는 변환된 사양을 반환합니다.

이것은 도커 Compose와 동등하지 않습니다. 기존 프로젝트를 임포트하기 전에 [Compose 지원](#compose-support)를 읽어보십시오.

<h2 id="before-you-begin">
  시작하기 전에
</h2>

다음 예시에서는 Forge API 키를 사용합니다. 자세한 내용은 [시작하기](/ko/products/sandboxes/get-started)를 참조하세요. 키는 `x-wandb-api-key` 헤더에 담아 전송하세요. 기본 entity가 아닌 다른 Forge entity에 샌드박스를 생성하려면 `x-entity-id`도 함께 전송하세요.

```bash theme={"system"}
export FORGE_API_KEY="[FORGE-API-KEY]"
```

CKS 배치를 포함하여 `SANDBOX_USER` 액션이 있는 CoreWeave API 액세스 토큰을 사용할 수도 있습니다. [사용자 인증 정보 선택 및 조회](/ko/products/sandboxes/placement#choose-and-get-credentials)의 안내에 따라 진행한 다음 토큰을 설정하세요.

```bash theme={"system"}
export CWSANDBOX_API_KEY="[API-ACCESS-TOKEN]"
```

해당 토큰을 사용하려면 이 가이드의 모든 요청에서 `-H "x-wandb-api-key: $FORGE_API_KEY"`를 `-H "Authorization: Bearer $CWSANDBOX_API_KEY"`로 바꾸세요. 인증 방식과 오류 형식은 다른 API와 동일합니다. 자세한 내용은 [API 개요](/ko/products/sandboxes/reference/control-plane-api)를 참조하세요.

<h2 id="request-fields">
  요청 필드
</h2>

| 필드 | 필수 | 설명 |
| - | - | - |
| `type` | 예 | 문서 종류입니다. `SANDBOX_FILE_TYPE_COMPOSE`를 사용하세요. |
| `contents` | 예 | JSON에서 base64로 인코딩된 파일 바이트입니다. UTF-8, 최대 256KiB입니다. |
| `primaryService` | 예 | 샌드박스의 주 서비스가 되는 서비스입니다. `contents`에 정의된 서비스 이름을 지정해야 합니다. 기본값은 없습니다. |
| `imageOverrides` | 아니요 | 서비스별 이미지 참조입니다. 키는 파일에 정의된 서비스 이름이어야 합니다. 원래는 빌드가 필요한 서비스에 pull 가능한 이미지를 제공하려면 이 필드를 사용하세요. |
| `defaultResources` | 조건부 | `deploy.resources`를 생략한 각 서비스에 복사되는 CPU 및 메모리 값입니다. 프로젝트 budget이 아니라 컨테이너별 값입니다. 여기에 GPU를 지정하면 거부됩니다. 파일에 서비스가 두 개 이상 있고 그중 하나라도 `deploy.resources`를 생략한 경우 필수입니다. |

이 요청에는 `mode`, `maxLifetimeSeconds`, `tags`, `network`, `objectStorageAccess`, `annotations`, `runnerIds`, `requestId`도 지정할 수 있으며, 각 필드의 의미는 `POST /v1/sandboxes`와 동일합니다. `networkIds`를 지정하면 `UNIMPLEMENTED`가 반환됩니다.

CKS에 배치하려면 CoreWeave API 액세스 토큰을 사용하고, [샌드박스 배치 및 스필오버](/ko/products/sandboxes/placement)에 설명된 대로 배치 필드를 설정하세요. 객체 저장소 사전 요구 사항은 [샌드박스에 AI Object Storage 액세스 권한 부여](/ko/products/sandboxes/operations/object-storage-access)를 참조하세요.

이 필드 목록 외의 필드는 지원되지 않습니다. 볼륨, instance type, 런타임 클래스, 이미지 pull 사용자 인증 정보, 게시된 서비스는 이 엔드포인트에서 사용할 수 없습니다. 이러한 항목이 필요하면 `POST /v1/sandboxes`를 사용하세요.

<h2 id="create-the-sandbox">
  샌드박스 만들기
</h2>

Compose 파일을 작성하세요:

```bash title="Write compose.yaml" theme={"system"}
cat > compose.yaml <<'EOF'
services:
  helper:
    image: docker.io/library/busybox:1.36
    command: ["sleep", "3600"]
    expose: ["8080"]
    healthcheck:
      test: ["CMD", "true"]
      interval: 1s
      timeout: 1s
      retries: 3
  main:
    image: docker.io/library/busybox:1.36
    command: ["sleep", "3600"]
    environment:
      HELPER_HOST: helper
    depends_on:
      helper:
        condition: service_healthy
EOF
```

`contents`를 base64로 인코딩하여 POST 요청으로 전송하세요:

```bash title="Create a sandbox from compose.yaml" theme={"system"}
jq -n --rawfile yaml compose.yaml '{
  type: "SANDBOX_FILE_TYPE_COMPOSE",
  contents: ($yaml | @base64),
  primaryService: "main",
  defaultResources: { requests: { cpu: "100m", memory: "128Mi" } },
  maxLifetimeSeconds: 3600,
  tags: ["from-file"]
}' | curl -sS -X POST https://api.cwsandbox.com/v1/sandboxes:createFromFile \
  -H "x-wandb-api-key: $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d @-
```

응답은 `STATE_CREATING` 상태의 샌드박스입니다. `STATE_RUNNING` 또는 종료 상태에 도달할 때까지 해당 `sandboxId`를 폴링하세요:

```bash title="Poll the sandbox" theme={"system"}
export SANDBOX_ID="[SANDBOX-ID]"

curl -sS "https://api.cwsandbox.com/v1/sandboxes/$SANDBOX_ID" \
  -H "x-wandb-api-key: $FORGE_API_KEY"
```

반환된 사양에는 컨테이너가 두 개 있으며, `main`은 주 컨테이너로 표시되고 `HELPER_HOST`는 여전히 `helper`로 설정되어 있습니다. 샌드박스 내부에서 `helper`는 `127.0.0.1`로 해석됩니다.

생성을 안전하게 재시도하려면 `requestId`를 보내세요. 동일한 `requestId`와 동일하게 선언된 입력을 보내면 기존 샌드박스가 반환됩니다. 동일한 `requestId`에 공백만 변경한 경우를 포함하여 다른 바이트를 보내면 사유가 `CWSANDBOX_REQUEST_ID_CONFLICT`인 `ALREADY_EXISTS`가 반환됩니다.

<h2 id="compose-support">
  Compose 지원
</h2>

모든 서비스는 하나의 파드와 하나의 네트워크 namespace를 공유합니다. 서비스 이름은 `127.0.0.1`로 확인되므로 `HELPER_HOST: helper` 및 `API_BASE: http://main:8080`과 같은 값은 파일을 다시 작성하지 않고도 작동합니다. 샌드박스에는 서비스별 IP 주소, 브리지 네트워크 또는 레플리카가 없습니다.

다음 동작은 도커 Compose와 다릅니다:

* **시작은 순차적입니다.** primary가 아닌 모든 서비스는 primary 서비스보다 먼저 하나씩 시작됩니다. 이를 위해 `maxLifetimeSeconds`를 설정하세요. 준비되지 않는 서비스는 샌드박스를 `STATE_CREATING` 상태로 남겨둡니다.
* **`RUNNING`은 primary 서비스만 추적합니다.** 시작 후 크래시가 발생한 헬퍼는 샌드박스를 실패로 만들지 않습니다.
* **`healthcheck`는 exec 전용 시작 프로브가 됩니다.** `test`는 문자열, `CMD`, `CMD-SHELL` 또는 `NONE`이어야 하며, 지속 시간은 정수 초여야 합니다. 프로브가 재시도 횟수를 모두 소진하면 컨테이너는 unhealthy로 표시되지 않고 중지됩니다.
* **포트는 파드에 남아 있습니다.** `expose`와 `ports`는 수신 포트를 선언하지만 외부에 게시되지는 않습니다.
* **이미지는 pull 가능해야 합니다.** 모든 서비스는 파일에 `image:`가 있거나 `imageOverrides`에 항목이 있어야 합니다. 여전히 `build:`가 필요한 서비스는 `UNIMPLEMENTED`를 반환합니다.
* **`command`와 `entrypoint`는 도커의 shell 및 exec 형식을 따릅니다.** 생략하면 이미지 기본값을 사용합니다. 명시적인 `null`과 `[]`은 거부됩니다.
* **GPU는 primary 서비스 전용**이며, `gpu` 기능과 양의 정수 개수를 가진 `deploy.resources.reservations.devices`를 통해 할당됩니다.
* **이름은 DNS-1123 레이블**(`my-app`, `My_App`이 아님)이어야 하며, 예약된 `cw-object-store-agent`, `cw-object-store-agent-restore` 또는 `dns-egress` 접두사를 사용할 수 없습니다.

<h3 id="unsupported-keys">
  지원되지 않는 키
</h3>

문서는 자체 포함되어야 합니다: 게이트웨이는 디스크를 읽지 않으며 환경을 확장하지 않습니다. 인식되지 않는 키는 무시되는 대신 문제가 되는 필드 경로와 함께 거부됩니다.

| 거부됨 | 참고 |
| - | - |
| `$VAR` 및 `${VAR}` 보간 | 리터럴 `$`는 `$$`로 작성하세요. |
| `include`, `extends`, `env_file` | `environment` 또는 `env`만 인라인으로 작성하세요. 베어 키와 `null` 값도 거부됩니다. |
| `volumes`, `tmpfs`, `configs`, `secrets`, 바인드 마운트 | 명명된 볼륨 프로젝트는 임포트할 수 없습니다. |
| `restart`, `logging`, `profiles`, `stdin_open`, `tty`, `scale` | 이 런타임에서는 구현되지 않았습니다. |
| `network_mode`, `pid`, `ipc`, `extra_hosts`, 명명된 네트워크 | 하나의 파드, 하나의 namespace. |
| 호스트-컨테이너 포트 매핑, 바인드 주소, 포트 범위, 비-TCP 프로토콜, 서비스 간 중복 포트 | 엔트리당 하나의 TCP 수신 포트, 샌드박스 전체에서 고유해야 합니다. |
| `depends_on: service_completed_successfully` 또는 primary를 대상으로 하는 모든 `depends_on` | `service_healthy`와 `service_started`는 non-primary 서비스 간에 지원됩니다. |
| Compose 메모리 표기(`512m`, `2g`, `512mb`) | `512Mi` 또는 `1Gi`와 같은 Kubernetes 수량을 사용하세요. |
| 명명된 `user` 값(`nobody`) | 숫자 UID를 사용하세요. |

게이트웨이는 `version`, 프로젝트 `name`, `labels`, `x-*` 확장 키를 무시합니다. `labels`가 샌드박스에 도달할 것이라고 기대하지 마십시오.

<h2 id="common-errors">
  일반적인 오류
</h2>

필드 위반은 경로와 제한을 명시하는 `BadRequest` 세부 정보로 도착합니다. 문서를 인용하지 않습니다.

| 상황 | 코드 및 이유 | 필드 |
| - | - | - |
| `type` 누락 | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST` | `type` |
| Compose 이외의 유형 | `UNIMPLEMENTED`, `CWSANDBOX_NOT_IMPLEMENTED` | `type` |
| `primaryService` 누락 또는 알 수 없음 | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST` | `primary_service` |
| `image:` 또는 `build:`가 없는 서비스 | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST` | `contents.services.<name>` |
| `build:`가 필요한 서비스 | `UNIMPLEMENTED`, `CWSANDBOX_NOT_IMPLEMENTED` | `contents.services.<name>.build` |
| 256 KiB를 초과하는 파일 또는 단일 UTF-8 YAML 문서가 아닌 경우 | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST` | `contents` |
| 지원되지 않는 Compose 키 | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST` | 키 경로 |
| 동일한 `requestId`, 다른 바이트 | `ALREADY_EXISTS`, `CWSANDBOX_REQUEST_ID_CONFLICT` | 없음 |

<h2 id="see-also">
  참고
</h2>

* [시작하기](/ko/products/sandboxes/get-started): 첫 번째 샌드박스를 사양에서 생성하세요.
* [API 개요](/ko/products/sandboxes/reference/control-plane-api): 인증, 버전 관리 및 오류 처리.
* [샌드박스 환경 변수](/ko/products/sandboxes/environment-variables): 플랫폼이 모든 컨테이너에 주입하는 내용.
