6

I'm using docker to build images from a docker file. In the process there's some error happened, so the build exit with error code.

When I run docker images I can see a untagged image. so I tried to remove it docker rmi xxxxx. But it always fails, it says the images can't be removed because it's used by a stopped container.

So I dig a little deeper. I run docker ps -a, now I can see a long list of stopped container which are created when the build process fails.

Why there will be container created?? I thought image is like the concept of "class" in programming, and container is instance of the class. Before the image is successfully built, why there'll be instance created? How can I build image without all those stopped containers ?

4

2 回答 2

6

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

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

如果所述指令失败,则可能会使容器处于退出状态,这反过来又会阻止从中创建它的中间映像。
只需清理所有容器,然后清理所有图像,然后重试。

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

这就是为什么当我的构建(最终)成功时,我总是在构建脚本中清理额外的容器、图像和(使用 docker 1.10+)卷:

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
于 2016-04-23T09:04:25.487 回答
2

构建过程正在为 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

于 2016-04-23T09:08:37.760 回答