Как запустить контейнер docker после успешного завершения сценария ожидания

#mysql #node.js #bash #docker

#mysql #node.js #bash #docker

Вопрос:

Я использую сценарий ожидания, чтобы проверить, запущена ли база данных, прежде чем запускать другое приложение.

 #!/bin/bash

set -e

host="$1"
shift
cmd="$@"

until psql -h "$host" -U "postgres" -c 'l'; do
  >amp;2 echo "Postgres is unavailable - sleeping"
  sleep 1
done

>amp;2 echo "Postgres is up - executing command"
exec $cmd
  

Я нашел этот скрипт здесь.
Теперь мое приложение-контейнер перестает работать MySQL is up - executing command .
Итак, сценарий прошел успешно (db запущен), но мне непонятно, как выполнить реальный CMD (после сценария), который находится в моем dockerfile моего приложения.

Это конец моего dockerfile:

 COPY docker-entrypoint.sh /entrypoint.sh
COPY ./wait-for-it.sh wait-for-it.sh
ENTRYPOINT ["/entrypoint.sh"]

EXPOSE 2368
CMD ["npm", "start"]
  

Комментарии:

1. Вы можете удалить ENTRYPOINT и поместить оба в CMD : CMD /entrypoint.sh amp;amp; npm start .

2. Привет, я сделал то, что вы сказали, но, похоже, все еще не удается выполнить команду в CMD после успешной проверки psql. Итак, изображение построено, мой docker-compose выполняет сценарий ожидания, он успешен, поэтому мой контейнер может запуститься, но там все идет не так. Ничего не происходит

3. Я думаю, что сценарию ожидания нужны аргументы. Попробуйте /entrypoint.sh localhost npm start . Извините, я не могу протестировать прямо сейчас, так как у меня нет Linux box.

Ответ №1:

Давайте сначала проясним пару вещей. Когда вы используете оба ENTRYPOINT и CMD в Dockerfile, CMD значение передается в ENTRYPOINT качестве параметра. Итак, то, что у вас сейчас есть в файле, преобразуется в

 /entrypoint.sh npm start
  

Это выполняется при запуске контейнера. Не зная, что происходит entrypoint.sh , трудно сказать, какое влияние это оказывает.

Docker

Вы могли бы внести следующие изменения, пожалуйста, попробуйте:

  • Удалите ENTRYPOINT из Dockerfile .
  • Измените CMD на следующее:

     CMD /wait-for-it.sh localhost amp;amp; /entrypoint.sh npm start
      

При этом, пожалуйста, настройте следующее:

  • Путь для wait-for-it.sh — пожалуйста, настройте туда, куда вы копируете файл скрипта в Dockerfile. Я предлагаю вам скопировать его в ту же папку, entrypoint.sh что и .
  • localhost Аргумент для файла wait-for-it.sh скрипта, пожалуйста, замените на ваш хост базы данных.

Что делает вышеупомянутое, так это запуск wait-for-it.sh скрипта, а затем, как только база данных запущена, она выполняет предыдущую команду, которую вы использовали в ENTRYPOINT and CMD . Он должен быть сопоставим с тем, что у вас есть в настоящее время.

В качестве альтернативы вы также можете вызвать wait-for-it.sh скрипт из своего entrypoint.sh скрипта и выполнить только дополнительные шаги ( npm start после успешного завершения сценария ожидания). Решать вам…

Docker-Compose

Если вы используете Docker-Compose для запуска ваших контейнеров, вы можете перезаписать команду, которая выполняется, когда контейнер начинает использовать command атрибут в вашем docker-compose.yaml файле, например

 command: >
  bash -c "

  /wait-for-it.sh localhost 
  amp;amp; /entrypoint.sh npm start
  "
  

Пожалуйста, обратите внимание на использование

  • bash -c для запуска нескольких команд с использованием выбранной вами оболочки (в данном случае Bash)
  • кавычки, они понадобятся вам для нескольких строк.

Используя этот метод, вы можете в основном связывать несколько команд для запуска друг за другом, комбинируя их с помощью amp;amp; оператора.

Сценарий ожидания

Кстати: я использую этот сценарий ожидания для аналогичной цели с хорошими результатами таким же образом, как описано выше. Он немного более надежен, чем ваша версия сценария ожидания, и поддерживает практически любую комбинацию хост / порт. Я использую его для ожидания MySQL — ваш вопрос неясен, касается ли он MySQL или PostgreSQL.

Комментарии:

1. спасибо за ваш ответ. Я использую mysql, но скрипт скопирован из документации docker, но адаптирован для mysql и работает хорошо. Я также пытаюсь запустить его с помощью docker-compose, так что мне все еще нужно редактировать dockerfile?

2. Я обновил ответ разделом о Docker-Compose