Use env variable inside secondary docker image


#1

I would like to pass the CIRCLE_SHA1 env variable to a secondary container. The secondary container can’t access them by default.


#2

Yep, when setting up your docker YAML map, you can provide an environment key which contains a map of env vars. I think you might be able to add this in there, though I know variable interpolation doesn’t work in all keys across the YAML file. Try it?

https://circleci.com/docs/2.0/configuration-reference/#docker--machine--macosexecutor


#3

I can confirm variable interpolation doesn’t work for secondary container environments.

I’m trying to work around this by using the machine executor, will post results…


#4

Would you show how you’re trying this? Perhaps there is another way that readers know about.


#5

The relevant excerpt from my .config.yml:

  performance-test:
    docker:
    - image: maven:3.5.3-jdk-8-alpine
    - image: "myPrivateImage"
      auth:
        username: _json_key
        password: $GCLOUD_KEY
      environment:
        GCLOUD_KEY: $GCLOUD_KEY

The expansion works for the private registry key but not the secondary container’s environment (it runs a bash script which checks its content).

I got around it by using the machine executor and running the docker commands manually:

  performance-test:
    machine: true
    steps:
    - checkout
    - run:
        name: Login to docker registry
        command: docker login -u _json_key -p "${GCLOUD_KEY}" eu.gcr.io
    - run:
        name: Create docker network
        command: docker network create perf-tests
    - run:
        name: Launch secondary container
        command: >
          docker run --rm 
          -e GCLOUD_KEY="${GCLOUD_KEY}"
          --name ...
          --network=perf-tests
          myPrivateImage
        background: true
    - run:
        name: Run Tests
        command: >
          docker run
          -v ${PWD}/performance-tests:/usr/src/tests
          -w /usr/src/tests
          --network=perf-tests
          maven:3.5.3-jdk-8-alpine

#6

Great, nice one. I wonder, do you need the Machine executor for this? DinD (Docker in Docker) works very well, in my experience. (I do a similar thing to you, but with Docker Compose, and it has been rock-solid for me).


#7

By DinD do you mean using setup_remote_docker and then docker-compose to setup the containers?
That seems like it might work great!


#8

Yep, pretty much. Essentially if you were to flip your above config back to a Docker machine (e.g. docker:17.05.0-ce-git) then a Docker container is created for your build by CircleCI. Then your docker run above becomes a DinD configuration, by virtue of the nested containers.

In my experience this arrangement works very well. I think the Docker core team discourage it in certain circumstances (may be worth doing a bit of reading around it) but it’s been very reliable for me on CircleCI. The advantage I get is that I can run my microservices integration tests locally as well.

I’ve found that although there is nothing wrong with docker run with lots of parameters, after a certain level of complexity, putting all that stuff in a docker-compose.yml file is just a bit tidier. It simplifies other things as well, like container start order and network joining.