天天看点

docker如何创建一个运行后台进程的容器并同时提供shell终端

只看标题还不是很明显,本文实现docker的这样一种比较常用的功能:通过<code>docker run</code>启动一个容器后,容器中已经运行了一个后台进程(这里以监听80端口的nginx为例),同时进入一个shell终端可供操作,而不受限于只能在前台运行nginx与运行shell终端之间的一种。这个例子实现了,那么其他类似的运行多任务docker就可以以此类推。另外本文还提供了一种在docker容器内部安装软件(<code>vim</code>)的方法,对于定制自己需要的镜像大有帮助。

使用官方image启动一个容器,名字nginx_dist,把host的目录(包含刚才的html)映射到容器中nginx server的root,绑定80端口:

此时通过浏览器访问主机<code>http://host_ip:port/</code>就可以看到结果了:

docker如何创建一个运行后台进程的容器并同时提供shell终端

熟悉一下docker的命令。

这里有个未解决的问题,能否有办法在上面已经启动的container的基础上执行命令?官方没有这样的支持。

目前只能重新启动一个容器(停止上面的<code>nginx_dist</code>容器)

但此时nginx服务是停止的,并没有在后台运行,访问<code>http://host_ip:port/</code>无效。为了后面编辑配置文件方便,我们先把<code>vim</code>安装好。

容器内部的网络与容器外部是相同的,并与host具有相同的dns,所以可以使用公网软件(<code>cat /etc/apt/sources.list</code>)镜像源来安装。

实现这一步的方法有许多种,比如

也就是用第4步的方法先启动到<code>/bin/bash</code>,再手动运行<code>/usr/sbin/nginx -c /etc/nginx/nginx.conf</code>或<code>service nginx start</code>,很容易想到,但太麻烦。

将装好vim的容器提交成新的image,然后通过<code>dockerfile</code>来自定义要启动哪些服务。关于<code>dockerfile</code>后面我也会写文章来单独介绍其语法。

最后一条<code>docker run</code>之后就会自动进入<code>bash</code>终端,同时发现<code>nginx</code>服务也启动了,可以通过<code>vim</code>来编辑配置文件。

保存后直接ctrl+d退出,在<code>start</code>就可以访问了,如果要进入终端就<code>attach</code>,如果需要可以<code>commit</code>成一个镜像。

<a href="http://air.googol.im/2014/03/28/supervisor-with-docker-to-manage-processes.html" target="_blank">在docker里使用(支持镜像继承的)supervisor管理进程</a>

从上面的操作中可以看出,<code>start</code>是可以保留<code>run</code>启动时的参数如<code>-v</code>、<code>-p</code>,而<code>commit</code>之后如果没在<code>dockerfile</code>中指定,下次启动依然需要带上目录、端口的映射参数。

另外提一点, <code>docker run -i -t seanlook/nginx:bash_vim</code>启动便会同时进入一个shell界面(但没有启动nginx),因为它的“前身”容器是在shell交互界面下<code>run</code>来的,但也没有保留<code>-v</code>、<code>-p</code>指定的映射关系。

继续阅读