Запуск службы во время сборки Docker

Я хотел бы запустить службу во время сборки Docker. Мне не нужно, чтобы эта служба продолжала работать после обязательного завершения процесса сборки (или я знаю, что могу использовать для этого команду CMD), однако мне нужно, чтобы она работала достаточно долго, чтобы выполнить вторую команду, которая зависит от этой службы. и работает.

Точнее, я пытаюсь написать Dockerfile для XMPP-сервера ejabberd, который также устанавливает модуль для этого сервера. Я пытаюсь запустить сервер ejabberd с запуском ejabberdctl, а затем установить модуль с помощью утилиты ejabberdctl module_install, которая зависит от того, работает ли узел. Это выглядит так:

RUN ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http

Теперь я столкнулся с проблемой, и я придумал две возможные причины. Проблема в том, что моя сборка не работает с этой строки, потому что нода не работает, когда вторая команда пытается выполниться. Я получаю следующую ошибку, которая является типичной, когда вы пытаетесь использовать утилиту ejabberdctl без фактического включения узла:

Ошибка RPC-подключения к узлу ejabberd@localhost

Команда '/bin/sh -c ejabberdctl start && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http' вернула ненулевой код: 3

Это может быть связано с тем, что запуск службы занимает немного больше времени, чем требуется для выполнения второй команды, поэтому вторая команда работает с узлом, который только запускается. Не уверен, насколько это вероятно. Вторая причина может заключаться в том, что запуск службы, которая зависит от init.d, просто не работает в Docker во время процесса сборки.

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

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


person melaniejb    schedule 13.04.2017    source источник
comment
почему бы вам не проверить свою гипотезу, просто добавив сон? то есть ejabberdctl start && sleep 10 && ejabberdctl modules_update_specs && ejabberdctl module_install ejabberd_auth_http?   -  person Adrian Mouat    schedule 14.04.2017
comment
И вы можете проверить вторую гипотезу, просто имея строку с ejabberdctl start и проверив, не сработает ли она.   -  person Adrian Mouat    schedule 14.04.2017
comment
Первая версия с sleep 10 сделала свое дело! Модуль был успешно установлен, так что на самом деле это была проблема с синхронизацией. Есть ли более приятный способ исправить это, чем использовать сон? Я видел несколько решений для внешнего сценария оболочки, который запускается после запуска службы и работает в цикле, пока не найдет процесс в списке процессов. Не уверен, что это немного..   -  person melaniejb    schedule 18.04.2017


Ответы (1)


Эти *ctl программы обычно поставляются с несколькими утилитами для запуска/остановки/мониторинга состояния службы.

В вашем случае, я думаю, лучше всего иметь простой скрипт bash, который вы можете запустить во время сборки, который делает это:

  • начать эджабберд
  • следить за состоянием через определенные промежутки времени
  • если статус процесса поднялся, запустите свою команду

Посмотри на это:

root@158479dec020:/# ejabberdctl status
Failed RPC connection to the node ejabberd@158479dec020: nodedown
root@158479dec020:/# echo $?
3
root@158479dec020:/# ejabberdctl start 
root@158479dec020:/# echo $?
0
root@158479dec020:/# ejabberdctl status
The node ejabberd@158479dec020 is started with status: started
ejabberd 16.01 is running in that node
root@158479dec020:/# echo $?
0
root@158479dec020:/# ejabberdctl stop  
root@158479dec020:/# echo $?
0
root@158479dec020:/# ejabberdctl status
Failed RPC connection to the node ejabberd@158479dec020: nodedown
root@158479dec020:/# echo $?
3

Таким образом, это говорит нам о том, что если вы запускаете ejabberd status, а демон не работает, вместо этого вы получаете код выхода 3, 0, если он запущен и работает.

Вот вам и ваш скрипт bash:

function run() {
  ejabberdctl start # Repeating just in case...
  ejabberdctl status &>/dev/null

  if [ $? -eq 0 ]; then
    echo "Do some magic here, ejabberd is running..."
    exit 0
  fi 

  echo "Ejabberd still down..."
}

while true; do run; sleep 1; done

И это то, что вы получите в CLI:

root@158479dec020:/# ./check.sh 
Ejabberd still down...
Do some magic here, ejabberd is running...
root@158479dec020:/# ejabberdctl stop
root@158479dec020:/# ./check.sh 
Ejabberd still down...
Ejabberd still down...
Do some magic here, ejabberd is running...
person odino    schedule 05.03.2018