我有一个Dockerfile将MySQL服务器安装在一个容器中,然后像这样开始:
sudo docker run -t -i 09d18b9a12be /bin/bash
但是MySQL服务不会自动启动,我必须手动运行(从容器内部):
service mysql start
运行docker容器时如何自动启动MySQL服务?
我有一个Dockerfile将MySQL服务器安装在一个容器中,然后像这样开始:
sudo docker run -t -i 09d18b9a12be /bin/bash
但是MySQL服务不会自动启动,我必须手动运行(从容器内部):
service mysql start
运行docker容器时如何自动启动MySQL服务?
Answers:
首先,有一个问题,在您的Dockerfile
:
RUN service mysql restart && /tmp/setup.sh
Docker映像不会保存正在运行的进程。因此,您的RUN
命令仅在docker build
阶段执行,并在构建完成后停止。相反,当使用以下命令CMD
或时,需要在启动容器时指定命令ENTRYPOINT
:
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
,不建议使用。老实说,这太过分了。最好对容器使用单个服务/单个命令。
顺便说一句:请检查https://registry.hub.docker.com以获取现有的mysql docker镜像以供参考
docker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
在您的中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
docker stop
或者docker restart
可以被杀死。
我一直发现还有另一种方法可以使可读性更高。
假设您要在运行它时启动rabbitmq和mongodb,那么您CMD
将看起来像这样:
CMD /etc/init.d/rabbitmq-server start && \
/etc/init.d/mongod start
由于CMD
每个选项只能包含一个,Dockerfile
因此把所有指令连接在一起&&
,然后\
对每个命令使用它来开始新的一行。
如果最后添加了许多命令,我建议您将所有命令都放在脚本文件中,然后像@ larry-cai建议的那样启动它:
CMD /start.sh
就我而言,我有一个由Apache2提供服务的PHP Web应用程序,该容器由Docker容器连接至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
ENTRYPOINT ['your location']
指令指向脚本文件。但是请记住要在脚本上设置执行权限。COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]
。在此示例中,我将入口点复制到Docker容器中的根目录。
这是我在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网站上的以下文档显示了如何在Docker容器中实现SSH服务。它应该很容易适应您的服务:
这里也有人问过这个问题:
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脚本,而不是跟踪启动时启动的服务。