# Environments

The environments you declare, the labels release steps pick them by, and how they differ from the base file that sandboxes run.

You declare your environments: any names. Staging and production are the usual pair, and nothing treats those names specially. How a build moves between them is the [release](/concepts/promote) under `release:`. `parity check --env <name>` shows what an environment runs.

```yaml
x-keys: &keys
  common: { APP_SECRET: { secret: shop/app-secret } }
environments:
  staging:
    env_groups: *keys
  production:
    env_groups: *keys
    services:
      web:
        replicas: 3
        resources: { requests: { cpu: "1" }, limits: { memory: 4Gi } }
    managed:
      db: { version: "17" }
  acme:
    labels: { fleet: dedicated }
    env_groups: *keys
```

The rest of the file is the base, which sandboxes run. Each environment lists only how it differs.

- **Labels.** `labels: { <key>: <value> }` lets one release step reach several environments: `promote: { labels: { fleet: dedicated } }`. Keys and values are lowercase letters, digits, `-` and `_`.
- **What it can change.** Per service: `replicas`, `resources`, `env` and `expose`. Per env group: its variables. Per managed entry: `version`. Images, commands, ports, health checks and jobs always come from the base, so what a sandbox tested is what runs.
- **Merging** works like Compose override files: maps merge per key, and a list or a scalar replaces the base's.
- **Only what the base declares.** Every service, group, entry and variable named here must exist in the base. A variable only production needs goes in the base as `{ secret: <ref> }`.
- **No `generate:` here.** Staging and production read credentials from the secret store, and `parity check --env` warns about each generated value they would still use.
- **Consecutive environments match.** Use the same secret refs in each; each environment reads its own values. `parity check` warns when two environments promoted one after the other differ.
- **Limits.** At most 25 environments, since each runs a full stack. Names are lowercase letters, digits and `-`, at most 20 characters. `sandbox` is taken.

`branch`, `from`, `auto` and `promote` are refused: list `- promote: <environment>` under `release.steps`, with a `- block:` step and its `prompt` before it where a person confirms.
