Skip to content

Environment Files

Billy.Zheng edited this page Apr 13, 2026 · 1 revision

Environment Files

Procodile can load an env file when starting the supervisor:

procodile start --env-file
procodile start --env-file .env.production

If no file is provided, Procodile uses .env.

Path Resolution

Relative paths are resolved from the application root.

For example:

procodile start -r /srv/myapp --env-file

Procodile reads:

/srv/myapp/.env

Precedence

Environment variables are applied in the following order, from lowest to highest priority:

  1. Global env from Procfile.options
  2. Global env from Procfile.local
  3. The env file loaded with --env-file
  4. processes.<process_name>.env from Procfile.options
  5. processes.<process_name>.env from Procfile.local

In practice, this means:

  • the env file overrides global environment variables
  • per-process environment variables override the env file
  • PROC_NAME, PID_FILE, APP_ROOT, and PORT are managed by Procodile and cannot be overridden by user-defined values

Variable Names

Environment variable names are treated case-insensitively, so they must be unique after being normalized to uppercase.

For example:

foo=foo
Foo=foo

This will produce a runtime issue such as:

Duplicate key FOO found in .env

Variable Expansion

Later variables in the same env file may reference earlier ones.

For example:

ENV1=foo
ENV2=${ENV1}

This is valid, and ENV2 resolves to foo.

LUCKY_ENV

Env files are loaded through Crystal shards lucky_env, so LUCKY_ENV is supported.

If LUCKY_ENV is set, LuckyEnv first looks for an environment-specific file:

  • LUCKY_ENV=development.env.development
  • LUCKY_ENV=test.env.test
  • LUCKY_ENV=production.env.production

If no matching file is found, or if LUCKY_ENV is not set, .env is used.

Reloading and Restarting

Changing an env file does not update the environment of processes that are already running.

New env file values are applied the next time a process is started or restarted.

For example, if you change .env and run:

procodile restart -p app1

then app1 will read the updated env file, but app2 will keep its old environment until it is started or restarted later.

Likewise, procodile reload reloads Procodile configuration, but it does not restart running processes just to pick up env file changes.

The same rule applies to configured env values from the options files: reload updates Procodile's in-memory configuration immediately, but running processes keep their current environment until they are started or restarted again.

Example

Given:

# Procfile.options
env:
  APP_MODE: production
  LOG_LEVEL: info

processes:
  web:
    env:
      LOG_LEVEL: debug

and:

# .env
APP_MODE=staging
API_HOST=api.internal

then:

  • APP_MODE becomes staging
  • API_HOST comes from the env file
  • the global LOG_LEVEL remains info
  • LOG_LEVEL remains debug for web

That is the intended precedence:

process env > env file > global env

Clone this wiki locally