1

I have below docker-compose.yml file. In the command section I would like to evaluate the curl expression before the command is passed to docker engine i.e. my curl should be evaluated first and then my container should run with -ip 10.0.0.2 option.

version: '2'
services:
  registrator:
    image: gliderlabs/registrator:v7
    container_name: registrator
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    command: ['-ip', '$$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)']

This however is not being evaluated and my option is passed as -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)

The respective docker run command however correctly evaluates the expression and my container is correctly starting with -ip 10.0.0.2 option:

docker run -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:v7 -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)
Rash
  • 7,677
  • 1
  • 53
  • 74

2 Answers2

2

The docker command on the command line will work as the command will be executed by the shell and not the docker image, so it will be resolved.

the docker-compose command will override the default command (CMD) (see https://docs.docker.com/compose/compose-file/#command) so it will not be executed before the container is started but as the primary command in the container...

you could do something like:

version: '2'
services:
  registrator:
    image: gliderlabs/registrator:v7
    container_name: registrator
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock
    command: ['-ip', '${IP}']

and run it with:

IP="$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)" docker-compose up

this will run it in the shell again and assign it to a variable called IP witch will be available during the docker-compose up command. You could put that command in a shell script to make it easier.

Ivonet
  • 2,492
  • 2
  • 15
  • 28
0

After searching the internet for hours and answers posted here, I finally settled for below solution. For explanation of why this works, please refer to @Ivonet answer.

I modified the Dockerfile to run a script when the container starts.

FROM gliderlabs/registrator:v7

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh && \
    apk update && \
    apk add curl

ENTRYPOINT ["/entrypoint.sh"]

The script entrypoint.sh is also very simple. It first checks if it can call the endpoint. A success response would trigger my container to start with correct IP address, while an un-successful response (for local testing) would not set any value.

#!/bin/sh

LOCAL_IP=$(curl -s --connect-timeout 3 169.254.169.254/latest/meta-data/local-ipv4)
if [ $? -eq 0 ]; then
  /bin/registrator -ip $LOCAL_IP $@
else
  /bin/registrator $@
fi
Rash
  • 7,677
  • 1
  • 53
  • 74