A by-no-means-exhaustive list of direnv configuration techniques I’ve found helpful.
Local configuration only
Situation: the project requires environment variables to function. There is no need to capture how those variables should be provisioned in source control, or no consensus to do so among the contributors.
Approach:
- Put
.envrcin the project root. - Mark
.envrcto be locally ignored (eg. via.git/info/exclude, for Git). - Store environment settings there.
Shared configuration, local variations
Situation: the project requires environment variables to function. For development, there is a consensus to use direnv, but individual values cannot or should not be captured in source control.
Approach:
- Put
.envrcin the project root, and check it into source control. - Use
source_env_if_exists .envrc.localin.envrc. - Ensure that
.envrc.localis marked as ignored in source control (eg. via.gitignore, for Git). - Put personalization in
.envrc.local(where it won’t be checked in), and shared settings in.envrc(where they can be checked in).
Common environment settings across multiple projects
Situation: multiple projects require identical environment variable sets. These projects share a parent directory, which also contains projects that do not need those environment variables.
For me, this is my AWS creds, which are used by multiple projects inside of my ~/Projects directory, but not by everything there.
Approach:
- Put the common configuration in the parent directory, in files named
.envrc.SUFFIXfor some appropriate suffix (.envrc.aws, for example). - Use
source_up .envrc.awsto load them (from.envrc.local,.envrc, or by any other means) in the projects that need them.
Tokens in a password manager
Situation: you have confidential authentication tokens that you need to provide in order to access an external service. You don’t want them on the filesystem.
Approach:
-
Use your password manager’s CLI tool from inside of
.envrcor an included configuration. (This meshes well with the.envrc.localapproach). For example:export AWS_ACCESS_KEY_ID=$(op item get AWS-Development --field 'access key id') export AWS_SECRET_ACCESS_KEY=$(op item get AWS-Development --field 'secret access key')
Caveat: Many password managers implicitly start an agent process, which lurks in the background facilitating access. This agent can cause direnv to wait indefinitely.