docker容器将不会启动,因为现有的PID文件

当我启动docker容器时,它会因为现有的pid文件而失败:

[root@newhope sergio]# docker logs sharp_shockley httpd (pid 1) already running httpd (pid 1) already running httpd (pid 1) already running httpd (pid 1) already running 

我如何删除这样的文件,因为我没有find它。

 [root@newhope sergio]# docker version Client version: 1.4.1 Client API version: 1.16 Go version (client): go1.3.3 Git commit (client): 5bc2ff8/1.4.1 OS/Arch (client): linux/amd64 Server version: 1.4.1 Server API version: 1.16 Go version (server): go1.3.3 Git commit (server): 5bc2ff8/1.4.1 [root@newhope sergio]# find / -name "httpd.pid" find: '/run/user/1000/gvfs': Permiso denegado 

经过太多的挫折,我解决了这个在我打破phabricator容器:

你必须知道http pid文件的名称/path是什么。 在下面的示例中,它位于/run/apache2/apache2.pid内的/run/apache2/apache2.pid 。 一旦你有了,你运行以下:

 docker start [container_id]; docker exec [container_id] rm /run/apache2/apache2.pid 

这样做是启动容器,然后立即尝试运行该命令来删除PID文件 – 希望在任何进程泊坞窗应该启动之前有时间失败。 如果你的容器进程无法快速完成,这可能不适合你。 尝试运行几次,你可能会打败它。

为了find我的PID文件的位置,我做了一些类似于@sebelk的东西,而不是扩展tar文件,我保存了一些时间,只是列出它的内容并寻找正确的文件名就像这样:

 docker export [container_id] > /tmp/brokecontainercontents.tar tar -tf /tmp/brokecontainercontents.tar | less 

这很愚蠢,可能有更好的方法来查看容器的内容。 理想情况下,您可以通过其他方式findPID文件的名称(欢迎评论!)。

顿悟

上面的答案是有用的,但是我现在意识到我和其他许多人在基本的层面上误解了Docker。 事实上,@ styonsk下面的答案是正确的。 而且,@ avijendr对此的评论也是正确的:这将破坏容器中的数据 – 但这不应该成为问题。 我会解释。

我原本被告知Docker“像chroot,但更好”。 这是真实的,但误导。 在一个chroot监狱里,你的数据住在监狱里(当然是这样,被监禁的过程怎么看呢?)。 所以当我开始使用Docker的时候,我认为Volumes特性是一种获取容器中数据的方法 – 您可以将Volume安装到本地系统,并查看其中的内容。 当我尝试的时候,我真的打勾了,因为它就好像容器丢失了我的所有数据 – 容器应用程序的行为,并没有在本地安装的位置! 错错了错。

Docker中的卷将本地数据/文件安装到容器中,而不是其他方式。 所以,当我把卷挂载到一个空的本地目录(预期容器中的文件出现)时,空的本地目录被挂载到容器中,隐藏容器中存在的文件,使得应用看起来像它失去了它的数据(好吧,因为它)。 实际上,Docker容器甚至在没有安装卷的情况下工作的事实是一个副作用,可以说是有害的。 这不是它打算工作的方式。 任何被写入容器内的容器位置的数据都预计是一次性的!

(顺便说一句,我通过Kitematic开始使用Docker,它将一步一步地拉取,创build和启动一个容器, 而不会问你要在哪里安装卷 ,这是我认为错误的想法的一部分…我现在个人认为它不应该启动容器,直到你已经在某处安装了卷或者明确地决定不这样做。)

因此,Docker容器的预期用途通常(也应该是)在容器运行容器应用程序 ,也就是在通过本地系统安装的卷中。 这意味着,如果出现问题, 应该能够销毁容器,并启动另一个安装在相同卷上的副本 – 将所有数据都归还,因为它不在容器中。

因此,@ styonsk的回答是正确的答案:如果您正确使用Docker,则应该能够销毁容器并启动一个新的容器。 一方面这听起来像是矫枉过正,但另一方面,集装箱化的应用程序的重点是,你不必知道它里面发生了什么,可以说你不…你怎么知道唯一的在不洁净的关机后坏掉的东西是httpd.pid文件还在吗? 可能会有更多的事情搞砸,你不知道! 这可以说是抽象是什么。

如果这个模型不适合你的用例 – 或者你不喜欢它 – 答案可能是你不应该使用Docker容器。 这也不是一件坏事,只是你可能试图把一个平头螺丝与一个菲利普斯司机。 您可能只需要一个轻量级但是完整的VM环境。

尝试:

 docker-compose down 

销毁任何已经运行的环境。

重build/重build可能会有帮助。 docker-compose up --build --force-recreate <service-name>

另外,主机(物理服务器)可能没有磁盘空间。

基于Paul的评论和docker文档,我find了解决scheme:

 docker export sharp_shockley > /tmp/sharp_shockley.tar mkdir /tmp/sharp_shockley cd /tmp/sharp_shockley/ tar xvf sharp_shockley.tar rm run/httpd/httpd.pid rm sharp_shockley.tar tar -c . | sudo docker import - apache3 

然后,我必须执行一些小的修复,删除/ var / run / httpd上的临时文件,提交更改,然后我可以再次启动我的容器。

更多信息请参阅https://docs.docker.com/reference/commandline/cli/#import Docker命令行