4.1 KiB
+++ title = "Environment Variables Made Easy" author = ["Elia el Lazkani"] date = 2025-02-20 lastmod = 2025-02-20 tags = ["env", "environment-variable", "envrc", "direnv", "dev", "developement"] categories = ["misc"] draft = false +++
If you've written software in the last decade, then you're probably familiar with the current technologies at play. You write your code, locally, in your IDE, build and test it. You've made your commit and pushed it to the revision control system server and created a pull request. Pipelines started, code built, unit tests ran, magic all over and now it's deployed in staging. Once the code lives in staging long enough to build trust in its performance it goes to production.
This is in a nutshell how it looks like. The big elephant in the room is, of course, that all of these different environments are, well... different !
This means that the values I used to test my code locally is different than the values used to test in the pipeline, for security reasons. The same goes for every single environment. Configuration files could solve a lot of these issues but, as we all know, they don't solve all of them.
Another solution is to use environment variables, which could be easily
injected into scripts, environments and even containers. It's a win-win
everywhere except managing them locally. You're probably thinking my .profile
file looks like a mess. You'd be surprised to know that mine is empty, but how ?
Direnv
Direnv
is described by the developers as
an extension for your shell. It augments existing shells with a new feature that can load and unload environment variables depending on the current directory.
It's as simple as that !
Direnv
runs on most operating systems and a wide variety of shells. The
installation process is well documented and the same goes for configuring
direnv
to hook to your favorite shell.
How does it work ?
First, let's start by creating a new project.
$ mkdir project-1
$ cd project-1
Now that we've created a project, let's create a .envrc
file and populate it
with the following.
# Add build/bin to $PATH
PATH_add build/bin
# Export environment variables
export DB_HOST="localhost"
export DB_PORT="5432"
export DB_USERNAME="dummy-user"
export DB_PASSWORD="super-secret"
Once I save the file and exit the editor, I get greeted with a lovely error.
direnv: error ~/project-1/.envrc is blocked. Run `direnv allow` to approve its content
The reason for this is very simple. The .envrc
file can do a lot, making it a
security risk. This error is there to make sure that you check the .envrc
and
only allow direnv
with trusted .envrc
files.
I wrote this .envrc
file, so I can safely trust it. But you can't !
$ direnv allow
direnv: loading ~/project-1/.envrc
direnv: export +DB_HOST +DB_PASSWORD +DB_PORT +DB_USERNAME ~PATH
This tells us that we've exported a list of environment variables. Let's check them out.
$ env | grep DB_
DB_PORT=5432
DB_HOST=localhost
DB_PASSWORD=super-secret
DB_USERNAME=dummy-user
We've also used the PATH_add
to add a project specific directory to our PATH
allowing us to run the binaries directly without having to navigate to the
build directory.
Warning
It is very important, at this stage, for me to warn you about the dangers of
committing your .envrc
to your revision control. This bad boy's got
passwords in it ! Don't do it !
That's impressive and all but...
I know what you're gonna ask me next and here's the answer.
$ cd ..
direnv: unloading
and now...
$ env | grep DB_
$
Nothing at all. All variables have been unloaded automatically. They will be loaded again the next time you navigate to the project's directory.
Conclusion
Next time you're working on your project, give direnv
a try. It will change
the way you work for the better, I hope.
Happy Hacking !