Module 1 · Lesson 3

Env Vars & Secrets

Configure your app with defaults, required values, and generated secrets.

What you'll learn
  • Declaring environment variables with defaults and descriptions
  • Using generators for automatic secret creation
  • The secrets block and $secrets.* expressions
  • Pipe transforms like |base64

The env block

Every app needs configuration — a port to listen on, an API key for a third-party service, a secret for signing sessions. In a Launchfile, the env block declares all of this in one place.

Each variable can have a default value, be marked as required, include a human-readable description, use a generator for automatic creation, or be flagged as sensitive so providers mask it in logs.

Build it up

1
Start simple. A default value means the app works out of the box — the deployer can override it if needed.
env:
  PORT:
    default: "3000"
2
Mark a variable as required when the app can't start without it. The description tells the deployer what to provide.
env:
  PORT:
    default: "3000"
  API_KEY:
    required: true
    description: "Third-party API key"
3
The generator: secret field tells the provider to create a cryptographic random string at deploy time. Marking it sensitive keeps it out of logs.
env:
  PORT:
    default: "3000"
  API_KEY:
    required: true
    description: "Third-party API key"
  SESSION_SECRET:
    generator: secret
    sensitive: true
4
For more complex cases, use a top-level secrets block. Reference secrets with ${secrets.app-key} and apply pipe transforms like |base64.
secrets:
  app-key:
    generator: secret

env:
  PORT:
    default: "3000"
  APP_KEY: "base64:${secrets.app-key|base64}"

Secrets vs env

When to use which

There are two ways to generate secrets in a Launchfile:

  • Inline in env: Add generator: secret directly to an env var. Simple and self-contained.
  • Secrets block: Define named secrets at the top level, then reference them with ${secrets.name} in env. Useful when one secret feeds multiple env vars, or when you need transforms.

For most apps, the inline approach is all you need. Reach for the secrets block when you need to reuse or transform a generated value.

Inline generator
env:
  SESSION_SECRET:
    generator: secret
    sensitive: true
Secrets block + expression
secrets:
  session-key:
    generator: secret

env:
  SESSION_SECRET: "${secrets.session-key}"

In the wild

Firefly III is a personal finance manager with one of the more interesting Launchfiles in the catalog. It uses a secrets block with a |base64 pipe transform, references $app.url for its public URL, and wires Postgres connection details individually.

firefly-iii/Launchfile View on GitHub
version: launch/v1
name: firefly-iii
description: "Personal finance manager with budgeting and reporting"
repository: https://github.com/firefly-iii/firefly-iii
website: https://firefly-iii.org
logo: https://raw.githubusercontent.com/firefly-iii/firefly-iii/main/public/v1/images/logo.svg

image: fireflyiii/core:latest
provides:
  - protocol: http
    port: 8080
    exposed: true
requires:
  - type: postgres
    set_env:
      DB_CONNECTION: "pgsql"
      DB_HOST: $host
      DB_PORT: $port
      DB_DATABASE: $name
      DB_USERNAME: $user
      DB_PASSWORD: $password
secrets:
  app-key:
    generator: secret
env:
  APP_KEY: "base64:${secrets.app-key|base64}"
  APP_URL:
    default: $app.url
    description: "Public URL Firefly III is reachable on (used in emails, OAuth, links)"
health: /login
storage:
  uploads:
    path: /var/www/html/storage/upload
    persistent: true
restart: always
secrets:
Defines a named secret that gets generated once and reused.
APP_KEY:
References the generated secret with a |base64 pipe transform — the app expects a base64-encoded key.
APP_URL:
Uses $app.url — a built-in expression the provider fills with the app's public URL.
set_env:
Wires Postgres credentials individually instead of using a single $url — because Firefly expects separate DB_HOST, DB_PORT, etc.
storage:
Persists the upload directory so user data survives redeployments.

Try it: npx launchfile up firefly-iii to launch this app locally. View in catalog

Check your understanding

What does generator: secret do?
Key takeaways
  • The env block declares all environment variables with optional default, required, description, generator, and sensitive fields.
  • generator: secret auto-creates a cryptographic random string at deploy time.
  • The secrets block defines reusable, named secrets referenced via ${secrets.name} expressions.
  • Pipe transforms like |base64 let you encode or transform values inline.
esc
Type to search the docs