If you have many different projects, each with their own tool stack, SaaS providers, and whatnot, you may have been annoyed at all projects sharing the same configuration stored in your home folder. Here is how you can isolate projects using direnv.
The principle is rather simple:
You add a file called
.envrcto any directory you need specific setup for,add instructions that update the environment as necessary, and
run
direnv allowonce to confirm you want to apply what you just did.
From then on, whenever you visit that directory (or a sub-directory) in your shell, your custom environment (variables) will be loaded.
Environment hygiene is particularly important when you let your shell prompt display different information, for instance with starship. Your prompt can get quite crowded otherwise! |
That is all very abstract — here are a few concrete examples that I have been using every day.
- Kubernetes
By default,
kubectlwill store all contexts in.kube/config. That's fine for my Minikube setup, but I prefer to keep project-specific environments separate; not least, I want to be sure that credentials are gone when I delete the project folder!
kube_config.yamlapiVersion: v1
# <snip>.envrcexport KUBECONFIG="$(realpath .)/kube_config.yaml:${HOME}/.kube/config"Here, I add the local config; replacing it would be just as easy.
The invocation of The order matters
as well: the first entry takes precedence, and is where |
I have also taken to adding the output of minikube docker-env so that I can directly interface with the Docker demon inside
- gcloud
Similar approach for a Google Cloud project, also adding the project identifier:
.envrcexport CLOUDSDK_CONFIG=$(realpath .)/gcloud-config
export PROJECT_ID=my-projectI was quite appalled by how invasive the Google Cloud SDK acts on the shell environment in general;
I might re-install it in a place that is not usually on the PATH, and
then add it selectively only in matching project folders.
- Python
When I run
venv/bin/pytest, it needs help to find all the includes. Simple fix:
.envrcexport PYTHONPATH="$(realpath src):$(realpath test)"