27

When I run docker-compose build && docker-compose up redis, with environment specified in docker-compose.yaml and RUN env in the Dockerfile, the environment variables I set don't get printed.

Why does this not work?

I'm using docker-compose version 1.4.2.

Here are the relevant files:

docker-compose.yaml with environment as a list of KEY=value pairs:

redis:
    build: ../storage/redis
    ports:
      - "6379:6379"
    environment:
      - FOO='bar'

docker-compose.yaml with environment as a dictionary:

redis:
    build: ../storage/redis
    ports:
      - "6379:6379"
    environment:
      - FOO: 'bar'

Dockerfile:

FROM redis:2.6
MAINTAINER [email protected]

RUN mkdir -p /var/redis && chown -R redis:redis /var/redis

RUN echo '-------------- env ---------------'
RUN env

COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
ENTRYPOINT ["redis-server", "/usr/local/etc/redis/redis.conf"]

4 Answers 4

26

That's normal

docker-compose only sets the environment variables specified in the environment directive in the docker-compose.yaml file during the run phase of the container, and not during the build phase.

So if you do docker-compose run --entrypoint "/bin/bash" redis -c env you will be able to see your env variables.

If you want to set variables inside your Dockerfile (to be able to see them during the build phase) you can add inside your dockerfile before your RUN env:

ENV FOO bar
Sign up to request clarification or add additional context in comments.

10 Comments

When I run $ docker-compose run redis env, I get: *** FATAL CONFIG FILE ERROR *** Reading the configuration file, at line 493 >>> '"env"' Bad directive or wrong number of arguments1
Ah ok sorry I did not see you changed the entrypoint. In your case do docker-compose run redis /bin/bash -c env @Neil
Running that emits: Bad directive or wrong number of arguments
Are you saying that docker-compose sets those environment variables in my own shell that runs docker compose up redis? How do you get the docker-compose environment to persist into the container? What is the point of the environment directive if this isn't done automatically?
You mentioned "during the build phase", where can I get the container to print the environment after the build phase is complete? I just want my running container to have access to the environment set in the docker-compose.yml file.
|
3

This is because you were using environment when (I guess) you wanted to use args inside the build block:

redis:
    build: 
      context: ../storage/redis
      args:
        - FOO: 'bar'
      ports:
        - "6379:6379"

And FUN would be defined as follows (in your Dockerfile):

FROM redis:2.6

RUN mkdir -p /var/redis && chown -R redis:redis /var/redis

# Read FUN from (build) arguments 
# (may define a default: ARG FUN='wow')
ARG FUN

# Define env variable FUN with value from ARG
ENV FUN=$FUN

RUN echo '-------------- env ---------------'
RUN env

COPY redis.conf /usr/local/etc/redis/redis.conf
EXPOSE 6379
ENTRYPOINT ["redis-server", "/usr/local/etc/redis/redis.conf"]

The environment block is used to define variables for the running container (when docker-compose up, NOT when docker-compose build).

Similar answer to a similar question, may be of interest:

Comments

2

Well I have tested and found following solutions for docker compose with env file or without env file. I will show you two different approach

Lets say you have following docker compose yml file

version: '3.8'
services:
db:
image: postgres:13
volumes:
 - "./volumes/postgres:/var/lib/postgresql/data"
ports:
 - "5432:5432"
env_file: docker.env

Now you need to setup the postgres variable in a file called docker.env. Remember you need to keep the docker_compose.yml file and docker.env file in same folder. Next, In the docker.env file you need to have the database variable and value like this:

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=myapp_db

Now hit docker-compose up . It should work. Lets say now you dont like to specify the env file name in the docker-compose.yml file. So you have to write docker-compose.yml file like this:

version: '3.8'
services:
db:
  image: postgres:13
  volumes:
    - "./volumes/postgres:/var/lib/postgresql/data"
  ports:
    - "5432:5432"
  environments:
     - POSTGRES_USER=${PGU}
     -POSTGRES_PASSWORD=${PGP}
     -POSTGRES_DB=${PGD}

Now your docker.env file should look like this:

PGU=postgres
PGP=postgres
PGD=myapp_db

now hit docker-compose --env-file docker.env up

you are good to go.

4 Comments

Using an env_file is a lot easier and provides greater seperation from the docker-compose file. Moreover, if you have heavily nested environments, i was ONLY able to get it to work using a seperate .env file instead of including it in the compose file.
Neither approach working here.
@bc3tech Can you please specify more what is your error message and may be share your code
The only thing that worked was building beforehand w/ --build-args passed from cmd line. I am thinking the environment bits only apply to image sections, not build sections.
1

TLDR: If you need to use environments, use an ENV file instead of placing it into a compose file. When placing environment variables in a docker-compose file (list of environment variables) and those variables are referencing each other, the docker-loader does not correctly join those correctly.

Explanation:

The long and short is, the Environment variables when placed in a .env file are evaluated BEFORE being provided to the running docker environment. This allows for specific environment variables to be made dynamically (see in my example below of the connection string leveraging the environment variables in the ENV file).

Use this Instead

version: '3.8'
services:
db:
image: postgres:13
volumes:
 - "./volumes/postgres:/var/lib/postgresql/data"
ports:
 - "5432:5432"
env_file: docker.env

docker.env file contains:

   ASPNETCORE_ENVIRONMENT=Test
    DATABASE_USER=lawguy007
    DATABASE_PASSWORD=myPasswordIsBoring
    DATABASE_SERVER=192.168.1.25    
    ConnectionStrings__DefaultConnection=Server="${DATABASE_SERVER}";Include Error Detail=true;Database=threatlists;User Id=${DATABASE_USER};Password=${DATABASE_PASSWORD}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.