# Environment variables

> One shape, three scopes — plain values, secrets declared without their value, and links that resolve at start

URL: https://pier.run/docs/vars

```yaml title="pier.yaml"
environments:
  prod:
    env:                                   # environment scope: every app and site
      LOG_LEVEL: { value: info }
    apps:
      - name: api
        env:                               # app scope: api's targets
          API_KEY: { secret: true }
          DATABASE_URL: { from: postgres.main.url }
          OPTIONAL_FLAG: { value: "1", required: false }
        targets:
          - name: canary
            env:                           # target scope: this target only
              LOG_LEVEL: { value: debug }
```

```bash
pier vars
```

```text title="output"
                                         
 KEY       VALUE    SECRET ENV  UPDATED  
                                         
 API_KEY   ******** yes    prod just now 
 LOG_LEVEL info            prod just now 
                                         

```

## One shape

| Field             | Means                                                                                                         |
| ----------------- | ------------------------------------------------------------------------------------------------------------- |
| `value`           | a plain value, committed with the file                                                                        |
| `secret: true`    | declared here; the value lives in the platform's vault (`pier vars set KEY --secret …`) and never in the file |
| `from`            | a link: `<type>.<name>.<key>`, resolved when the target starts                                                |
| `required: false` | a missing value does not block a deploy (default `true`)                                                      |

Links:

| Type       | Keys                                                  |
| ---------- | ----------------------------------------------------- |
| `postgres` | `url`, `host`, `port`, `user`, `password`, `database` |
| `buckets`  | `url`, `name`, `endpoint`, `access_key`, `secret_key` |

A link may only name a resource in the same environment.

## Three scopes

Environment → app (or site) → target, the narrower winning. `pier vars set K=V` sets the
environment scope; `--app api` the app; `--app api/canary` the target. `pier vars` lists
every scope with its origin.

## How a change reaches the container

A variable change is recorded as a new *environment version*; the values are injected
when a target's container starts. A running container keeps its environment until the
next deploy: `pier deploy api` releases the pending version without a rebuild (the plan
says `deployed inline`), and `pier deploy` with no ref releases every target that is
behind. `pier restart` restarts the running deploy with the environment it was deployed
with: a rotated secret value is picked up, a new version is not. `pier status` lists
targets whose running version is older than the current one. A
[rollback](/docs/guides/roll-back-a-deploy) changes the image, not the variables.

## Commands

| Command                                                                                                                | Does                                                            |
| ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `pier vars`                                                                                                            | list (all scopes)                                               |
| `pier vars set KEY=VALUE`, `pier vars set KEY --secret --secret-value -`, `pier vars set KEY --from postgres.main.url` | set; `--app`, `--site` scope it; `--stage` writes the file only |
| `pier vars rm KEY`                                                                                                     | remove                                                          |
| `pier vars reveal KEY`                                                                                                 | show a secret's value                                           |
| `pier vars import --file .env [--secret]`                                                                              | many at once                                                    |

## Tasks

[Set environment variables](/docs/guides/set-environment-variables) · [Add Postgres to an app](/docs/guides/add-postgres-to-an-app)
