What is direnv
direnv is a tool that allows you to set up different environments for different directories. direnv allows you to automatically set up the specified environment variables, aliases, commands, and shell functions for a directory each time you navigate to it. This makes it easy to switch between environments as needed for different projects.
direnv uses a file .envrc
to set the environment for a directory. The .envrc
file is read by direnv when it is moved with the cd
command, and sets the environment for that directory.
The following is an example of .envrc
file.
# environment variable
export MY_VAR=example_value
export PATH=$PWD/bin:$PATH
# alias
alias ll='ls -l'
# shell function
function my_function() {
echo "Hello, World!"
}
This example defines an environment variable called MY_VAR
and adds $PWD/bin
to $PATH
. It also defines an alias ll
and a shell function my_function
. In this way, you can easily set up different environments for different projects.
How to use direnv
Here is how to use direnv.
Install
On Mac, you can easily install direnv with the brew
command.
$ brew install direnv
After installing direnv, add hooks to your shell; for bash, run the following command.
$ echo 'eval "$(direnv hook bash)"' >> ~/.bashrc
$ source ~/.bashrc
allow
Read the .envrc
file with the direnv allow
command.
For example, in the /my-project
directory, create a .envrc
file like this.
export TEST=test
Execute the following command.
$ direnv allow
direnv: loading ~/my-project/.envrc
direnv: export +TEST
Under the /my-project
directory, the environment variable TEST
will be set.
$ echo $TEST
test
Moving from the /my-project
directory will unload direnv.
$ cd ..
direnv: unloading
You can see that the environment variable TEST
is unset.
$ echo $TEST
Other commands
direnv has several commands in addition to the allow
command. See the direnv --help
command for details.
$ direnv --help
direnv v2.32.2
Usage: direnv COMMAND [...ARGS]
Available commands
------------------
allow [PATH_TO_RC]:
permit [PATH_TO_RC]:
grant [PATH_TO_RC]:
Grants direnv permission to load the given .envrc or .env file.
block [PATH_TO_RC]:
deny [PATH_TO_RC]:
revoke [PATH_TO_RC]:
Revokes the authorization of a given .envrc or .env file.
edit [PATH_TO_RC]:
Opens PATH_TO_RC or the current .envrc or .env into an $EDITOR and allow
the file to be loaded afterwards.
exec DIR COMMAND [...ARGS]:
Executes a command after loading the first .envrc or .env found in DIR
fetchurl <url> [<integrity-hash>]:
Fetches a given URL into direnv's CAS
help [SHOW_PRIVATE]:
shows this help
hook SHELL:
Used to setup the shell hook
prune:
removes old allowed files
reload:
triggers an env reload
status:
prints some debug status information
stdlib:
Displays the stdlib available in the .envrc execution context
version [VERSION_AT_LEAST]:
prints the version or checks that direnv is older than VERSION_AT_LEAST.
Use .env and .envrc together
docker-compose and dotenv use a file .env
to set environment variables.
If you want to use .env
and .envrc
together, you can avoid double management of environment variables in the following way.
Environment variable definitions are written in .env
.
API_KEY=xxxxxxxxxxxxxxxxxxxx
You can refer to environment variables defined in .env
in .envrc
by writing dotenv
in .envrc
.
dotenv
If the file name is not .env
, the path can be specified as follows.
dotenv ./.env.development
Use venv and .envrc together
By using direnv with Python's venv
, you can activate a virtual environment when you move to a project directory and automatically deactivate it when you exit that directory.
First, create a Python virtual environment.
$ cd my-project
$ python -m venv venv
Create a .envrc
under the project directory as follows.
source venv/bin/activate
export PYTHONPATH=${APP_HOME}
export HOGE='HOGE'
export FUGA='FUGA'
Navigate to the target directory to activate the virtual environment.
$ cd my-project
direnv: loading ~/Projects/my-project/.envrc
direnv: export +BAR +FOO ~PYTHONPATH
(venv)$
After exiting the directory, the virtual environment is deactivated.
(venv)$ cd ..
direnv: unloading
$
References