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

如何在运行docker容器时自动启动服务?,docker,Docker,我需要在一个容器中安装MySQL服务器,然后像这样开始: sudo docker run -t -i 09d18b9a12be /bin/bash CMD /etc/init.d/rabbitmq-server start && \ /etc/init.d/mongod start 但是MySQL服务不会自动启动,我必须手动运行(从容器中): 如何在运行docker容器时自动启动MySQL服务?docker网站上的以下文档说明了如何在docker容器中实现SSH服务。

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

sudo docker run -t -i 09d18b9a12be /bin/bash
CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start
但是MySQL服务不会自动启动,我必须手动运行(从容器中):


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

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

这里还提出了一个关于这个问题的变体:


首先,您的
Dockerfile中有一个问题

RUN service mysql restart && /tmp/setup.sh
Docker映像不保存正在运行的进程。因此,您的
RUN
命令仅在
docker构建
阶段执行,并在构建完成后停止。相反,您需要在容器启动时使用
CMD
ENTRYPOINT
命令指定该命令,如下所示:

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

解决方案 有三种保持流程运行的典型方法:

  • 使用
    service
    命令并在该命令之后附加非结束命令,如
    tail-F

    CMD service mysql start && tail -F /var/log/mysql/error.log
    
当您运行单个服务时,这通常是首选的,因为它使docker可以访问输出的日志

  • 或者使用前台命令执行此操作

    CMD /usr/bin/mysqld_safe
    
仅当存在类似于
mysqld\u safe
的脚本时,此操作才有效

  • 或者将脚本包装到
    start.sh
    中,并将其放在末尾

    CMD /start.sh
    
如果命令必须执行一系列步骤,这是最好的选择,
/start.sh
应保持运行

注 对于初学者,不建议使用
supervisord
。老实说,这太过分了。最好对容器使用单个服务/单个命令

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

顺便说一句:请检查现有的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时启动它,那么您的
CMD
将如下所示:

sudo docker run -t -i 09d18b9a12be /bin/bash
CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start
因为每个
Dockerfile
只能有一个
CMD
,所以技巧是将所有指令与
&
连接起来,然后对每个命令使用
\
来开始新行

如果您最终添加了许多命令,我建议您将所有命令放在脚本文件中,并按照建议的方式启动:

CMD /start.sh

简单!在dockerfile的末尾添加:

ENTRYPOINT service mysql start && /bin/bash

在我的例子中,我有一个PHP web应用程序,由连接到MYSQL后端数据库的docker容器中的Apache2提供服务。拉里·蔡的解决方案进行了微小的修改。我创建了一个
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

我将以下代码添加到/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

下面是我如何在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在容器中运行。

docker export-o.tar
docker export -o <nameOfContainer>.tar <nameOfContainer>
可能需要使用docker prune修剪现有容器

在需要修改的情况下导入:

cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>
cat.tar | docker导入-c“入口点服务mysql启动&&/bin/bash”-
例如,使用always restart(始终重新启动)选项运行容器,以确保它将在主机/守护程序回收后自动恢复:

docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash
docker run-d-t-i——始终重新启动——name/bin/bash
旁注:
在我看来,合理的做法是只启动cron服务,让容器尽可能干净,然后只修改crontab或cron.hourly、.daily等。。。具有相应的检查/监视脚本。原因是您只依赖一个守护进程,在发生更改的情况下,ansible或puppet更容易重新分发cron脚本,而不是跟踪启动时启动的服务

当我想自动启动ssh服务时,我也遇到了同样的问题。
我发现append/etc/init.d/ssh start to ~/.bashrc可以解决这个问题,但只有用bash打开它才能解决。

这不起作用
CMD服务mysql start&&bin/bash

/etc/init.d/ssh start 这不起作用
CMD服务mysql启动/bin/bash

--我猜交互模式不支持前台

这个有用
CMD服务nginx启动;虽然真实;睡100个;完成

这个有用
CMD服务nginx开始和结束-F/var/log/nginx/access.log


注意,您应该使用不带命令参数的
docker run-p 80:80 nginx\u bash

no,对于一个简单的服务,不需要管理员,这对start用户来说很复杂。您可能希望将dockerfile复制到此处,而不是链接到不再存在的文件。有关supervisord的docker文章现在在此处:我使用了&&tail命令使我的服务正常工作,但需要添加“-cap add SYS\u PTRACE”docker run command.nsenter工具是另一种进入容器的方法,无需安装SSH服务器:。但是这种方法需要访问Docker主机(通常SSH访问是e)