> ## 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.

# Create a sandbox from a Compose file

> Start a multi-container sandbox by uploading a Docker Compose file to the sandbox API.

`POST /v1/sandboxes:createFromFile` starts a sandbox from an uploaded file. You send a file type and the file bytes, and the sandbox gateway translates the document into a sandbox spec and runs the same create path as `POST /v1/sandboxes`.

Docker Compose (`SANDBOX_FILE_TYPE_COMPOSE`) is the only accepted file type. Every service in the file becomes a container in a single sandbox, and one service you name becomes the sandbox primary. The gateway doesn't store the file bytes. `GET /v1/sandboxes/{sandboxId}` returns the translated spec.

This isn't Docker Compose equivalence. Before you import an existing project, read [Compose support](#compose-support).

<Note>
  CoreWeave sandboxes are in public preview. For access, contact your CoreWeave account team, [CoreWeave Support](https://cloud.coreweave.com/contact), or email [support@coreweave.com](mailto:support@coreweave.com).
</Note>

## Before you begin

You need a CoreWeave API access token with the `SANDBOX_USER` action, and serverless sandboxes enabled for your organization. See [Get started with CoreWeave sandboxes](/products/sandboxes/get-started). Authentication and error shapes match the rest of the API. See [API overview](/products/sandboxes/reference/control-plane-api).

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

## Request fields

| Field              | Required    | Description                                                                                                                                                                                                                  |
| ------------------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`             | Yes         | Document kind. Use `SANDBOX_FILE_TYPE_COMPOSE`.                                                                                                                                                                              |
| `contents`         | Yes         | The file bytes, base64-encoded in JSON. UTF-8, max 256 KiB.                                                                                                                                                                  |
| `primaryService`   | Yes         | Service that becomes the sandbox primary. Must name a service in `contents`. No default.                                                                                                                                     |
| `imageOverrides`   | No          | Per-service image references. Keys must name services in the file. Use this to supply a pullable image for a service that would otherwise need a build.                                                                      |
| `defaultResources` | Conditional | CPU and memory copied onto each service that omits `deploy.resources`. Per container, not a project budget. GPU here is rejected. Required when the file has more than one service and any service omits `deploy.resources`. |

The request also accepts `mode`, `maxLifetimeSeconds`, `tags`, `network`, `objectStorageAccess`, `annotations`, `runnerIds`, and `requestId`, with the same meaning as on `POST /v1/sandboxes`. `networkIds` returns `UNIMPLEMENTED`.

This field list is closed. Volumes, instance type, runtime class, image-pull credentials, and published services aren't available on this endpoint. Use `POST /v1/sandboxes` when you need them.

## Create the sandbox

Write a Compose file, then post it with `contents` base64-encoded:

```bash title="Create a sandbox from 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

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.coreweave.com/v1/sandboxes:createFromFile \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @-
```

The response is a sandbox in `STATE_CREATING`. Poll its `sandboxId` until it reaches `STATE_RUNNING` or a terminal state:

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

curl -sS "https://api.coreweave.com/v1/sandboxes/$SANDBOX_ID" \
  -H "Authorization: Bearer $TOKEN"
```

The returned spec has two containers, `main` marked primary, and `HELPER_HOST` still set to `helper`. Inside the sandbox, `helper` resolves to `127.0.0.1`.

To retry a create safely, send `requestId`. The same `requestId` with the same declared inputs returns the existing sandbox. The same `requestId` with different bytes, including a whitespace-only change, returns `ALREADY_EXISTS` with reason `CWSANDBOX_REQUEST_ID_CONFLICT`.

## Compose support

All services share one pod and one network namespace. Service names resolve to `127.0.0.1`, so values such as `HELPER_HOST: helper` and `API_BASE: http://main:8080` work without rewriting the file. The sandbox has no per-service IP addresses, bridge networks, or replicas.

The following behavior differs from Docker Compose:

* **Startup is serial.** Every non-primary service starts one after another, before the primary. Size `maxLifetimeSeconds` for that. A service that never becomes ready leaves the sandbox in `STATE_CREATING`.
* **`RUNNING` tracks the primary only.** A helper that crashes after start doesn't fail the sandbox.
* **`healthcheck` becomes an exec-only startup probe.** `test` must be a string, `CMD`, `CMD-SHELL`, or `NONE`, and durations must be whole seconds. When the probe exhausts its retries, the container is stopped rather than marked unhealthy.
* **Ports stay in the pod.** `expose` and `ports` declare listen ports, but nothing is published externally.
* **Images must be pullable.** Every service needs `image:` in the file or an entry in `imageOverrides`. A service that still needs `build:` returns `UNIMPLEMENTED`.
* **`command` and `entrypoint` follow Docker's shell and exec forms.** Omit them to use the image defaults. Explicit `null` and `[]` are rejected.
* **GPUs are primary-only**, through `deploy.resources.reservations.devices` with the `gpu` capability and a positive integer count.
* **Names must be DNS-1123 labels** (`my-app`, not `My_App`), and can't use the reserved `cw-object-store-agent`, `cw-object-store-agent-restore`, or `dns-egress` prefixes.

### Unsupported keys

The document must be self-contained: the gateway doesn't read your disk and doesn't expand your environment. Unrecognized keys are rejected with the offending field path rather than ignored.

| Rejected                                                                                                         | Notes                                                                               |
| ---------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `$VAR` and `${VAR}` interpolation                                                                                | Write `$$` for a literal `$`.                                                       |
| `include`, `extends`, `env_file`                                                                                 | Inline `environment` or `env` only. Bare keys and `null` values are also rejected.  |
| `volumes`, `tmpfs`, `configs`, `secrets`, bind mounts                                                            | Named-volume projects can't be imported.                                            |
| `restart`, `logging`, `profiles`, `stdin_open`, `tty`, `scale`                                                   | Not implemented on this runtime.                                                    |
| `network_mode`, `pid`, `ipc`, `extra_hosts`, named networks                                                      | One pod, one namespace.                                                             |
| Host-to-container port mappings, bind addresses, port ranges, non-TCP protocols, duplicate ports across services | One TCP listen port per entry, unique across the sandbox.                           |
| `depends_on: service_completed_successfully`, or any `depends_on` targeting the primary                          | `service_healthy` and `service_started` are supported between non-primary services. |
| Compose memory spellings (`512m`, `2g`, `512mb`)                                                                 | Use Kubernetes quantities such as `512Mi` or `1Gi`.                                 |
| Named `user` values (`nobody`)                                                                                   | Use a numeric UID.                                                                  |

The gateway ignores `version`, project `name`, `labels`, and `x-*` extension keys. Don't rely on `labels` reaching the sandbox.

## Common errors

Field violations arrive as `BadRequest` details naming the path and the limit. They don't quote your document.

| Situation                                              | Code and reason                                   | Field                            |
| ------------------------------------------------------ | ------------------------------------------------- | -------------------------------- |
| Omitted `type`                                         | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST`   | `type`                           |
| Type other than Compose                                | `UNIMPLEMENTED`, `CWSANDBOX_NOT_IMPLEMENTED`      | `type`                           |
| Omitted or unknown `primaryService`                    | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST`   | `primary_service`                |
| Service with neither `image:` nor `build:`             | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST`   | `contents.services.<name>`       |
| Service that still needs `build:`                      | `UNIMPLEMENTED`, `CWSANDBOX_NOT_IMPLEMENTED`      | `contents.services.<name>.build` |
| File over 256 KiB, or not a single UTF-8 YAML document | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST`   | `contents`                       |
| Unsupported Compose key                                | `INVALID_ARGUMENT`, `CWSANDBOX_INVALID_REQUEST`   | The key path                     |
| Same `requestId`, different bytes                      | `ALREADY_EXISTS`, `CWSANDBOX_REQUEST_ID_CONFLICT` | None                             |

## See also

* [Get started with CoreWeave sandboxes](/products/sandboxes/get-started): create your first sandbox from a spec.
* [API overview](/products/sandboxes/reference/control-plane-api): authentication, versioning, and error handling.
* [Sandbox environment variables](/products/sandboxes/environment-variables): what the platform injects into every container.
