Как я могу заставить Docker составить "wait-for-it" script вызвать оригинальный контейнер ENTRYPOINT или CMD?

В соответствии с контролем порядка запуска в Compose можно управлять порядком, в котором Docker Compose запускает контейнеры используя wait-for-it "script. Script wait-for-it.sh ожидает как аргумент host:port, так и команду, которую должен выполнить Script, когда порт доступен. В документации рекомендуется, чтобы Docker Compose вызывал этот Script с помощью параметра entrypoint:. Однако, если вы используете эту опцию, контейнер больше не будет запускать свои настройки по умолчанию ENTRYPOINT или CMD, потому что entrypoint: переопределяет значение по умолчанию.

Как можно предоставить эту команду по умолчанию для wait-for-it.sh, чтобы Script мог вызывать по умолчанию ENTRYPOINT или CMD, когда условие, для которого оно ожидает, выполнено?

В моем случае я внедрил Script wait-for-file.sh, что опросы ожидают существования файла:

#!/bin/bash

set -e

waitFile="$1"
shift
cmd="[email protected]"

until test -e $waitFile
do
  >&2 echo "Waiting for file [$waitFile]."
  sleep 1
done

>&2 echo "Found file [$waitFile]."
exec $cmd

Docker Compose вызывает wait-for-file.sh как точку входа в немного настраиваемый контейнер, полученный из tomcat:8-jre8:

  platinum-oms:
    image: opes/platinum-oms
    ports:
      - "8080:8080"
    volumes_from:
      - liquibase
    links:
      - postgres:postgres
      - activemq:activemq
    depends_on:
      - liquibase
      - activemq
    entrypoint: /wait-for-file.sh /var/run/liquibase/done

Перед тем, как он успешно завершит работу, другой пользовательский контейнер liquibase создает /var/run/liquibase/done, и поэтому platinum-oms фактически ожидает завершения контейнера liquibase.

Как только контейнер liquibase создает файл /var/run/liquibase/done, wait-for-file.sh печатает Found file [/var/run/liquibase/done]., но не может вызывать команду по умолчанию catalina.sh run в базовом контейнере tomcat:8-jre8. Почему?

Сценарий тестирования

Я создал упрощенный тестовый сценарий docker-compose-wait-for-file, чтобы продемонстрировать свою проблему. Контейнер ubuntu-wait-for-file ждет контейнер ubuntu-create-file для создания файла /wait/done, а затем я ожидаю, что контейнер ubuntu-wait-for-file вызовет команду контейнера ubuntu по умолчанию /bin/bash по умолчанию, но вместо этого он выйдет. Почему он не работает, как я ожидаю?

Ответы

Ответ 1

Однако, если вы используете эту опцию, контейнер больше не будет выполнять свою команду по умолчанию ENTRYPOINT или CMD, поскольку entrypoint: переопределяет значение по умолчанию.

Это ожидается, поэтому wait-for-it представлен как обертка script.
Это позволяет выполнять "подкоманду", хотя:

wait-for-it.sh host:port [-s] [-t timeout] [-- command args]
                                               ^^^^^^^^^^^^

Подкоманда будет выполнена независимо от того, включена ли служба или нет.
Если вы хотите выполнить подкоманду только в том случае, если служба завершена, добавьте аргумент --strict.

Это означает, что часть вашего изображения CMD может использоваться для вашей фактической команды контейнера, поскольку ее параметры передаются в параметрах команде ENTRYPOINT:

entrypoint: wait-for-it.sh host:port --
cmd: mycmd myargs

Это должно работать... кроме docker-compose issue 3140 (упоминается OP Derek Mahar в комментариях)

точка входа, определенная в docker-compose.yml, удаляет CMD, определенный в файле Docker