Как автоматически запустить службу при запуске контейнера докеров?
У меня есть Dockerfile для установки сервера MySQL в контейнере, который я начинаю следующим образом:
sudo docker run -t -i 09d18b9a12be /bin/bash
Но служба MySQL не запускается автоматически, мне приходится вручную запускать (изнутри контейнера):
service mysql start
Как автоматически запустить службу MySQL при запуске контейнера докеров?
Ответы
Ответ 1
Во-первых, в вашем Dockerfile
есть проблема:
RUN service mysql restart && /tmp/setup.sh
Образы Docker не сохраняют запущенные процессы. Поэтому ваша команда RUN
выполняется только во время фазы docker build
и останавливается после завершения сборки. Вместо этого вам нужно указать команду при запуске контейнера с помощью команд CMD
или ENTRYPOINT
как ENTRYPOINT
ниже:
CMD mysql start
Во-вторых, контейнеру Docker необходим процесс (последняя команда) для продолжения работы, в противном случае контейнер выйдет/остановится. Следовательно, обычная service mysql start
команда service mysql start
не может использоваться непосредственно в Dockerfile.
Решение
Существует три типичных способа поддержания процесса в рабочем состоянии:
Это часто предпочтительнее, когда у вас запущена одна служба, поскольку она делает выводимый журнал доступным для докера.
Это работает, только если есть скрипт, такой как mysqld_safe
.
Это лучше всего, если команда должна выполнить серию шагов, опять же, /start.sh
должен оставаться запущенным.
Заметка
Для начинающих использовать supervisord
не рекомендуется. Честно говоря, это излишне. Гораздо лучше использовать одну команду service/single для контейнера.
Кстати: пожалуйста, проверьте https://registry.hub.docker.com для существующих изображений MySQL Docker для справки
Ответ 2
В Dockerfile
добавить в последнюю строку
ENTRYPOINT service ssh restart && bash
Это работает для меня
И это результат:
[email protected]:/home/vagrant/docker/add# docker run -i -t ubuntu
* Restarting OpenBSD Secure Shell server sshd [ OK ]
[email protected]:~# service ssh status
* sshd is running
Ответ 3
Есть другой способ сделать это, который я всегда находил более читабельным.
Скажем, что вы хотите запустить rabbitmq и mongodb при запуске, тогда ваш CMD
будет выглядеть примерно так:
CMD /etc/init.d/rabbitmq-server start && \
/etc/init.d/mongod start
Поскольку вы можете иметь только один CMD
каждого Dockerfile
уловка состоит в том, чтобы Dockerfile
все инструкции с &&
а затем использовать \
для каждой команды, чтобы начать новую строку.
Если вы добавите ко многим из них, я предлагаю вам поместить все свои команды в файл сценария и запустить его так, как предложил @larry-cai:
CMD /start.sh
Ответ 4
Simple! Добавить в конце файла docker:
ENTRYPOINT service mysql start && /bin/bash
Ответ 5
В моем случае у меня есть веб-приложение PHP, обслуживаемое Apache2 в контейнере докеров, который подключается к базе данных бэкэнда MYSQL. Решение Larry Cai работало с небольшими изменениями. Я создал файл entrypoint.sh
, в котором я управляю своими услугами. Я думаю, что создание entrypoint.sh
, когда у вас есть несколько команд для запуска, когда ваш контейнер запускается, является более чистым способом загрузочного докера.
#!/bin/sh
set -e
echo "Starting the mysql daemon"
service mysql start
echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite
a2enmod headers
service apache2 restart
a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload
if [ -z "$1" ]
then
exec "/usr/sbin/apache2 -D -foreground"
else
exec "$1"
fi
Ответ 6
Вот как я автоматически запускаю службу MySQL всякий раз, когда запускается контейнер докеров.
В моем случае мне нужно запустить не только MySQL, но также PHP, Nginx и Memcached
У меня есть следующие строки в Dockerfile
RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 3306
CMD service mysql start && service php-fpm start && nginx -g 'daemon off;' && service memcached start && bash
Добавление && bash будет поддерживать Nginx, MySQL, PHP и Memcached в контейнере.
Ответ 7
У меня та же проблема, когда я хочу автоматически запустить службу SSH. Я обнаружил, что добавление
/etc/init.d/ssh start
к ~/.bashrc
может разрешить его, но только вы откроете его с помощью bash.
Ответ 8
В следующей документации веб-сайта Docker показано, как реализовать службу SSH в контейнере докеров. Он должен быть легко адаптирован для вашего обслуживания:
Здесь также задан вариант по этому вопросу:
Ответ 9
Я добавляю следующий код в /root/.bashrc для запуска кода только один раз,
Пожалуйста, перенесите контейнер в изображение перед запуском этого script, иначе файл "docker_services" будет создан на изображениях, и никакая служба не будет запущена.
if [ ! -e /var/run/docker_services ]; then
echo "Starting services"
service mysql start
service ssh start
service nginx start
touch /var/run/docker_services
fi
Ответ 10
docker export -o <nameOfContainer>.tar <nameOfContainer>
Возможно, нужно удалить существующий контейнер, используя docker prune...
Импорт с необходимыми изменениями:
cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>
Например, запустите контейнер с параметром всегда перезапускать, чтобы убедиться, что он автоматически возобновит работу после перезагрузки хоста/демона:
docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash
Примечание: на мой взгляд, разумно запускать только службу cron, оставляя контейнер максимально чистым, а затем просто модифицируйте crontab или cron.hourly,.daily и т.д.... с помощью соответствующих сценариев проверки/мониторинга. Причина в том, что вы полагаетесь только на одного демона, и в случае изменений с ansible или puppet легче перераспределить скрипты cron вместо отслеживания сервисов, которые запускаются при загрузке.
Ответ 11
Это не работает CMD service mysql start &&/bin/bash
Это не работает CMD service mysql start ; /bin/bash ;
CMD service mysql start ; /bin/bash ;
- Я думаю, интерактивный режим не будет поддерживать передний план.
Это работает !! CMD service nginx start; while true; do sleep 100; done;
Это работает !! CMD service nginx start && tail -F/var/log/nginx/access.log
будьте осторожны, вы должны использовать docker run -p 80:80 nginx_bash
без параметра команды.