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

# Image, Theme, And Deployment

> Runtime images, theming, filesystems, pricing, and deployment settings.

## `Image`

`cpsl.Image` defines the runtime environment for your app. If the app needs Python packages, system packages, or setup commands, this is where they go.

### Worked example

This is a realistic app-level deployment config:

```python theme={null}
app = cpsl.App(
    name="support-ops",
    image=cpsl.Image(
        python_packages=["openai", "pypdf"],
        apt_packages=["poppler-utils"],
    ),
    secrets=["OPENAI_API_KEY"],
    filesystems={"/data": cpsl.FileSystem("support-ops")},
    keep_warm_seconds=30,
    price=1500,
    pricing_type="monthly",
)

app.theme(
    preset="light",
    accent="#1565C0",
    font_sans="DM Sans, sans-serif",
    tagline="Mailbox triage and support operations",
)
```

This is what makes Capsule feel like an application platform instead of a model wrapper: runtime dependencies, branding, storage, warm behavior, and pricing all live next to the app code.

### Constructor

```python theme={null}
image = cpsl.Image(
    python_packages=["openai", "numpy"],
    apt_packages=["ffmpeg"],
    commands=["python -m spacy download en_core_web_sm"],
)
```

You can also build it up incrementally:

```python theme={null}
image = (
    cpsl.Image()
    .add_python_packages(["openai", "numpy"])
    .add_apt_packages(["ffmpeg"])
    .add_commands(["python -m spacy download en_core_web_sm"])
)
```

### Methods

| Method                          | Purpose                                              |
| ------------------------------- | ---------------------------------------------------- |
| `add_python_packages(packages)` | Add Python packages or load from a requirements file |
| `add_apt_packages(packages)`    | Add apt packages                                     |
| `add_commands(commands)`        | Add shell commands to run during setup               |

`python_packages` can be a list or a path to `requirements.txt`.

## `Theme`

Configure app branding with `app.theme(...)`.

Most apps do not need a fully custom theme. A preset plus a few overrides is usually enough:

```python theme={null}
app.theme(
    preset="midnight",
    accent="#A78BFA",
    font_sans="DM Sans, sans-serif",
    font_mono="DM Mono, monospace",
)
```

### Presets

Built-in presets:

* `dark`
* `light`
* `midnight`
* `warm`

### Common theme fields

| Field             | Meaning                    |
| ----------------- | -------------------------- |
| `preset`          | Starting palette           |
| `logo`            | Path or URL to a logo      |
| `logo_background` | Background behind the logo |
| `tagline`         | Sidebar subtitle           |
| `primary`         | Main interactive color     |
| `accent`          | Accent color               |
| `background`      | Page background            |
| `foreground`      | Main text color            |
| `sidebar`         | Sidebar background         |
| `surface`         | Cards and panels           |
| `border`          | Borders and dividers       |
| `muted`           | Secondary text             |
| `danger`          | Error/destructive color    |
| `success`         | Success color              |
| `font_sans`       | Body font family           |
| `font_mono`       | Code/data font family      |
| `radius`          | `sm`, `md`, or `lg`        |

## `FileSystem`

Use `cpsl.FileSystem("name")` to mount named durable storage into the runtime:

```python theme={null}
app = cpsl.App(
    name="reports",
    image=cpsl.Image(),
    filesystems={"/data": cpsl.FileSystem("reports")},
)
```

The key is the mount path inside the runtime. The value is the named filesystem resource in the workspace.

Once mounted, you can use it like a normal path:

```python theme={null}
with open("/data/summary.txt", "w") as f:
    f.write("hello from capsule\n")
```

## Deployment-related app knobs

### Pricing

Capsule uses cents for pricing:

```python theme={null}
app = cpsl.App(
    name="infra-analyst",
    image=cpsl.Image(),
    price=500,
    pricing_type="monthly",
)
```

Valid pricing types:

* `one_time`
* `monthly`

### Warm runtimes

```python theme={null}
app = cpsl.App(
    name="fast-agent",
    image=cpsl.Image(),
    keep_warm_seconds=30,
)
```

This asks Capsule to keep the runtime warm for a short period after activity.

### Secrets and filesystems

These are deployment config, not runtime afterthoughts:

```python theme={null}
app = cpsl.App(
    name="secure-agent",
    image=cpsl.Image(),
    secrets=["OPENAI_API_KEY"],
    filesystems={"/data": cpsl.FileSystem("reports")},
)
```

That same app could also set a theme, pages, tasks, and integrations. There is no separate deployment manifest hiding elsewhere.

## Class-based deploy config

For class-based apps, the deploy-specific knobs live on `@app.cls(...)` instead of the `App(...)` constructor:

```python theme={null}
@app.cls(
    image=cpsl.Image(),
    price=500,
    pricing_type="monthly",
    keep_warm_seconds=30,
    secrets=["OPENAI_API_KEY"],
    filesystems={"/data": cpsl.FileSystem("reports")},
)
class MyApp:
    ...
```

## See also

* [Custom React Pages](/features/custom-react-pages)
* [Connect Services](/build/connect-services)
* [CLI Reference](/reference/cli)
