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

# Launch a Run

> Submit Python, Docker, or Docker Compose workloads

Lyceum Cloud accepts three execution types: **Python**, **Docker image**, and **Docker Compose**. Pick the one that matches how your code is packaged.

| You have...                                  | Use            |
| -------------------------------------------- | -------------- |
| A `.py` script and a `requirements.txt`      | Python         |
| A container image (public or private)        | Docker image   |
| A multi-service stack (`docker-compose.yml`) | Docker Compose |

All three submission paths return an `execution_id` plus a streaming URL. From that point on you read logs, fetch results, and abort through the same set of endpoints, see [Runs](/docs/serverless/runs).

## Choosing a hardware profile

Every run targets a **hardware profile** (e.g. `cpu`, `gpu.a100`, `gpu.h100`). You can only launch on profiles your account is authorised for. Three endpoints help you check what's available:

| Endpoint                              | Returns                                |
| ------------------------------------- | -------------------------------------- |
| `GET /machine-types`                  | The full catalogue with hourly pricing |
| `GET /user/quotas/available-hardware` | Just the profiles your account can use |
| `GET /resources/available-resources`  | Detailed hardware specs and pricing    |

If a profile you need isn't listed, contact [support@lyceum.technology](mailto:support@lyceum.technology).

## Python

Python is the most common entry point. The CLI handles packaging your script, bundling local imports, and installing pip requirements before the code runs. The `.lyceum/config.json` workspace file lets you persist requirements and import paths so you don't need to repeat them on every invocation.

