Я'видел кучу руководств, которые вроде бы делают то же самое, что и я'пытаюсь сделать, но по какой-то причине мои Docker-контейнеры выходят. По сути, я устанавливаю веб-сервер и несколько демонов внутри контейнера Docker. Я делаю последние части этого через сценарий bash под названием run-all.sh
, который я запускаю через CMD в моем Dockerfile. run-all.sh
выглядит следующим образом:
service supervisor start
service nginx start
И я запускаю его внутри моего Dockerfile следующим образом:
CMD ["sh", "/root/credentialize_and_run.sh"]
Я вижу, что все службы запускаются правильно, когда я запускаю все вручную (т.е. подключаюсь к образу с помощью -i -t /bin/bash), и все выглядит так, будто запускается правильно, когда я запускаю образ, но он завершает работу, как только заканчивает запуск моих процессов. Я хотел бы, чтобы процессы запускались бесконечно, и, насколько я понимаю, контейнер должен продолжать работать, чтобы это произошло. Тем не менее, когда я запускаю docker ps -a
, я вижу:
➜ docker_test docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7706edc4189 some_name/some_repo:blah "sh /root/run-all.sh 8 minutes ago Exited (0) 8 minutes ago grave_jones
Что происходит? Почему он завершается? Я знаю, что могу просто поместить цикл while в конец моего сценария bash, чтобы поддерживать его, но какой правильный способ не дать ему выйти?
Если вы используете файла Docker, попробуйте:
Точки входа [на"хвост" В, С " Ф" и " Ну/dev/нуль", у]
(Очевидно, что это только для целей разработки, вы должны'т нужна, чтобы держать контейнер в живых, если он's идущий процесс, например. с nginx...)
Я просто была такая же проблема, и я узнал, что если вы используете свой контейнер с -т
и -Д
флаг, он продолжает работать.
docker run -td <image>
Вот что делают флаги (по данным `докер запустить - "помощь"):
-d, --detach=false Run container in background and print container ID
-t, --tty=false Allocate a pseudo-TTY
Наиболее важным является-Т флаг.
-д` просто позволяет запускать контейнер в фоновом режиме.
Это не совсем то, как вы должны проектировать свои контейнеры Docker.
При проектировании контейнера Docker вы должны создать его таким образом, чтобы в нем был запущен только один процесс (т.е. у вас должен быть один контейнер для Nginx, и один для supervisord или приложения, которое он запускает); кроме того, этот процесс должен работать на переднем плане.
Контейнер будет "завершаться", когда завершится сам процесс (в вашем случае этим процессом является ваш bash-скрипт).
Однако, если вам действительно нужно (или вы хотите) запустить несколько сервисов в вашем Docker-контейнере, подумайте о том, чтобы начать с "Docker Base Image", который использует runit
в качестве псевдо-запускаемого процесса (runit
будет оставаться онлайн, пока запущены Nginx и Supervisor), который будет оставаться на переднем плане, пока другие ваши процессы делают свое дело.
У них есть подробная документация, так что вы должны быть в состоянии достичь того, что вы пытаетесь сделать, достаточно легко.
Причина его выхода заключается в том, что сценарий оболочки сначала запускается от имени PID 1, а когда он завершается, PID 1 исчезает, а docker запускается только при PID 1.
Вы можете использовать supervisor для выполнения всех действий, если он запущен с флагом "-n", ему сказано не демонетизировать, поэтому он останется первым процессом:
CMD ["/usr/bin/supervisord", "-n"]
И ваш supervisord.conf:
[supervisord]
nodaemon=true
[program:startup]
priority=1
command=/root/credentialize_and_run.sh
stdout_logfile=/var/log/supervisor/%(program_name)s.log
stderr_logfile=/var/log/supervisor/%(program_name)s.log
autorestart=false
startsecs=0
[program:nginx]
priority=10
command=nginx -g "daemon off;"
stdout_logfile=/var/log/supervisor/nginx.log
stderr_logfile=/var/log/supervisor/nginx.log
autorestart=true
Тогда вы можете иметь столько других процессов, сколько захотите, и supervisor будет обрабатывать их перезапуск, если потребуется.
Таким образом, вы можете использовать supervisord в случаях, когда вам нужны nginx и php5-fpm, и нет особого смысла держать их отдельно.
вы можете запустить простой " кот " без каких-либо аргументов как отметил бро @Са'ад, чтобы просто держать контейнер работает [на самом деле ничего не делает, а ждет ввода пользователя] (Дженкинс' Докер плагин делает то же самое)
Убедитесь, что вы добавили daemon off;
в nginx.conf или запустили его с помощью CMD ["nginx", "-g", "daemon off;"]
согласно официальному образу nginx
Затем используйте следующее для запуска supervisor в качестве службы и nginx в качестве фонового процесса, что предотвратит выход контейнера из системы
service supervisor start && nginx
.
В некоторых случаях вам потребуется более одного процесса в контейнере, поэтому принуждение контейнера иметь только один процесс не будет работать и может создать дополнительные проблемы при развертывании.
Поэтому вам нужно понять компромиссы и принять соответствующее решение.
Захват PID процесса ngnix в переменной (например, $NGNIX_PID) и в конце файла точки входа делать
wait $NGNIX_PID
Таким образом, контейнер должен работать до ngnix жив, когда ngnix остановки, контейнера, а также останавливается
Мотивация:
Есть ничего плохого в выполнении нескольких процессов внутри контейнера Docker]1. Если вам нравится использовать Docker в свет ВМ вес - так и будет. Другие, как разделить их применения в микро-услуг. Мне думает: лампы укладывают в один контейнер? Просто замечательно.
Ответ:
Палка с хорошее базовое изображение как phusion базового изображения. Могут быть и другие. Пожалуйста, прокомментируйте.
И это еще просто еще один ратую за руководителем. Потому что phusion основного изображения, обеспечивая руководитель, помимо некоторых других вещей, например, cron и настроить локаль. Вещи вы хотели бы иметь настройки при запуске такая светлая ВМ вес. За то, что он'стоит также обеспечивает SSH-подключения в контейнер.
Само изображение phusion будет просто начать и продолжать работать, если вы вопрос это базовые настройки выполнить оператор:
МОиН@stretchDEV:~$ докер запустить -д phusion/baseimage 521e8a12f6ff844fb142d0e2587ed33cdc82b70aa64cce07ed6c0226d857b367 МОиН@stretchDEV:~$ докер ПС КОМАНДА КОНТЕЙНЕРА ИДЕНТИФИКАТОР ОБРАЗ, СОЗДАННЫЙ СТАТУС Я phusion/baseimage &521e8a12f6ff; я на/sbin/my_init&; 12 секунд назад 11 секунд
Или мертв просто:
Если основной образ не для вас... для быстрого cmd, чтобы сохранить это работает, я бы предположил что-то подобное для bash:
УМК старпома /бин/Баш-с помощью "ловушка : срок ИНТ; спать бесконечности & ждать"и
Или это для busybox:
УМК старпома /Бен/ш-ц "и ловушка : ной ИНТ; (пока, правда; не спать 1000; сделал) &ампер; ждать"и
Это хорошо, потому что он будет выход сразу на докер остановить. Просто сон
или кошка
займет несколько секунд до того, как контейнер выходит.
Как насчет использования надзор форма обслуживания, если такая имеется?
услуги YOUR_SERVICE контролировать
Избавляет от необходимости создания supervisord.conf`и