Подтвердить что ты не робот

Запуск службы автоматически в контейнере докера

Я создаю простой образ: тот, который содержит Riak (база данных NoSQL). Изображение запускает службу Riak с riak start как CMD. Теперь, если я запускаю его как демон с помощью docker run -d quintenk/riak-dev, он запускает процесс Riak (я вижу это в журналах). Однако через несколько секунд он автоматически закрывается. Если я запускаю его с помощью docker run -i -t quintenk/riak-dev /bin/bash, процесс riak не запускается (UPDATE: см. Ответы для объяснения этого). Фактически, никакие службы не работают вообще. Я могу запустить его вручную с помощью терминала, но я бы хотел, чтобы Riak начал автоматически. Я полагаю, что это поведение будет происходить и для других сервисов, а Riak - всего лишь пример.

Итак, запуск/перезапуск контейнера должен автоматически запускать Riak. Каков правильный подход к настройке?


Для справки, вот файл Docker, с помощью которого можно создать изображение (UPDATE: изменено с помощью выбранного ответа):

FROM ubuntu:12.04
RUN apt-get update
RUN apt-get install -y openssh-server curl 
RUN curl http://apt.basho.com/gpg/basho.apt.key | apt-key add -
RUN bash -c "echo deb http://apt.basho.com precise main > /etc/apt/sources.list.d/basho.list"
RUN apt-get update
RUN apt-get -y install riak
RUN perl -p -i -e 's/(?<=\{http,\s\[\s\{")127\.0\.0\.1/0.0.0.0/g' /etc/riak/app.config
EXPOSE 8098 
CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

EDIT: -f изменен на -F в CMD в соответствии с sesm его замечанием


МОЙ СОБСТВЕННЫЙ ОТВЕТ

После работы с Docker в течение некоторого времени я взял привычку использовать supervisord для настройки моих процессов. Если вам нужен пример кода для этого, посмотрите https://github.com/Krijger/docker-cookbooks. Я использую свое изображение супервизора в качестве базы для всех моих других изображений. Я написал блог с помощью супервизора здесь.

4b9b3361

Ответ 1

Чтобы контейнеры-докеры работали, вам необходимо сохранить активный процесс на переднем плане.

Итак, вы могли бы заменить эту последнюю строку в файле Docker с помощью

CMD /bin/riak console

Или даже

CMD /bin/riak start && tail -F /var/log/riak/erlang.log.1

Обратите внимание, что вы не можете иметь несколько строк инструкций CMD, только последний запускается.

Ответ 2

Использование хвоста для хранения контейнера в живых - это взломать. Также обратите внимание, что с контейнером -f будет завершаться, когда произойдет поворот журнала (этого можно избежать, используя вместо этого -f).

Лучшим решением является использование supervisor. Взгляните на этот учебник о запуске Riak в контейнере Docker.

Ответ 3

Объяснение:

Если я запустил его с помощью docker run -i -t quintenk/riak-dev /bin/bash, процесс riak не запускается

выглядит следующим образом. Использование CMD в Dockerfile на самом деле та же самая функциональность, что и запуск контейнера с помощью docker run {image} {command}. Как заметил Гигабла, используется только последний CMD, поэтому файл, написанный в файле Docker, перезаписывается в этом случае.

Используя CMD /bin/riak start && tail -f /var/log/riak/erlang.log.1 в Buildfile, вы можете запустить контейнер как фоновый процесс, используя docker run -d {image}, который работает как прелесть.

Ответ 4

"Если я запустил его с помощью docker run -i -t quintenk/riak-dev/bin/ bash, процесс riak не запущен"

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

В образ/контейнер добавьте команды, которые вы хотите автоматически запустить в конец файла /etc/bash.bashrc.

В вашем случае просто добавьте строку /bin/riak start && tail -F /var/log/riak/erlang.log.1 или поместите /bin/riak start и tail -F /var/log/riak/erlang.log.1 на отдельные строки в зависимости от желаемой функциональности.

Теперь скопируйте свои изменения в свой контейнер и запустите его снова с помощью docker run -i -t quintenk/riak-dev /bin/bash. Вы найдете команды, которые вы ввели в bashrc, уже запущены, когда вы прикрепляетесь.

Ответ 5

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

[email protected]:~/docker$ sudo docker run -d -t -i -v /raid:/raid -p 4040:4040 subsonic /bin/bash -c 'service subsonic start && read -p "waiting"'
WARNING: Docker detected local DNS server on resolv.conf. Using default external servers: [8.8.8.8 8.8.4.4]
f27229a260c9

[email protected]:~/docker$ sudo docker ps                                                                                                                                     
[sudo] password for arthur: 
ID                  IMAGE               COMMAND                CREATED              STATUS              PORTS
35f253bdf45a        subsonic:latest     /bin/bash -c service   2 days ago          Up 2 days           4040->4040

[email protected]:~/docker$ sudo docker attach 35f253bdf45a

[email protected]:~/docker$ sudo docker ps                                                                                                                                     
ID                  IMAGE               COMMAND             CREATED             STATUS              PORTS

поскольку вы можете видеть, что контейнер выходит после его присоединения и разблокирует чтение. Разумеется, вы можете использовать более сложный script, чем read -p, если вам нужно выполнить другую очистку, например, остановку сервисов и сохранение журналов и т.д.