pier_

Set environment variables

Plain values, secrets and links — per environment, per app, or per target — and how they reach the container

Goal. api reads LOG_LEVEL and a secret API_KEY from its environment, with the secret never written to pier.yaml.

A plain value

pier vars set LOG_LEVEL=info --app api
output
→  Updated pier.yaml

  Changes:
    + create env_var "LOG_LEVEL" in prod (plain)

OK  Set LOG_LEVEL on api in prod

--app api scopes the variable to the app. Without it, the variable is set on the environment and every app and site in it sees it; --app api/canary scopes it to one target. A narrower scope wins over a wider one with the same key.

A secret

pier vars set API_KEY --secret --secret-value 'sk_live_9f2e4c…' --app api
output
→  Updated pier.yaml

  Changes:
    + create env_var "API_KEY" in prod (secret)

OK  Set API_KEY on api in prod (secret)

The declaration (API_KEY: { secret: true }) is written to pier.yaml; the value is stored in the platform's vault only. --secret-value - reads the value from stdin; pier vars import --file .env --secret loads several at once.

Check what is set

pier vars
output
                                         
 KEY       VALUE    SECRET ENV  UPDATED  
                                         
 API_KEY   ******** yes    prod just now 
 LOG_LEVEL info            prod just now 
                                         
pier vars reveal API_KEY
output
API_KEY=sk_live_9f2e4c…

Roll it into the container

A variable change is recorded as a new environment version; the running container keeps its old environment until the next deploy. pier deploy api releases it without a rebuild: the plan says deployed inline and counts the pending variables.

pier deploy api
output
→  Comparing prod environment against platform state...

  Changes:
    ~ update app "api" in prod
      env_version: 0 → 2  (env var — next deploy)

  Deploy:
    app "api"    deploy (deployed inline)

  Env vars:
    app "api"    2 pending

OK  Applied 1 config change(s) to prod
→  Waiting for infrastructure provisioning...
OK  Infrastructure ready

OK  Summary: 1 deployed
pier ssh api -- env | grep -E '^(LOG_LEVEL|API_KEY)='
output
API_KEY=sk_live_9f2e4c…
LOG_LEVEL=info

What changed

pier.yaml
    apps:
      - name: api
        build_context: ./api
        env:
          API_KEY:
            secret: true
          LOG_LEVEL:
            value: info

The file can be committed: it holds no secret value. Applying it from another checkout produces the same declaration, and the container receives the same vault value.

Variations

  • Link a resource instead of pasting its URL: pier vars set DATABASE_URL --from postgres.main.url --app apiAdd Postgres to an app.
  • Edit the file and apply: the env: block accepts value, secret: true, from, and required: false; pier apply converges it.
  • Remove: pier vars rm LOG_LEVEL --app api.
  • Per environment: -e staging on any of these commands targets that environment only; environments never share a variable.

See also

Environment variables · pier vars · Concepts: environment

On this page