How to automatically start a service when running a docker container?
我有一个Dockerfile将MySQL服务器安装在一个容器中,然后像这样开始:
1 | sudo docker run -t -i 09d18b9a12be /bin/bash |
但是MySQL服务不会自动启动,我必须手动运行(从容器内部):
1 | service mysql start |
运行docker容器时如何自动启动MySQL服务?
首先,您的
1 | RUN service mysql restart && /tmp/setup.sh |
Docker映像不会保存正在运行的进程。因此,您的
1 | CMD mysql start |
其次,docker容器需要一个进程(最后一个命令)来保持运行,否则该容器将退出/停止。因此,常规
解
保持进程运行的三种典型方法:
-
使用
service 命令并在其后附加非结束命令,例如tail -F 1CMD service mysql start && tail -F /var/log/mysql/error.log
当您运行单个服务时,这通常是首选的,因为这会使docker访问输出的日志。
-
或使用前台命令执行此操作
1CMD /usr/bin/mysqld_safe
仅当存在
-
或将您的脚本包装为
start.sh 并放在最后1CMD /start.sh
如果命令必须执行一系列步骤,这是最好的选择,同样,
注意
对于初学者,不建议使用
顺便说一句:请检查https://registry.hub.docker.com以获取现有的mysql docker镜像以供参考
在您的
1 | ENTRYPOINT service ssh restart && bash |
这个对我有用
结果如下:
1 2 3 4 | root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu * Restarting OpenBSD Secure Shell server sshd [ OK ] root@dccc354e422e:~# service ssh status * sshd is running |
简单!在dockerfile的末尾添加:
1 | ENTRYPOINT service mysql start && /bin/bash |
我一直发现还有另一种方法可以使可读性更高。
假设您要在运行它时启动rabbitmq和mongodb,那么您的
1 2 | CMD /etc/init.d/rabbitmq-server start && \\ /etc/init.d/mongod start |
由于每个
如果最后添加了许多命令,我建议您将所有命令都放在脚本文件中,然后像@ larry-cai建议的那样启动它:
1 | CMD /start.sh |
当我想自动启动ssh服务时遇到同样的问题。
我发现将
1 | /etc/init.d/ssh start |
追加到
1 | ~/.bashrc |
可以解决它,但是只有使用bash打开它才能做到。
就我而言,我有一个由Apache2提供服务的PHP Web应用程序,它在Docker容器中连接到MYSQL后端数据库。 Larry Cai的解决方案进行了少量修改。我创建了一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/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 |
这不起作用
这不起作用
-我猜交互式模式不支持前台。
这有效!
这有效!
注意,您应该使用不带命令参数的
这是我在docker容器运行时自动启动MySQL服务的方式。
就我而言,我不仅需要运行MySQL,还需要运行PHP,Nginx和Memcached
我在Dockerfile中有以下几行
1 2 3 4 | 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在容器中运行。
我将以下代码添加到/root/.bashrc中,以仅运行一次代码,
在运行此脚本之前,请先将容器提交到映像,否则将在映像中创建" docker_services"文件,并且将不运行任何服务。
1 2 3 4 5 6 7 | 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 |
1 | docker export -o <nameOfContainer>.tar <nameOfContainer> |
可能需要使用docker prune修剪现有容器...
导入并进行必要的修改:
1 | cat <nameOfContainer>.tar | docker import -c"ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer> |
例如,使用始终重启选项运行容器,以确保其在主机/守护程序回收后将自动恢复:
1 | docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash |
边注:
在我看来,合理的做法是只启动cron服务,使容器保持尽可能干净,然后仅使用相应的检查/监视脚本修改crontab或cron.hourly,.daily等。原因是您仅依赖一个守护程序,如果发生更改,则使用ansible或puppet更容易重新分发cron脚本,而不是跟踪启动时启动的服务。
Docker网站上的以下文档显示了如何在Docker容器中实现SSH服务。它应该很容易适应您的服务:
- https://docs.docker.com/engine/examples/running_ssh_service/
这里也有人问过这个问题:
- 使用Docker容器自动启动sshd