dockerdocker-composedocker-ce

Can't pass environment variables with the docker-compose run -e option


I'm trying to get the variable from the command line using:

 sudo docker-compose -f docker-compose-fooname.yml run -e BLABLA=hello someservicename

My file looks like this:

version: '3'

services:
  someservicename:
    environment:
      - BLABLA
    image: docker.websitename.com/image-name:latest
    volumes:
      - /var/www/image-name
    command: ["npm", "run", BLABLA]

All of this is so that I can run a script defined by what I use as BLABLA in the command line, I've tried going with official documentation.

Tried several options including:

sudo COMPOSE_OPTIONS="-e BLABLA=hello" docker-compose -f docker-compose-fooname.yml run someservicename

UPDATE: I have to mention that as it is, I always get:

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

Even when I just run the following command (be it remove, stop..):

  sudo docker-compose -f docker-compose-fooname.yml stop someservicename

For the record: I'm pulling the image first, I never build it but my CI/CD tool does (gitlab), does this affect it?

I'm using docker-compose version 1.18, docker version 18.06.1-ce, Ubuntu 16.04


Solution

  • That docker-compose.yml syntax doesn't work the way you expect. If you write:

    command: ["npm", "run", BLABLA]
    

    A YAML parser will turn that into a list of three strings npm, run, and BLABLA, and when Docker Compose sees that list it will try to run literally that exact command, without running a shell to try to interpret anything.

    If you set it to a string, Docker will run a shell over it, and that shell will expand the environment variable; try

    command: "npm run $BLABLA"
    

    That having been said, this is a little bit odd use of Docker Compose. As the services: key implies the more usual use case is to launch some set of long-running services with docker-compose up; you might npm run start or some such as a service but you wouldn't typically have a totally parametrizable block with no default.

    I might make the docker-compose.yml just say

    version: '3'
    services:
      someservicename:
        image: docker.websitename.com/image-name:latest
        command: ["npm", "run", "start"]
    

    and if I did actually need to run something else, run

    docker-compose run --rm someservicename npm run somethingelse
    

    (or just use my local ./node_modules/.bin/somethingelse and not involve Docker at all)