Loading env from a dotenv file
Use --env-file to populate the inline env layer from a .env-formatted file, then let workflow / task / step env: blocks layer on top. Most useful when you keep per-environment files (.env.staging, .env.production) committed at the repo root.
The shape
# zorb.yml
tasks:
migrate:
description: Apply database migrations
env:
# Workflow-level env still wins over --env-file, so safe defaults belong here.
LOG_LEVEL: ${{ env.LOG_LEVEL | default('info') }}
steps:
- run: |
set -euo pipefail
./bin/migrate --url "$DATABASE_URL" --log "$LOG_LEVEL"# .env.staging
DATABASE_URL=postgres://staging-db.internal/app
LOG_LEVEL=debugzorb run migrate --env-file .env.stagingLayering
--env-file populates the inline env layer, which sits at the bottom of the precedence stack:
inline CLI env < defaults.run.env < workflow env < task env < step envSo values in a dotenv become sensible defaults — anything the workflow declares at a higher scope overrides them. Inline -e KEY=VALUE flags override --env-file values, so a CLI invocation can pin a single variable without editing the file:
zorb run migrate --env-file .env.staging -e LOG_LEVEL=tracePer-environment files
Stash one dotenv per environment, gitignore the ones with secrets, commit the ones without:
.env.staging # checked in
.env.production # gitignored
.env.staging.local # gitignoredThen wire each one to a task that targets that environment:
zorb run deploy --with environment=staging --env-file .env.staging
zorb run deploy --with environment=production --env-file .env.productionIf the choice is mechanical, push it into a wrapper task:
tasks:
deploy-staging:
steps:
- uses: ./zorb.deploy
with:
environment: staging…and call zorb run deploy-staging --env-file .env.staging.
Secrets, not just config
--env-file is fine for non-secret config. For real credentials, prefer a secrets: loader that fetches at run time and registers values through context.setSecret:
secrets:
- uses: '@zorb/secrets/load-1password'
with:
vault: Production
items: [DATABASE_URL, STRIPE_KEY]
tasks:
migrate:
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
steps:
- run: ./bin/migrateThe difference: registered secrets are masked to *** in step output. Values from --env-file are not.
Dotenv syntax zorb supports
# Comments start with '#'
DATABASE_URL=postgres://localhost/app
LOG_LEVEL=debug # inline comment after an unquoted value
export API_TOKEN=ghp_xxx # 'export ' prefix is accepted, ignored
GREETING="hello\nworld" # double quotes: \n \r \t \" \\ interpreted
LITERAL='no escapes here' # single quotes: literal valueBlank lines and # lines are skipped. See CLI reference → Env file format for the precise rules.
See also
- CLI reference →
zorb run— every flag in this recipe. - Workflow format → Env — the precedence stack.
- Multi-environment deploy — combines
--env-filewith--with.