Environments & previews
Each environment is a full, isolated copy of your project: its own variables, data, addresses, and private network. Use them to test before production, and let every pull request get one of its own.
Environments
Every project starts with production and staging. Create more on the project’s Environments page — for example qa or demo; a project can have up to 50. Services are defined once for the project and deployed to each environment separately, so staging can run a newer release than production.
apprail envs shop
apprail deploy shop/web --image ghcr.io/acme/web:1.5 --env stagingData doesn’t cross environments: a database created in staging is only reachable from staging’s services, and production’s variables are never visible to staging.
Promote from staging to production
Promotion deploys the exact release that is live in one environment to another — the same image digest and settings, nothing rebuilt — so what you tested is what ships. Each environment keeps its own variables.
apprail promote shop/web --from staging --to productionProtect production
An owner or admin can turn on Require approval for an environment. From then on, a deployment there waits unless an owner or admin started it while signed in to the console. Everything else waits for a person:
- API tokens of every kind — CI, coding agents, even an owner’s own token;
- git pushes and the builds they start;
- developers, even in the console;
- deploys, promotions, rollbacks, settings changes, and rebuilds alike.
A waiting deployment changes nothing; the live release keeps serving. Owners and admins see who asked, through what, and exactly what would change — image, commit, settings, which variables changed — and approve or reject it in the console. Alert channels get an Approval needed message. Only the newest waiting request per service is kept.
apprail deploy says it is waiting and keeps following, so a CI job blocks until someone decides; --detach leaves it waiting.
Approving, rejecting, and turning protection on or off only work for a person in the console. No token — however much access it has — can approve its own deployment or remove the protection. One-off commands in a protected environment are limited to owners and admins in the console too.
Pull-request previews
Turn on Previews in a GitHub-connected service’s settings. Every pull request into the linked branch then gets its own environment, pr-<number>, with its own address. New commits update it; closing the pull request removes it.
| Rule | Why |
|---|---|
| Pull requests from forks are never built | Untrusted code never runs with your project’s variables or registry credentials |
| Variables are copied only from an environment you choose (production or staging), once, when the preview opens | Secrets are never inherited by accident, and later changes don’t leak into old previews |
| A preview expires 14 days after its last commit | Forgotten previews don’t run forever |
| At most 10 open previews per project | Keeps a busy repository within your limits; extra pull requests are skipped |
| No custom domains and no protection on previews | They follow their pull request and use generated addresses |
Removal is thorough and safe: the preview’s instances, builds, deployments, variables, and environment are deleted; other environments and the services themselves are untouched. Failed deployments in previews don’t send alerts.