Published on

Specifying an Alternate Env File to Docker Compose

Authors

Docker-compose supports using an .env file to replace environment variables in your compose files with a value configured in the file. For example, say I have the following .env file:

FOO=bar

I then have a docker-compose.yaml that looks as follows:

version: '3.7'

services:
  chain-node:
    image: some/container:0.1
    restart: unless-stopped
    ports:
      - '30303:30303'
    environment:
      - fizz="${FOO:?NO_VALUE_PROVIDED_FOR_FOO}"

The following ${FOO:?NO_VALUE_PROVIDED_FOR_FOO} will be replaced with bar as long as docker-compose up -d is run from the directory with the .env file in. Using variables like this will also cause an error NO_VALUE_PROVIDED_FOR_FOO if the .env file did not have a value configrued for FOO.

One issue I ran into today was that there was no way to tell docker-compose where to find the .env file or to use a file with a different name for example to use .env.local. After a bit of Googling I came across this workaround:

env $(cat .env.test) docker-compose up

This basically dumps the .env values before the docker-compose command as if you run it as:

FOO=bar docker-compose up

I assume this works as compose (like many programs) gives command-line variables passed in precedence over file-based configurations. One issue you may run into if you have comments in your .env file is an error of the form:

env: # : No such file or directory

This is caused by cat dumping everything before the command including any comments in the file. For example, if I have the below .env file:

# my awesome config
FOO=bar

Then use the above-mentioned workaround it is basically equivalent to running:

# my awesome config FOO=bar docker-compose up

To fix this simply tweak the original to grep out the comments as below:

env $(cat .env.test | grep "#" -v) docker-compose up