Compose: command does not use latest environment variables

Created on 28 Oct 2016  路  6Comments  路  Source: docker/compose

Hi,

I have come across a minor issue. The command option does not seem to use the latest environment variables, as specified in the config file.

If I have the following:

#.env
APP_PORT=123
#docker-compose.yml
version: '2'
services:
  web:
    environment:
      APP_PORT: 1234
    command: "program ${APP_PORT}"

The final command is program 123 not program 1234. This is preventing me from conveniently setting up different environments.

However, if I create a debug.env file and add all my environment variables in there, and load it using env_file: [debug.env], command will use the latest env vars as specified in debug.env.

P.S. I'm open to any suggestions of better ways to share environemnt variables.

Most helpful comment

It's confusing, but the problem stems from the difference between the environment variables in your host shell when Compose loads the file, and the environment variables passed to the container.

Furthermore, the APP_PORT variable is being substituted at the point of loading the file, because Compose substitutes environment variables in ${...} expressions. This means that the container is being created with program 123 as its command, not program ${APP_PORT}.

If you want the command to pick up the APP_PORT variable from the container's environment, you'll need to do two things:

  • Wrap it in sh
  • Escape the $

This should work:

version: '2'
services:
  web:
    environment:
      APP_PORT: 1234
    command: ["sh", "-c", "program $${APP_PORT}"]

All 6 comments

It's confusing, but the problem stems from the difference between the environment variables in your host shell when Compose loads the file, and the environment variables passed to the container.

Furthermore, the APP_PORT variable is being substituted at the point of loading the file, because Compose substitutes environment variables in ${...} expressions. This means that the container is being created with program 123 as its command, not program ${APP_PORT}.

If you want the command to pick up the APP_PORT variable from the container's environment, you'll need to do two things:

  • Wrap it in sh
  • Escape the $

This should work:

version: '2'
services:
  web:
    environment:
      APP_PORT: 1234
    command: ["sh", "-c", "program $${APP_PORT}"]

The container keeps crashing, but docker logs outputs nothing. I assume it has something to do with the sh -c wrap. Do you have any suggestions on how I can further debug?

Edit: here's logs: https://gist.github.com/SupaHam/1152373b272c788219df45ea0c298138

@SupaHam What does your docker-compose.yml look like now?

@shin- I've changed it since, but it was something like

version: '2'
services:
  website:
    build: './website'
    command: '...'
    depends_on: [...]

Then in a docker-compose.override.yml:

version: '2'
services:
  website:
    env_file: [dev.env]
    ports: [...]

The file above would be used for the dev env by default.

Before I keep going on I realised a flaw in my setup in that prod and dev wouldn't even be able to run alongside one another as I was only using one service website and overriding it for each command start up:

  • For prod: docker-compose up -f docker-compose.yml -f docker-compose.prod.yml -d
  • For dev: docker-compose up -d

After realising this flaw, I've then dropped the idea of setting up a dev env and just doing a production env for now until I can figure out how to setup a dev env for django.

P.S. I don't believe service extending would serve me well as I can't specify dependencies in the abstract service.

Why environment variables from the docker-compose.yml are not took in account here?

You need to use sudo privileges,
1.- export ENV=data
2.- sudo -E docker-compose up .....

Was this page helpful?
0 / 5 - 0 ratings