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

# Capsules

> How a preview environment per branch is created, updated, scheduled and removed, and what each one gets

A **capsule** is a preview environment for one git branch. Every branch you push gets its own copy of your app, deployed by Monk from the same `MANIFEST` as your other environments, with its own URL. GitHub Actions creates it when the branch is pushed, updates it on every later push and removes it when the branch's pull request closes.

The point of a capsule is isolation. Two branches, or two coding agents working on two branches, run separate copies of the app and don't read or write each other's data. A reviewer opens a running app instead of reading a diff, and a coding agent can test its change against real services before it hands the pull request over.

Capsules are part of the Pro plan and above. See [monk.io/pricing](https://monk.io/pricing).

## What runs a capsule

Monk sets capsules up once and then GitHub Actions runs them. Setup:

1. writes `.github/workflows/dynenv.yml`, a workflow named "Monk Capsules" built on Monk's GitHub Actions (`monk-io/monk-actions`)
2. creates an API key scoped to the project, valid for 365 days
3. stores the key, your cloud credentials (in cloud mode) and the values of your `MANIFEST` secrets in a GitHub environment, `monk-capsules` by default
4. allows GitHub Actions to open pull requests in the repository

You review all of it in the local dashboard before anything is created or pushed, then commit and push the workflow yourself. From that point Monk isn't involved in each run: the workflow talks to Monk's platform with the stored key and to the capsule's cluster with short-lived tokens it creates per run.

See [Set up preview environments](/guides/preview-environments) for the steps.

## Two modes

| | Cloud mode (default) | Cluster mode |
| - | - | - |
| Where a capsule runs | A new cluster per branch, in the cloud account, region and machine type you choose | A pool of nodes on one existing cluster, shared by every branch |
| Isolation | Its own nodes, volumes, domain, ingress and container registry | Its own workloads and secrets, on shared nodes |
| Preview URL | One per branch | Branches share the nodes' domain, so only one branch's web service is reachable |
| Starts | Slower: a new cluster is provisioned for each branch | Faster: the nodes are already running |
| Cost | A cluster per active branch | The nodes you already pay for |
| Good for | Anything with a web front end | Workers and APIs reached by internal address |

Cloud mode works on AWS, GCP, Azure and DigitalOcean. Cluster mode uses the nodes tagged with a pool tag (`capsule-pool` by default); setup tags the cluster's nodes for you unless you say otherwise. A shared cluster can serve one project only.

## Lifecycle

| Event | What the workflow does |
| - | - |
| Push to a branch | Creates the capsule if it doesn't exist (a cluster in cloud mode), builds the `MANIFEST` images, deploys, and records the preview URL. It also opens a pull request titled `[capsule] <branch>` if the branch has none. |
| Another push to the same branch | Rebuilds the images and updates the same capsule in place. |
| Pull request into the base branch closed or merged | Removes the capsule and its records. |
| Run by hand from the Actions tab | One of `provision_deploy`, `deploy`, `deprovision` or `destroy`, for any branch. |

The base branch you ran setup from, `main` and `master` don't get capsules. A push to them does nothing.

Deleting a branch without closing its pull request doesn't remove the capsule. Close the pull request, or run the workflow with `destroy`.

### Manual actions

* **`provision_deploy`:** the same as a push. Creates the capsule if needed, then builds and deploys.
* **`deploy`:** rebuilds and deploys to an existing capsule without touching its infrastructure.
* **`deprovision`:** deletes the capsule's cluster, volumes and snapshots, and keeps its record so it can be created again later. This is what a schedule uses to take a capsule down.
* **`destroy`:** everything `deprovision` does, plus the capsule's records and its GitHub deployment.

## What each capsule gets

* **A name from the branch.** The branch is lowercased and anything outside `a-z`, `0-9` and `-` becomes `-`, so `feat/Search` becomes `feat-search`. That is the name of the capsule's environment in Monk, and the deploy sets the `environment` variable of your app's entry workload to it.
* **Its own cluster** in cloud mode, named `<prefix>-<branch>`, where the prefix defaults to the workspace folder name.
* **Your `MANIFEST` secrets**, copied from the GitHub environment into the capsule on every provision.
* **A preview URL.** If your templates define an endpoints entity for the entry workload, its URL is used. Otherwise it is the cluster's domain, with a generated certificate.
* **A GitHub deployment** named `capsule-<branch>`, with the preview URL, so the link shows in GitHub.

### What is shared between branches

Everything inside the capsule's cluster is per branch in cloud mode. Anything your templates create **outside** the cluster, such as a managed database, a bucket, a DNS record or a queue, is shared by every branch unless its name is built from `environment`. With a fixed name, the first capsule to start owns the resource and the others use it.

When Monk prepares a project for capsules, your coding agent sets `environment` once on the entry group, with your default branch as its value, and builds every outside name from it, for example `shop-${environment}` for a managed database. Setup warns when a member of the group declares its own `environment`, because that member would keep the default on every branch.

Production data is not copied into a capsule. A new capsule starts with empty databases, or whatever your templates seed.

## Schedules

A schedule keeps capsules up only when people use them. It has:

* a timezone
* rules, each saying when capsules are up or down: a daily window, a weekly window on chosen weekdays, or a calendar override for a date or date range
* a default state for times no rule covers

The project's schedule applies to every capsule. One capsule can have its own schedule instead, and can go back to following the project's. The workflow checks every hour and takes capsules down or brings them back to match, so a change can take up to an hour to apply, and GitHub doesn't run scheduled workflows at an exact time.

> [!WARNING]
>
> Taking a capsule down deletes its cluster with its volumes and snapshots. When it comes back up it is provisioned again from the branch, with fresh data.

You can change schedules by asking Monk, which asks for approval in the local dashboard, or in the web dashboard, under the project's Previews tab and on a preview's page.

## Which branches get capsules

Besides the branches excluded at setup, the project's settings in the web dashboard (Previews, "How previews work here") can:

* turn capsules off for the project
* limit them to some branches (**Only these branches**)
* leave some branches out (**Never these branches**)

Branch patterns are globs such as `feature/*`. The workflow reads these settings on every push, so a change applies to the next push without editing the workflow.

## Secrets

Capsule secrets are the secrets your `MANIFEST` lists. There are two ways to update them:

* **Global** stores the values in the GitHub environment and updates the workflow to pass every secret, so new capsules get them. Commit and push the updated workflow. It can also refresh the cloud credentials stored in GitHub.
* **Local** writes the values into one running capsule only, right away. Monk needs to be switched to that capsule's cluster.

Values are entered in the local dashboard. Monk never shows them to your coding agent.

## Limits

* The repository has to be on GitHub, and capsules run in GitHub Actions. Other CI systems aren't supported.
* The project needs a `MANIFEST` with an entry workload and at least one image built from your source, and it has to deploy cleanly to a normal cluster first.
* The workspace has to be bound to a project in an organization. Personal projects aren't supported yet.
* Creating a cluster for a branch takes minutes, so the first deploy of a branch is much slower than later pushes.
* Two branch names that become the same name, such as `feat/a` and `feat-a`, share one capsule.
* The project API key lasts 365 days. Run setup again to replace it.
* If the workflow fails, fix what is in your project (templates, `MANIFEST`, secrets, code) and push again. Don't edit `dynenv.yml` by hand: running setup again replaces it. Don't delete a capsule's cluster yourself either, because its records and pull request stay behind.

## Capsules and CI/CD

Capsules give each branch a new environment. [CI/CD](/guides/cicd) deploys one branch to a cluster you already have, on every push. They use different workflows and can be set up in the same repository.

## Related

> **[Set up preview environments](/guides/preview-environments)**
>
> Prepare the project and run setup

> **[Manage preview environments](/guides/manage-preview-environments)**
>
> List, schedule, update secrets, remove

> **[Environments and previews](/concepts/environments-and-previews)**
>
> Projects, workspaces and environments

> **[Clusters and clouds](/concepts/clusters-and-clouds)**
>
> Clusters, node tags and binding


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.