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

# Custom Runtimes

Use a **custom runtime** when the official Charm base images are not enough — extra system packages, pre-baked models, a private fork of `charmos`, or a **third-party adapter/telemetry/memory plugin** baked into the image.

`runtime.custom_image` tells the cloud runner which container image to pull. When set, it **overrides** the default adapter→image mapping from [Base Images](/platform/base-images).

## When you need this

| Goal                                | Typical setup                                                                       |
| ----------------------------------- | ----------------------------------------------------------------------------------- |
| Extra Python/system deps only       | `type: custom` + `custom_image`                                                     |
| Third-party adapter plugin          | `type: your_plugin` + `custom_image` with plugin installed                          |
| Telemetry plugin on cloud           | Typically **no custom\_image needed** (runner auto-installs via `requirements.txt`) |
| Private or pinned `charmos` version | Extend base image and install your SDK build                                        |

You do **not** need `custom_image` for a normal `charm init` Python agent that runs on the default `runner-base` image.

## 1. Create a Dockerfile

Extend the official base image:

> \[!WARNING]
> **You must inherit from an official Charm base image.** The cloud runner injects a bootstrap script and expects `bash`, `python3`, and the core `charmos` SDK to be pre-installed. Do not build from scratch (e.g., `FROM ubuntu` or `FROM python:3.11`).

```dockerfile theme={"theme":{"light":"min-light","dark":"min-dark"}}
FROM ghcr.io/charmaios/charm-base:latest

# System dependencies (example)
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg \
    && rm -rf /var/lib/apt/lists/*

# Third-party plugin packages (examples)
RUN uv pip install charm-adapter-ag2 charm-telemetry-datadog
```

Build and push to a registry the runner can reach:

> \[!CAUTION]
> **Always build for `linux/amd64`**. The cloud runners (Google Cloud Run / Fly.io) run on `amd64` architecture. If you are on an Apple Silicon Mac (M1/M2/M3) and build without the `--platform linux/amd64` flag, your agent will crash with an `exec format error`.

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
docker build --platform linux/amd64 -t ghcr.io/your-org/my-agent-runtime:prod .
docker push ghcr.io/your-org/my-agent-runtime:prod
```

For Google Artifact Registry:

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
gcloud auth configure-docker us-central1-docker.pkg.dev
docker tag ghcr.io/your-org/my-agent-runtime:prod \
  us-central1-docker.pkg.dev/YOUR_PROJECT/charm-images/my-agent-runtime:prod
docker push us-central1-docker.pkg.dev/YOUR_PROJECT/charm-images/my-agent-runtime:prod
```

## 2. Declare the image in `charm.yaml`

```yaml theme={"theme":{"light":"min-light","dark":"min-dark"}}
version: "0.4.2"

persona:
  name: "My Custom Agent"
  description: "Runs on a custom runtime image"
  version: "0.1.0"

interface:
  input:
    type: object
    required: [input]
    properties:
      input: { type: string }
  output:
    type: string

runtime:
  custom_image: "ghcr.io/your-org/my-agent-runtime:prod"
  adapter:
    type: custom
    entry_point: src.main:agent
  lifecycle: serverless
```

The runner bundles your **agent source code** at execute time; the **image** supplies the environment (Python deps, plugins, system libs).

## 3. Publish and run

```bash theme={"theme":{"light":"min-light","dark":"min-dark"}}
charm validate .
charm push .
```

Users trigger runs from the Store; the runner pulls `custom_image` and executes your bundle inside that container.

## Registry access

| Registry visibility        | Requirement                                                             |
| -------------------------- | ----------------------------------------------------------------------- |
| Public (GHCR public, etc.) | Runner pulls without extra IAM                                          |
| Private                    | Grant the cloud runner service account **read** access to your registry |

> **Note on dynamic installation**: The cloud runner **does** run `uv pip install -r requirements.txt` at boot time for lightweight dependencies (like Telemetry and Memory plugins). However, if your agent requires heavy ML packages, long compile times, or system-level dependencies (like `ffmpeg`), you **must** use a `custom_image` to avoid the 300-second boot timeout.

## Community Plugins

You can discover custom runtimes built by the community in the **Charm Store (Plugins Tab)**.

If you have built a custom runtime that others might find useful (e.g., an image pre-configured with Chromium, specialized ML models, or custom data pipelines), you can submit it to the official registry:

1. Fork the [charm-community-plugin](https://github.com/CharmAIOS/charm-community-plugin) repository.
2. Edit `runtimes/registry.json` to include your image's metadata and URL.
3. Submit a Pull Request.

Once merged, your runtime will instantly appear in the Charm Store for others to use via the `custom_image` field.

## Related

* [Extensibility Overview](/guides/extensibility)
* [Custom Adapters](/guides/custom-adapters)
* [Base Images](/platform/base-images)