<Tabs>
  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    lyceum python run script.py --machine gpu.a100 --requirements requirements.txt
    ```

    | Flag                           | Description                                           |
    | ------------------------------ | ----------------------------------------------------- |
    | `-m`, `--machine`              | Hardware profile (`cpu`, `gpu.a100`, `gpu.h100`, ...) |
    | `-r`, `--requirements`         | Path to a `requirements.txt`                          |
    | `-f`, `--file-name`            | Display name for the run                              |
    | `--import`                     | Local imports to bundle                               |
    | `--use-config` / `--no-config` | Toggle reading `.lyceum/config.json`                  |
    | `-d`, `--debug`                | Enable debug logging                                  |

    Manage the workspace config (`.lyceum/config.json`) for shared dependencies and import paths:

    ```bash theme={null}
    lyceum python config init      # create
    lyceum python config show      # print current config
    lyceum python config refresh   # regenerate
    ```
  </Tab>

  <Tab title="REST API" icon="play">
    ```http theme={null}
    POST /api/v2/external/execution/streaming/start
    ```

    Body fields include `code` (the Python source as a string), `machine_type`, optional `requirements`, `imports`, and other execution options. Returns `execution_id` and `stream_url`.
  </Tab>
</Tabs>

## Docker image

Use Docker when your environment is already containerised, for example a CUDA image with preinstalled dependencies, or a job that doesn't fit the Python entrypoint cleanly. The platform pulls the image, runs the command you specify, and streams stdout/stderr back.

For private registries, the request supports two credential modes:

* **Basic auth**, username and password for any registry
* **AWS**, access key, secret key, session token, and region for Amazon ECR

<Tabs>
  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    lyceum docker run python:3.11-slim -c "python -c 'print(1)'" -m cpu
    ```

    | Flag               | Default   | Description                                                                                                |
    | ------------------ | --------- | ---------------------------------------------------------------------------------------------------------- |
    | `-c`, `--command`  | —         | Command to run inside the container                                                                        |
    | `-e`, `--env`      | —         | Environment variable, e.g. `KEY=value` (repeatable)                                                        |
    | `-m`, `--machine`  | `cpu`     | Machine type                                                                                               |
    | `--s3` / `--no-s3` | on        | Mount your storage bucket inside the container                                                             |
    | `--s3-mount-path`  | `/mnt/s3` | Where to mount the bucket inside the container                                                             |
    | `--callback`       | —         | Webhook URL for completion notification                                                                    |
    | `--registry-creds` | —         | Private registry auth as a JSON string (see [Private registry credentials](#private-registry-credentials)) |
    | `--registry-type`  | —         | Registry credential type (`basic`, `aws`)                                                                  |

    By default the bucket is mounted at `/mnt/s3` inside the container.
  </Tab>

  <Tab title="REST API" icon="play">
    ```http theme={null}
    POST /api/v2/external/execution/image/start
    ```

    Body: `docker_image_ref`, `docker_run_cmd`, `docker_run_env`, `machine_type`, and `docker_registry_credential_type` (`basic` or `aws`) plus the matching credential fields when needed. For ECR pass `aws_access_key_id`, `aws_secret_access_key`, `aws_session_token`, `aws_region`. For other registries pass `docker_username` and `docker_password`. Set `enable_s3_mount: true` to mount your storage bucket (path defaults to `s3_mount_path: "/mnt/s3"`).

    `docker_run_env` is a single string of newline-separated `KEY=VALUE` pairs (`.env` style), for example `"DEBUG=true\nTIMEOUT=300"`. The CLI builds this for you from repeated `-e` flags.
  </Tab>
</Tabs>

### Private registry credentials

Public images (for example `python:3.11-slim` from Docker Hub) need no credentials, just leave them out. A **private** registry requires login details so Lyceum can pull your image. Two modes are supported:

| Mode    | Use for                                                                         | Fields                                        |
| ------- | ------------------------------------------------------------------------------- | --------------------------------------------- |
| `basic` | Docker Hub (private), GHCR, GitLab, self-hosted, any username/password registry | username, password                            |
| `aws`   | Amazon ECR                                                                      | access key, secret key, session token, region |

<Note>
  `--registry-creds` and `--registry-type` must always be passed together. A Kubernetes-style `.dockerconfigjson` is not supported; use the JSON shapes below.
</Note>

<Tabs>
  <Tab title="CLI" icon="terminal">
    The `--registry-creds` value is a JSON string whose keys depend on `--registry-type`:

    ```bash theme={null}
    # Basic auth (any username/password registry)
    lyceum docker run myregistry.io/team/app:tag -m cpu \
      --registry-type basic \
      --registry-creds '{"username": "me", "password": "••••••"}'

    # AWS ECR
    lyceum docker run 123456.dkr.ecr.eu-central-1.amazonaws.com/app:latest -m gpu.a100 \
      --registry-type aws \
      --registry-creds '{"aws_access_key_id": "AKIA…", "aws_secret_access_key": "••••", "aws_session_token": "••••", "region": "eu-central-1"}'
    ```

    | Type    | Required JSON keys                                                                                    |
    | ------- | ----------------------------------------------------------------------------------------------------- |
    | `basic` | `username`, `password`                                                                                |
    | `aws`   | `aws_access_key_id`, `aws_secret_access_key`, `aws_session_token`, `region` (defaults to `us-east-1`) |
  </Tab>

  <Tab title="REST API" icon="play">
    In the request body the fields are flat, not nested in a JSON string. Set `docker_registry_credential_type`, then the matching fields:

    ```json theme={null}
    // Basic auth
    {
      "docker_image_ref": "myregistry.io/team/app:tag",
      "docker_registry_credential_type": "basic",
      "docker_username": "me",
      "docker_password": "••••••"
    }
    ```

    ```json theme={null}
    // AWS ECR
    {
      "docker_image_ref": "123456.dkr.ecr.eu-central-1.amazonaws.com/app:latest",
      "docker_registry_credential_type": "aws",
      "aws_access_key_id": "AKIA…",
      "aws_secret_access_key": "••••",
      "aws_session_token": "••••",
      "aws_region": "eu-central-1"
    }
    ```
  </Tab>
</Tabs>

<Warning>
  The region key differs by interface: the CLI JSON uses `region`, the REST body uses `aws_region`.
</Warning>

## Docker Compose

For multi-service stacks (e.g. an app talking to a database) you can submit a whole `docker-compose.yml`. The platform brings up all services on the same machine and tears them down when the entrypoint service exits.

<Tabs>
  <Tab title="CLI" icon="terminal">
    ```bash theme={null}
    lyceum compose run docker-compose.yml --machine gpu.a100
    ```

    | Flag              | Description                  |
    | ----------------- | ---------------------------- |
    | `-m`, `--machine` | Hardware profile             |
    | `--env-file`      | Env file passed to the stack |
  </Tab>

  <Tab title="REST API" icon="play">
    ```http theme={null}
    POST /api/v2/external/execution/compose/start
    ```

    Body: the `compose_file_code` as a string and a `machine_type`.
  </Tab>
</Tabs>

## Aborting

Each execution type has its own abort endpoint. Use `abort` to immediately kill a run; for graceful stop (notebooks, interactive sessions), use `POST /workloads/stop/{execution_id}` instead.

```http theme={null}
POST /execution/streaming/abort/{execution_id}
POST /execution/image/abort/{execution_id}
POST /execution/compose/abort/{execution_id}
```

## See also

<Columns cols={2}>
  <Card title="Worked examples" icon="terminal" href="/examples/python-basics">
    Real CLI and curl invocations for Python and Docker runs.
  </Card>

  <Card title="Runs" icon="list" href="/docs/serverless/runs">
    Monitor, log, and abort executions after they're submitted.
  </Card>
</Columns>
