Project-Specific Shell Configuration

2021-03-26 • edited 2022-03-15

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 .envrc to any directory you need specific setup for,

  • add instructions that update the environment as necessary, and

  • run direnv allow once 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.

Tip

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, kubectl will 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.yaml
apiVersion: v1
# <snip>
.envrc
export KUBECONFIG="$(realpath .)/kube_config.yaml:${HOME}/.kube/config"

Here, I add the local config; replacing it would be just as easy.

Note

The invocation of realpath ensures that KUBECONFIG refers to the correct file, even if I switch to a sub-directory later. If I ever do not want that, I can use a relative path.

The order matters as well: the first entry takes precedence, and is where kubectl will write to.

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:

.envrc
export CLOUDSDK_CONFIG=$(realpath .)/gcloud-config
export PROJECT_ID=my-project

I 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:

.envrc
export PYTHONPATH="$(realpath src):$(realpath test)"
ToolShell
Comment & Share on Twitter 

Private GitLab mirror of a public GitHub repository