Deployment
Work with environments
Add a staging environment, fork one from production, or let each pull request open its own preview.
An environment is an isolated slice of your product: its own services, variables, volumes, managed databases and domains. A production environment exists from the moment deployment is connected to your product — you do not create it and you cannot delete it. Every other environment is yours to add and remove.
Where each action lives
| Surface | Environment actions |
|---|---|
| Product App | Create: New environment, at the foot of the Environments list. Rename and reconcile: Environment → Settings → Overview. Preview policy: Environment → Settings → Preview Policy. Start a preview: New preview, in the Previews section of the Environments list. Delete a preview: the banner above its canvas. Fork a persistent environment: —. Delete an environment: —. |
| CLI | Every action on this page: the CLI renders the same operation catalog as MCP. Sign in from the terminal. |
| MCP | Every action on this page. Tool names are linked per section. |
| REST | Every action on this page, under /deployment/environments/…. Browse the endpoints. |
Pick how to create it
| Way in | What you get | Use it when |
|---|---|---|
| Create empty | A named, empty environment. You add services yourself. | The new environment is not a copy of anything you already run. |
| Fork | A deep copy of the shape of a base environment, which deploys itself as soon as the copy is in place. | You want staging to look like production without rebuilding it by hand. |
| Preview | A fork with an automatic lifecycle, created and deleted with a pull request. | You want every pull request reviewed against a running copy. |
The usual shape is a long-lived production, a long-lived staging you validate against, and short-lived preview environments created per pull request.
Create an empty environment
- Call
deployment_environment_createwith a name of up to 80 characters. A slug — a short URL-safe identifier of up to 40 characters — is derived from the name unless you set one yourself. - Wait while it is prepared in the background. It moves through
provisioningtoready. - Add services once it reports
ready. See Set up a service.
The slug is unique within the product, and production is reserved: you cannot claim it for a second environment. Once the environment exists, only its name can be changed — the slug is fixed for its lifetime, so renaming never breaks addresses or scripts.
Statuses
| Status | Meaning |
|---|---|
provisioning | Being prepared; not ready for services yet |
ready | Usable |
provisioning_failed | Preparation failed; the reason is on the environment |
deprovisioning | Being torn down after deletion |
deprovisioning_failed | Teardown failed; the reason is on the environment |
When a status ends in _failed, the environment carries the error message that explains it. deployment_environment_reconcile re-runs the preparation or the teardown from the start; it is the way out of a failed state without recreating anything.
Fork an environment
- Pick a base environment. It has to be
ready. - Call
deployment_environment_forkwith that base and a name for the new environment. - Set the secrets yourself — they are deliberately not carried over.
The fork deploys itself as soon as the copy is in place: every copied service with at least one replica starts a deployment, and every copied database is created. You do not have to press anything.
| Copied | Not copied |
|---|---|
| Every service definition: its type and its source, its port, replica count and health checks | Secrets. Secret keys are not carried over at all — this keeps production credentials out of a staging or preview environment created by someone else |
| Variables at the environment and service levels, as long as they are not secrets | Custom domains. Your own domains stay attached to the environment you connected them to |
| The generated domain of each service, with its routes — the new environment gets its own hostnames | Data. Volumes come up empty and managed databases come up blank |
| Volume definitions: same name, size and mount path, but empty | Deploy history. The new environment starts clean |
| Managed databases: same engine, version and size, created empty with fresh credentials | |
| The layout of the environment canvas, so the copy is recognisable |
Let pull requests open previews
A preview environment is a fork tied to a pull request in the repository your services are built from. It is created from a base environment, given the slug pr-<number> and the name PR #<number>, and it records which pull request and which branch it belongs to. Structurally it is an ordinary environment — same services, same fork rules, including that secrets are not carried over. What differs is that it expires.
Configure it per base environment with deployment_preview_policy_set:
| Setting | Default | Range |
|---|---|---|
| Enabled | on | on / off |
| Maximum live previews | 5 | 1–50 |
| Lifetime | 72 hours | 1–720 hours |
A preview is refused when the policy is disabled for that base, when the maximum is already reached, when a preview for that pull request already exists, or when the base environment is not ready.
While the pull request is open. Every new commit pushed to it redeploys the services in the preview that are built from a repository, and resets the lifetime clock to the full window. A preview that keeps receiving commits keeps living.
When it ends. Closing or merging the pull request schedules the preview for deletion after a fifteen-minute grace period — enough to read the last logs. A preview that nobody touches until its lifetime runs out is deleted the same way. Expired and scheduled environments are collected every few minutes, so teardown begins shortly after the deadline rather than exactly on it. You can also delete a preview yourself at any time with deployment_preview_environment_delete.
What is never shared
Nothing crosses the environment boundary:
- Variables are separate records.
DATABASE_URLinstagingandDATABASE_URLinproductionare two independent values; changing one never changes the other. - Services are separate services, with separate deploy history, domains and storage.
- Volumes and managed databases are separate, with their own data and their own credentials.
- Private networking does not cross the boundary: a service can reach the other services of its own environment, and nothing outside it.
What is shared is the product itself: every environment belongs to exactly one product, and no environment of one product is visible from another.
Delete an environment
The production environment cannot be deleted this way. It goes away only when deployment is disconnected from the product.
Next steps
- Set up a service: fill a new environment with something to run.
- Deploy, redeploy and roll back: what a fork triggers, and how a push reaches a preview.
- Connect a domain: custom domains are added per environment, so
stagingandproductioneach have their own. - Read how deployment works: where an environment sits between a product and a service.