Как я могу заставить 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