如何在运行Docker容器时自动启动服务?

我有一个Dockerfile在一个容器中安装MySQL服务器,然后我开始像这样:

sudo docker run -t -i 09d18b9a12be /bin/bash 

但MySQL服务不会自动启动,我必须手动运行(从容器内):

 service mysql start 

如何在运行Docker容器时自动启动MySQL服务?

首先,你的Dockerfile存在一个问题

 RUN service mysql restart && /tmp/setup.sh 

Docker镜像不保存正在运行的进程。 因此,您的RUN命令仅在docker build阶段执行,并在构build完成后停止。 相反,您需要使用如下的CMDENTRYPOINT命令来启动容器时指定命令:

 CMD mysql start 

其次,docker容器需要一个进程(最后一个命令)继续运行,否则容器将退出/停止。 因此,正常的service mysql start命令不能直接在Dockerfile中使用。

有三种典型的方法来保持进程运行:

  • 之后使用service命令并追加非尾命令,如tail -F

     CMD service mysql start && tail -F /var/log/mysql/error.log 

当运行单个服务时,这通常是首选,因为它使得docker可以访问输出的日志。

  • 或者使用前台命令来做到这一点

     CMD /usr/bin/mysqld_safe 

这只有在有像mysqld_safe这样的脚本时才有效。

  • 或者把你的脚本包装到start.sh并把它放到最后

     CMD /start.sh 

这是最好的,如果命令必须执行一系列的步骤,再次,/ /start.sh应该保持运行。

注意

不推荐使用supervisord的初学者。 老实说,这是过分的。 对容器使用single service / single命令要好得多。

顺便说一句:请查看https://registry.hub.docker.com现有的mysql docker镜像以供参考

在你的Dockerfile ,在最后一行添加

 ENTRYPOINT service ssh restart && bash 

这个对我有用

这就是结果:

 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 

还有另外一种方法可以做到这一点,我总是发现它更具可读性。

假设你想启动rabbitmq,mongodb,并且你希望在你的docker映像里运行它,那么你的CMD看起来就像这样:

 CMD /etc/init.d/rabbitmq-server start && \ /etc/init.d/mongod start && \ /bin/bash 

由于每个Dockerfile只能有一个CMDDockerfile诀窍是用&&连接所有指令,然后使用\为每个命令启动一个新行,从而使其更具可读性。

如果你最终添加了许多这些,我build议你把所有的命令放在一个脚本文件中,像@ larry-caibuild议的那样启动它:

 CMD /start.sh 

在我的情况下,我有一个PHP Web应用程序,由连接到MYSQL后端数据库的Docker容器内的Apache2提供服务。 拉里蔡的解决scheme进行了小的修改。 我创build了一个我正在pipe理我的服务的entrypoint.sh文件。 我想创build一个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 

简单! 在dockerfile的末尾添加:

 ENTRYPOINT service mysql start && /bin/bash 

以下来自Docker网站的文档显示了如何在Docker容器中实现SSH服务。 它应该很容易适应您的服务:

在这个问题上的一个变种也被问到这里:

  • 使用docker容器自动启动sshd

我将下面的代码添加到/root/.bashrc只运行一次代码,

请在运行此脚本之前将容器提交到映像,否则将在映像中创build“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