#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