Isolated development with direnv & devbox (& gum)
In this blog we will talk about 3 tools to make a deal with multiple environments easier.
In real world development, we have to maintain environment variables e.g. target urls, service port number, database table name, etc. It would sound messy if we have to declare those variables every time we open an IDE, and would be more pain if we need to switch to another environment.
In this blog we will talk about 3 tools to make a deal with multiple environments easier.
direnvto get folder ready for environment variables.devboxto make a folder isolated like a container for packages installed.gumto switch environment easily.
plus a big advantage for team collaboration because they are file-based that we can push to the repo (with proper security management).
direnv for env
direnv is a tool to setup environment when access a prepared folder. for example, we enter a folder of python and it automatically activates venv for us.
direnv setup
- we need to install
direnv. in my setup, i installed it through homebrew. - once it’s installed, add the hook into your shell file. in my setup that uses zsh, i just add this line into my
~/.zshrc.
1
eval "$(direnv hook zsh)"
and that’s it. we are ready to initial my folder.
direnv usage
auto-scripts
say we want to develop a python app. once we created venv, we have to activate it first, and deactivate at last, right?
with direnv we don’t have to do so. just enter the folder and it will activate and deactivate when leave the folder for us. follow this.
- Make sure we are in the folder and
direnv allowto execute.envrc
- Leave the folder and see
direnvdeactivate the environment.
We can check Python venv with command which pip. The figure above represent my prompt showing venv from Oh-my-posh installed. Learn more about it from my dotfiles or https://ohmyposh.dev.
embedded env vars
Beside of that auto-script, the another main objective of direnv is to embed variables into the environment.
Let’s say we embed a variable env into this folder. .envrc would look like this.
When we direnv allow and enter the folder, we will access the variable env. And get nothing when leave the folder.
Now we don’t have to create and remove variables we declared over and over again.
Our lives go easier by +1 step.
devbox for packages
Move to another tool. devbox enables a directory installs packages locally
devbox setup
1
curl -fsSL https://get.jetify.com/devbox | bash
If that is the error Error: Unable to find nix startup file, please try installing Nix package manager.
1
sh <(curl -L https://nixos.org/nix/install) # for macos
devbox usage
First, init it.
1
devbox init
then we can see a file “devbox.json”.
Now we need to find the packages we want to install using devbox search like this.
1
2
devbox search package
devbox search package@version
Okay, we are gonna add Python 3.10 via
1
devbox add python@3.10
If this is a first time, devbox will install nix package manager if it’s not installed yet.
Next time we can see the package has been being installed.
Then we should see the updated “devbox.json” like this.
The packages shows “python@3.10” (line 4) right there.
Next we start with the command below.
1
devbox shell # start shell
And we can see the python environment has been created. Basically venv folder named “.venv”.
And exit at the end.
1
exit # exit shell
However the env is in .venv. We can custom the folder name by adding env (line 17-19) and apply it in init_hook (line 9) like this.
combo direnv & devbox
With devbox, we have no need to create venv beforehand because devbox will do it for us but we have to run shell and activate every time.
We can combo devbox with direnv to run shell automatically with this command.
1
devbox generate direnv
.envrc generated this way will be like this.
At this step, we now control packages and access the environment at ease.
gum for multiple env
Okay we now are able to build an isolated workspace. How about maintaining multiple environment such as dev & prod?
Of course we have to prepare multiple files for each environment. And it will be good if we can switch from an environment to another.
We are talking about gum.
gum is a tiny tool to represent designated prompt for a specific task. It works great and flexible in operations using shell scripts. Here we will see how can we utilize gum to work with multiple environment.
gum setup
Install via homebrew.
1
brew install gum
or others by your preferences by visiting the link in references below.
gum usage
With gum alone, we can create a simple shell prompt like this.
And we will adapt with our setup earlier.
Say we have 2 environments; dev & prod. Also there are 2 env files like this.
And the structure becomes as below.
We will use a flag of devbox for direnv to select each of both files like this. That flag is --env-file followed by a target env filepath. It will turn out like this in .envrc.
ls .envsto list all files in.envsfolder.gum chooseto prompt choosing files fromlsabove.--env-fileto input chosen files fromgumprompt.
And we run direnv allow. Finally we can select any env file to start an environment to work with.
Repo
References
direnvhttps://direnv.netdirenvwiki https://github.com/direnv/direnv/wikihomebrewhttps://bluebirz.net/posts/homebrew-one-place-for-all/devboxby jetify https://www.jetify.com/devbox/- Nix package manager https://nixos.org/download/
gumhttps://github.com/charmbracelet/gum










