Environment variables from .env not set

I am running docker in guest Ubuntu OS. Inside the Ubuntu directory, I have my docker-compose.yml and .env files. Inside my docker-compose.yml file, a couple of lines from the environment section are:

environment:
  POSTGRES_USER: ${POSTGRES_USER}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
  …

Inside my .env file, I have

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres

But when I ran the yml file, I got warnings about my environment variables not being set. For example:

WARNING: The POSTGRES_USER variable is not set. Defaulting to a blank string.
WARNING: The POSTGRES_PASSWORD variable is not set. Defaulting to a blank string.

The containers in this project, for example, postgres, were all up and running for a few seconds. Then they all stopped. When I restarted the containers, they started and stopped right away. The cause for this stoppage is most likely due to the failure of setting the values from the .env file.

I googled. The general consensus is for this to occur, yml and .env are not in the same directory. But in my case, they are.

Can someone please give me some guidance how to solve this blank string issue?

Thanks in advance.

I think you’ll need to provide some more details. For instance:

vagrant@vagrant:~/git/pg_docker_demo$ docker-compose --version; docker --version
docker-compose version 1.25.5, build 8a1c60f6
Docker version 19.03.13, build 4484c46d9d
vagrant@vagrant:~/git/pg_docker_demo$ grep '.*' * .env
docker-compose.yml:version: '3.8'
docker-compose.yml:
docker-compose.yml:services:
docker-compose.yml:  pg:
docker-compose.yml:    image: postgres
docker-compose.yml:    environment:
docker-compose.yml:      POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER unset}
docker-compose.yml:      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD unset}
.env:POSTGRES_USER=postgres
.env:POSTGRES_PASSWORD=postgres
vagrant@vagrant:~/git/pg_docker_demo$ docker-compose up -d
Starting pg_docker_demo_pg_1 ... done
vagrant@vagrant:~/git/pg_docker_demo$ docker-compose ps
       Name                      Command              State    Ports
----------------------------------------------------------------------
pg_docker_demo_pg_1   docker-entrypoint.sh postgres   Up      5432/tcp
vagrant@vagrant:~/git/pg_docker_demo$ docker-compose logs --tail=10
Attaching to pg_docker_demo_pg_1
pg_1  | 2020-11-13 13:24:01.355 UTC [1] LOG:  database system is shut down
pg_1  |
pg_1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
pg_1  |
pg_1  | 2020-11-13 13:26:02.301 UTC [1] LOG:  starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
pg_1  | 2020-11-13 13:26:02.301 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
pg_1  | 2020-11-13 13:26:02.302 UTC [1] LOG:  listening on IPv6 address "::", port 5432
pg_1  | 2020-11-13 13:26:02.306 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
pg_1  | 2020-11-13 13:26:02.311 UTC [25] LOG:  database system was shut down at 2020-11-13 13:24:01 UTC
pg_1  | 2020-11-13 13:26:02.315 UTC [1] LOG:  database system is ready to accept connections

Note that I’m using the ${VAR:?message} form just because these are required variables and I’d rather have docker-compose fail fast than try to start only to fail during the init process. See the docs for further details.

Also note that in this case you may be better off using a regular env file.

vagrant@vagrant:~/git/pg_docker_demo$ grep '.*' * .env
docker-compose.yml:version: '3.8'
docker-compose.yml:
docker-compose.yml:services:
docker-compose.yml:  pg:
docker-compose.yml:    image: postgres
docker-compose.yml:    environment:
docker-compose.yml:      POSTGRES_USER: ${POSTGRES_USER:?POSTGRES_USER unset}
docker-compose.yml:      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD unset}
docker-compose.yml:  pg-with-env-file:
docker-compose.yml:    image: postgres
docker-compose.yml:    env_file:
docker-compose.yml:      - pg.docker.env
pg.docker.env:POSTGRES_USER=postgres
pg.docker.env:POSTGRES_PASSWORD=postgres
.env:POSTGRES_USER=postgres
.env:POSTGRES_PASSWORD=postgres
vagrant@vagrant:~/git/pg_docker_demo$ docker-compose up -d pg-with-env-file
Creating network "pg_docker_demo_default" with the default driver
Creating pg_docker_demo_pg-with-env-file_1 ... done
vagrant@vagrant:~/git/pg_docker_demo$ docker-compose logs --tail=10 pg-with-env-file
Attaching to pg_docker_demo_pg-with-env-file_1
pg-with-env-file_1  | server stopped
pg-with-env-file_1  |
pg-with-env-file_1  | PostgreSQL init process complete; ready for start up.
pg-with-env-file_1  |
pg-with-env-file_1  | 2020-11-13 13:31:23.108 UTC [1] LOG:  starting PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
pg-with-env-file_1  | 2020-11-13 13:31:23.108 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
pg-with-env-file_1  | 2020-11-13 13:31:23.108 UTC [1] LOG:  listening on IPv6 address "::", port 5432
pg-with-env-file_1  | 2020-11-13 13:31:23.112 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
pg-with-env-file_1  | 2020-11-13 13:31:23.118 UTC [55] LOG:  database system was shut down at 2020-11-13 13:31:22 UTC
pg-with-env-file_1  | 2020-11-13 13:31:23.122 UTC [1] LOG:  database system is ready to accept connections

You should define the environment as an array like this:

environment:
  - POSTGRES_USER=${POSTGRES_USER}
  - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}

BTW if the env variable has the same name in the .env file you don’t even need to specify it. This should work too:

environment:
  - POSTGRES_USER
  - POSTGRES_PASSWORD