Combining docker-compose override files with mutliple .env files

I see why it is confusing but the env_file in the docker compose file is for setting variables in a container. Just like environment. You could do it using docker like docker run -e FA_SERVER=LINODE or docker run --env-file linode.env. Those variables will not be available in the docker compose file.

.env is for docker compose, whcih means it will be interpreted by docker compose and you can use the variables in the yaml file. Since your .env contains LOCAL, this is the value of ${FA_SERVER} in docker-compose.linode.yml.

The list you find

refers that you can define variables for a container multiple ways.

let’s say you have a .env file:

source=.env

and defined in the shell:

export source=shell

compose file

services:
  ubuntu:
    image: ubuntu:20.04
    stdin_open: true
    tty: true
    env_file:
      - custom.env
    environment:
      source: compose

Then run

docker-compose up -d
docker-compose exec ubuntu env | grep source

You would see

source=compose

Then you remove the environment section from the compose file and keep the env_file section, run docker exec again to see

source=custom.env

None of these values came from the .env file neither from the shell because you defined it in the docker compose either using the environment section or the env_file section.

Now remove the env_file section from the compose file, and you won’t see source defined in the container becuse the shell variables and the content of the .env file will not be set in the containers.

Put the environment section back this way:

services:
  ubuntu:
    image: ubuntu:20.04
    stdin_open: true
    tty: true
    env_file:
      - custom.env
    environment:
      source: ${source}

Now you will see source=shell in the output because the shell has higher precedence (2) than the .env file (3).
Now delete the shell variable:

unset source

Run docker-compose up and docker exec again to see this:

source=.env

If you don’t have .env file but you have source set in the Dockerfile, then the container see that value like source=dockerfile.

Let’s call .env and the shell external sources. I don’t know if anyone calls it that way but I will. So if you use these external sources, then if you have a variable accidentaly or intentionally defined in. the shell, it overrides the values in the .env file. Even if you could have multiple .env files.

You can use docker-compose.linode.yml to set the variables without any external source, or create shell scripts for the different setups to set different variables in each case.