docker container因为现有的pid文件而无法启动

时间:2015-02-22 03:14:17

标签: 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

如何删除此类文件,因为我找不到它。

[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

7 个答案:

答案 0 :(得分:28)

尝试:

docker-compose down

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

答案 1 :(得分:19)

经过太多的挫折之后,我在破碎的phabricator容器中解决了这个问题:

你必须知道http pid文件的名称/路径是什么。在下面的示例中,它位于容器内的/run/apache2/apache2.pid处。完成后,运行以下命令:

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

这样做是启动容器然后立即尝试运行命令来删除PID文件 - 希望在任何进程docker启动之前有时间失败。如果您的容器进程无法快速执行,则可能对您无效。尝试运行几次,你可能会打败它。

为了找到我的PID文件的位置,我做了类似于@sebelk的操作,但是我没有扩展tar文件,而是通过列出其内容并查找正确的文件名来节省一些时间......就像这样:

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

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

主显

上面的答案很有用,但我现在意识到我和其他许多人在基础层面上误解了Docker。事实上,@ styonsk的下面的回答是正确的。并且,@ avijendr对它的批评性评论也是正确的:这会破坏容器中的数据 - 但这并不重要。我会解释一下。

我最初被告知Docker“像chroot但更好。”这是真实但有误导性的。在chroot jail中,你的数据存在于jail中(当然它确实存在,被监禁的进程还会看到它吗?)。因此,当我开始使用Docker时,我认为Volumes功能是一种获取容器中数据的方法 - 您可以将Volume安装到本地系统并查看其中的内容。当我尝试的时候,我真的被勾掉了,因为好像容器丢失了我的所有数据 - 容器应用程序采取了这种方式,并且本地安装位置没有任何东西!错误的错误。

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

(顺便提一下,我开始通过Kitematic使用Docker,它将在一步中拉动,创建和启动一个容器,而无需询问您要在哪里安装卷,这是我认为错误的想法的一部分...我现在个人认为它不应该启动容器,直到您在某处安装了卷或明确决定不这样做。)

因此,Docker容器的预期用途通常是(并且应该)在容器中运行应用程序,该容器作用于容器外数据的容器,即通过本地系统挂载的卷。这意味着你应该能够破坏容器,如果它出现问题并启动另一个副本挂载到相同的卷 - 你得到所有数据,因为它不在容器中首先。

因此,@ styonsk的答案是正确的答案:如果你正确使用Docker,你应该能够销毁容器并启动一个新的容器。一方面,这听起来有点矫枉过正,但另一方面,容器化应用程序的要点是你不必知道它内部发生了什么,可以说你不知道...你怎么知道唯一的在一次不干净的关机后,httpd.pid文件仍然存在?可能会有更多搞砸你不知道的事情!这可以说是抽象的目的。

如果该模型不适用于您的用例 - 或者您根本不喜欢它 - 答案可能是您不应该使用Docker容器。这也不是一件坏事,只是你可能试图用菲利普斯的驱动程序安装一个平头螺钉。您可能只需要一个轻量级但全栈的VM环境。

答案 2 :(得分:5)

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

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

答案 3 :(得分:0)

根据Paul的评论和docker文档,我找到了解决方案:

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 Command Line

的更多信息

答案 4 :(得分:0)

您不需要破坏容器。由于您没有正确停止容器,因此仍有一些碎片悬在周围。具体来说,网络仍连接到容器。

尝试:docker network list

您会看到类似的内容:

NETWORK ID          NAME                             DRIVER              SCOPE
3d8f4b8ce4e5        bridge                           bridge              local
5ec8cb6bbe44        folderNameOfContainer_default    bridge              local
2503d2978229        host                             host                local

然后您需要做的就是断开连接:

docker network disconnect folderNameOfContainer_default my_container_name

docker-compose down也很好,但严格来说没有必要。

答案 5 :(得分:0)

某种程度上,只有失败对我不起作用。 到目前为止,对我来说最好的解决方案是制作一个如下所示的bash文件。我自己测试了很多次,做了必要的修改。

#!/usr/bin/env bash
# chmod +x start_dockers.sh
# ./start_dockers.sh

sudo docker-compose down

#stop all containers
sudo docker stop $(docker ps -aq)

sudo docker-compose up --build

答案 6 :(得分:0)

我不是 Docker 专家,但是为本地网站清除容器的缓存就成功了。