2016-04-23 48 views
2

我使用docker从docker文件构建图像。在这个过程中发生了一些错误,所以编译出口带有错误代码。为什么docker从docker文件构建图像会在不正确地构建出口时创建容器?

当我运行docker images时,我可以看到未标记的图像。所以我试图删除它docker rmi xxxxx。但它总是失败,它说图像不能被删除,因为它被停止的容器使用。

所以我深入一点。我运行docker ps -a,现在我可以看到构建过程失败时创建的停止容器的长列表。

为什么会有容器创建?我认为图像就像编程中的“类”的概念,而容器是类的实例。在图像成功构建之前,为什么会创建实例?如何在没有所有停止的容器的情况下构建图像?

回答

4

Dockerfile的每一行都会创建一个中间容器来为该行执行Dockerfile指令。

如果指令成功,这将创建一个中间图像,这将是该基地为下一个容器是启动(以执行Dockerfile的下一行)

如果所说的指令失败,则可以离开一个处于Exited状态的容器,这反过来会阻挡它创建的中间图像。
只需cleanup all the containers then all the images,然后重试。

如果您试图重复构建Dockerfile,最终会生成一组中间图像和容器。

这就是为什么,当我的版本(最终)成功,我总是清理多余的容器,图像和(与泊坞窗1.10+)在卷我build script

cmdb="docker build${proxy}${f} -t $1 $2" 
# echo "cmdb='${cmdb}" 
if eval ${cmdb}; then 
    docker rm $(docker ps -qa --no-trunc --filter "status=exited" 2>/dev/null) 2>/dev/null 
    docker rmi $(docker images --filter "dangling=true" -q --no-trunc 2>/dev/null) 2>/dev/null 
    docker volume rm $(docker volume ls -qf dangling=true 2>/dev/null) 2>/dev/null 
    exit 0 
fi 
1

的构建过程创建一个中间的dockerfile中的每一步。就像你可以在这个例子中看到的那样:

... 
Removing intermediate container e07079f73a9f 
Step 3 : RUN cd /opt/ 
---> Running in 78d480a57cca 
---> 324e9006d642 
Removing intermediate container 78d480a57cca 
Step 4 : RUN unzip /opt/mule-ee-distribution-standalone-3.7.3.zip -d /opt/ 
---> Running in 81aa445c770c 
... 
---> e702e1cff4ee 
---> removing intermediate container 81aa445c770c 

为了加快构建过程,中间容器将被用作缓存。这些容器将在成功构建后被删除,但是当您尝试多次构建“旧”中间容器和图像时,它们仍将存在于您的系统中。

如果您希望在构建完成后保留中间容器,则必须使用--rm=false。默认情况下它是true,所以在成功构建之后,中间容器将被删除。在使用中间容器期间构建失败时,该容器将退出。这个容器的中间'图像'有标签<none>:<none>,并且不能正常删除,因为这个图像有一个(兴奋的)容器。您可以使用-f(强制)标志删除图像:docker rmi -f image-id

相关问题