Using *.env-files everywhere


Many tools automatically look for a special file called .env, which contains KEY=VALUE pairs, one per line. I am here referring to a file with the same syntax, but with arbitrary names. I use different names to distinguish between configurations for different development stages.

Using environment variables for configuration is pretty much accepted as good practice today for web applications. But it’s always a hassle to deal with them during development, if you are not using a specialised service for them. My current approach is to create separate *.env-file for the development and testing stage: development.env and testing.env. These files use regular bash-syntax for variable declaration:

1
2
3
# development.env
DEBUG=True
DATABASE_URL=postgresql://postgres:postgres@postgres/devdb

and here is the version for the testing-stage:

1
2
3
# testing.env
DEBUG=False
DATABASE_URL=postgresql://postgres:postgres@postgres/testdb

The great thing about these files is that many popular tools support them in one way or the other. Either directly as command line arguments, or by using a shell script.

Here are some examples.

Using .env-files with docker compose

You can specify env-files both as part of your docker-compose.yml file or by passing it on the command line.

# Inside your docker-compose.yml
app:
  env_file:
    - development.yml

or by passing it on the command line:

$ docker compose --env-file env/development.env up -d

Note that these two uses are not semantically equivalent. The first makes all environment variables available to the app container, the second makes them only available during the build-process. Passing the --env-file parameter will not magically make those variables available to the container. For each variable you will still need to specify in each container’s environment:-section, which variables are made available.

Using .env-files with shell-scripts

The most robust way to use .env-files in a shell script seems to be this:

1
2
3
set -o allexport
source development.env
set +o allexport

Using .env-files with PyCharm IDE (or any IntelliJ based IDE)

PyCharm does not come with built-in support for using *.env-files for run-configurations, but there is a very popular and robust third-party plugin called EnvFile. It can be installed from Plugins-preference and let’s you specify one or more .env-files as sources for environment variables. If you want to see it in action, there are some screenshot in the official github repo..

Other uses

  • pipenv will automatically load a file named .env if it is found in the project folder. There is no command line argument to override it, but luckily there is an environment variable to tell pipenv to look for a different file-name: PIPENV_DOTENV_LOCATION=development.env pipenv shell will start pipenv-shell with the environment variables from your development.env file.
  • Procfile-based application management tools, which have also been adopted by cloud providers like AWS and heroku. The original foreman-repo has a list of ports for other languages.. You can specify different (and multiple) env-files using the --env command line parameter.
  • the ´python-dotenv´ library will load environment variables from a .env-file. In most cases I believe this an anti-pattern. After all, the whole idea of environment-variables was to get away from config-files. However, for python scripts that help you manage your environments, this might come in handy.

See also