为什么 docker 从 docker 文件构建镜像会在构建错误退出时创建容器?
Why docker build image from docker file will create container when build exit incorrectly?
我正在使用 docker 从 docker 文件构建图像。在此过程中发生了一些错误,因此构建退出并显示错误代码。
当我 运行 docker images
我可以看到未标记的图像。所以我试图删除它 docker rmi xxxxx
。但它总是失败,它说无法删除图像,因为它被停止的容器使用。
所以我挖得更深一点。我 运行 docker ps -a
,现在我可以看到一长串在构建过程失败时创建的已停止容器。
为什么会创建容器??我以为图像就像编程中"class"的概念,容器是class的实例。镜像构建成功之前,为什么会创建实例?我如何在没有所有这些已停止容器的情况下构建映像?
Dockerfile 的每一行都会创建一个中间容器来执行该行的 Dockerfile 指令。
如果指令成功,将创建一个中间映像,它将作为下一个要启动的容器的基础(以执行 Dockerfile 的下一行)
如果上述指令失败,容器将处于退出状态,这反过来会阻止创建它的中间图像。
只需 ,然后重试。
如果您尝试反复构建 Dockerfile,您最终会得到中间图像和容器的集合。
这就是为什么当我的构建(最终)成功时,我总是在我的 build script:
中清理额外的容器、图像和(docker 1.10+)卷
cmdb="docker build${proxy}${f} -t "
# 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
构建过程正在为 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
为了加快构建过程,中间容器将用作缓存。这些容器将在成功构建后被删除,但当您尝试多次构建时,'old' 中间容器和图像仍将在您的系统上。
如果您希望在构建完成后保留中间容器,则必须使用 --rm=false
。默认情况下它是 true
所以在成功构建后中间容器将被删除。当在使用中间容器期间构建失败时,该容器将退出。中间 'image for this container' 有标签 <none>:<none>
并且不能正常删除,因为有一个(兴奋的)容器来自这个图像。您可以使用 -f(强制)标志删除图像:docker rmi -f image-id
我正在使用 docker 从 docker 文件构建图像。在此过程中发生了一些错误,因此构建退出并显示错误代码。
当我 运行 docker images
我可以看到未标记的图像。所以我试图删除它 docker rmi xxxxx
。但它总是失败,它说无法删除图像,因为它被停止的容器使用。
所以我挖得更深一点。我 运行 docker ps -a
,现在我可以看到一长串在构建过程失败时创建的已停止容器。
为什么会创建容器??我以为图像就像编程中"class"的概念,容器是class的实例。镜像构建成功之前,为什么会创建实例?我如何在没有所有这些已停止容器的情况下构建映像?
Dockerfile 的每一行都会创建一个中间容器来执行该行的 Dockerfile 指令。
如果指令成功,将创建一个中间映像,它将作为下一个要启动的容器的基础(以执行 Dockerfile 的下一行)
如果上述指令失败,容器将处于退出状态,这反过来会阻止创建它的中间图像。
只需
如果您尝试反复构建 Dockerfile,您最终会得到中间图像和容器的集合。
这就是为什么当我的构建(最终)成功时,我总是在我的 build script:
中清理额外的容器、图像和(docker 1.10+)卷cmdb="docker build${proxy}${f} -t "
# 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
构建过程正在为 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
为了加快构建过程,中间容器将用作缓存。这些容器将在成功构建后被删除,但当您尝试多次构建时,'old' 中间容器和图像仍将在您的系统上。
如果您希望在构建完成后保留中间容器,则必须使用 --rm=false
。默认情况下它是 true
所以在成功构建后中间容器将被删除。当在使用中间容器期间构建失败时,该容器将退出。中间 'image for this container' 有标签 <none>:<none>
并且不能正常删除,因为有一个(兴奋的)容器来自这个图像。您可以使用 -f(强制)标志删除图像:docker rmi -f image-id