Access env file variables in docker-compose file

Viewed 7262

I have an environment file that contain a variable called Database_User.

In my docker-compose, I have this:

services:
  database:
    container_name: postgres
    hostname: db
    image: postgres:12-alpine
    environment:
      - POSTGRES_USER=${Database_User}
   ports:
      - "54321:5432"
   env_file: project/myproject/.env

But, I am getting an error:

The Database_User variable is not set. Defaulting to a blank string.

2 Answers

To get this right it is important to correctly understand the differences between the environment and env_file properties and the .env file:

  • environment and env_file let you specify environment variables to be set in the container:
    • with environment you can specify the variables explicitly in the docker-compose.yml
    • with env_file you implicitly import all variables from that file
    • mixing both on the same service is bad practice since it will easily lead to unexpected behavior
  • the .env file is loaded by docker-compose into the environment of docker-compose itself where it can be used

So your current configuration does not do what you probably think it does:

env_file: project/myproject/.env

Will load that .env file into the environment of the container and not of docker-compose. Therefor Database_User won't be set for variable substitution:

environment:
  - POSTGRES_USER=${Database_User}

The solution here: remove env_file from your docker-compose.yml and place .env in the same directory you are starting docker-compose from. Alternatively you can specify an .env file by path with the --env-file flag:

docker-compose --env-file project/myproject/.env up

EDIT: This answer clearly explains the important difference from defining environment variables in an env file vs using variable substitution in a docker-compose file. I have edited my answer for clarity but please make sure you also understand the other answer.

Option 1

You likely have not set the environment variable Database_User for variable substitution to work and need to source wherever you have that defined before running docker-compose.

source ./database_user_defined_here.env
docker-compose up

You can review the docs on environment variable substitution: https://docs.docker.com/compose/environment-variables/#substitute-environment-variables-in-compose-files

Option 2

If you're using an environment file, you shouldn't have to specify the environment section (then just define POSTGRES_USER=... in that file). Then you'd run:

docker-compose --env-file ./your-env-file.env up 

Or you can also specify the env file in docker-compose.yml:

database:
  ...
  env_file:
    - your-env-file.env

However, you must specify the environment variables explicitly in this file. These docs go over env file syntax.

Related