tl;dr - You should be using direnv
to load ENV variables dynamically per-project.
You don’t necessarily have to buy into the entirety of the 12 factor app manifesto, but you should almost definitely be using ENV-as-configuration by this point.
Even if it’s just a CONFIG
ENV var that points to a config.toml
that your application reads, passing configuration via environment variables is the tried and true method of configuring applications these days (inside a docker container or out).
But how do you manage your ENV configuration when doing local development? Well that’s where direnv
comes in.
If you place a .envrc
(or .env
) file in a directory, and browse to it in your shell of choice, direnv
will load those ENV variables.
direnv
Check out the install instructions to get direnv
installed, then make a .envrc
file like this:
# let's say you want to use the superior editor
export EDITOR=emacs
# and the superior browser
export BROWSER_BIN=firefox-developer-edition
# Application variables
# (these are what your application needs to run)
export FOO=bar
In addition to just values, you can put whatever you want in your .envrc
and it will be evaluated… Which means you can do a lot with .envrc
files.
One example You could get the absolute path to a file or even read it into an ENV var.
# You can get the absolute path to a file
export ABS_PATH_TO_FILE=$(realpath relative/path/to/file)
# You can also read files into ENV vars
export FILE_IN_VAR=$(cat relative/path/to/small/file)
NOTE: you’ll need realpath
installed of course, but you could run any other command as well
git
hooks with direnv
One of my favorite uses is to trigger/configure git
to do hooks, avoiding the need to use tools like husky
:
# While in the project folder tree, git will load hooks from `.githooks` (which can be checked into source control!)
git config --local core.hooksPath $PWD/.githooks
.env
files work too!Whether you’re developing a NodeJS app that expects .env
files, or you’re working with a file that could be passed to docker
(via --envfile
), you can configure
In the configuration file for direnv
(ex. ~/.config/direnv/direnv.toml
) you can add a configuration like this:
[global]
load_dotenv = true
This will enable direnv
to read .env
files which have a slightly different syntax and are less dynamic:
NODE_ENV=development
FOO=bar
.gitignore
/.dockerignore
your .env files!If you’re going to use direnv
, don’t forget to add .envrc
and .env
to your .gitignore
if you don’t want to check the files in!
You could ignore the files for every repo on your own computer, but the best way to make sure that no one on your team checks the file in either is to put the .gitignore
(which includes .envrc
/.env
) into source control.
direnv
is super flexible and I’ve loved having it as part of my go-to tooling for a long time. If you haven’t already, start using it!