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

时间:2014-08-05 09:53:58

标签: docker

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

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

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

service mysql start

运行docker容器时,如何自动启动MySQL服务?

12 个答案:

答案 0 :(得分:181)

首先,Dockerfile

中存在问题
RUN service mysql restart && /tmp/setup.sh

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

CMD mysql start

其次,docker容器需要一个进程(last命令)继续运行,否则容器将退出/停止。因此,正常的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初学者。老实说,这太过分了。对容器使用单个服务/单个命令要好得多。

BTW:请查看https://registry.hub.docker.com以获取现有的mysql docker镜像以供参考

答案 1 :(得分:58)

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

答案 2 :(得分:7)

还有另一种方法,我总是发现它更具可读性。

假设你想要在运行时启动rabbitmq和mongodb,那么你的CMD将会是这样的:

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

由于每CMD只能有一个Dockerfile,所以诀窍是将所有指令与&&连接起来,然后使用\为每个命令启动一个新行。

如果您最终添加到其中的许多内容中,我建议您将所有命令放在脚本文件中并启动它,如@ larry-cai建议:

CMD /start.sh

答案 3 :(得分:4)

简单!在dockerfile的末尾添加:

ENTRYPOINT service mysql start && /bin/bash

答案 4 :(得分:3)

就我而言,我有一个PHP Web应用程序由docker容器中的Apache2提供服务,该容器连接到MYSQL后端数据库。 Larry Cai的解决方案只做了一些修改。我创建了一个entrypoint.sh文件,我在其中管理我的服务。我认为当容器启动时有多个命令要执行时创建一个entrypoint.sh是一种更简洁的方法来引导docker。

#!/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

答案 5 :(得分:1)

以下是每当docker容器运行时我自动启动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。

答案 6 :(得分:1)

当我要自动启动ssh服务时遇到同样的问题。 我发现将

/etc/init.d/ssh start
附加到
~/.bashrc
可以解决它,但是只有您使用bash打开它才可以。

答案 7 :(得分:0)

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

这里也提出了这个问题的一个变体:

答案 8 :(得分:0)

我将以下代码添加到/root/.bashrc以仅运行一次代码,

请在运行此脚本之前将容器提交到图像,否则' 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

答案 9 :(得分:0)

docker export -o <nameOfContainer>.tar <nameOfContainer>

可能需要使用docker prune修剪现有容器...

导入并进行必要的修改:

cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>

运行容器,例如使用always restart选项,以确保它在主机/守护程序回收后自动恢复:

docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash

旁注: 在我看来,合理的是只启动cron服务,尽可能保持容器干净,然后只需修改crontab或cron.hourly,.daily等...以及相应的检查/监控脚本。原因是您只依赖一个守护进程,并且在更改的情况下,使用ansible或puppet重新分发cron脚本而不是在引导时启动的跟踪服务更容易。

答案 10 :(得分:0)

这不起作用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

答案 11 :(得分:0)

如果您无法更改 docker 文件 /docker 镜像。 这是解决方法:

docker run imageid bash -c 'service mysql start ;虽然是真的;睡100;完毕; '