docker-compose вычислить выражение в массиве команд

У меня ниже файл docker-compose.yml. в command раздел я хотел бы оценить curl выражение перед передачей команды в механизм докера, т.е. мой curl должен быть сначала оценен, а затем мой контейнер должен работать с -ip 10.0.0.2 вариант.

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)']

Это, однако, не оценивается, и мой вариант передается как -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)

Однако соответствующая команда запуска docker правильно оценивает выражение, и мой контейнер правильно запускается с -ip 10.0.0.2 опция:

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)

2 ответа

Решение

Команда docker в командной строке будет работать, так как команда будет выполняться оболочкой, а не образом docker, поэтому она будет разрешена.

docker-compose command переопределит команду по умолчанию (CMD) (см. https://docs.docker.com/compose/compose-file/), поэтому она будет выполняться не до запуска контейнера, а как основная команда в контейнере.,

Вы могли бы сделать что-то вроде:

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

и запустить его с:

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

это снова запустит его в оболочке и присвоит переменной IP, которая будет доступна во время docker-compose up команда. Вы можете поместить эту команду в скрипт оболочки, чтобы упростить ее.

После поиска в Интернете часов и ответов, размещенных здесь, я, наконец, остановился на следующем решении. Для объяснения того, почему это работает, пожалуйста, обратитесь к ответу @Ivonet.

Я модифицировал Dockerfile запустить скрипт при запуске контейнера.

FROM gliderlabs/registrator:v7

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

ENTRYPOINT ["/entrypoint.sh"]

Сценарий entrypoint.sh тоже очень просто. Сначала он проверяет, может ли он вызвать конечную точку. В случае успешного ответа мой контейнер запустится с правильного IP-адреса, а в случае неудачного ответа (для локального тестирования) не будет установлено никакого значения.

#!/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
Другие вопросы по тегам