问题
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 ?
回答1:
Each line of your Dockerfile creates an intermediate container to execute the Dockerfile directive for that line.
If the directive succeeds, that will create an intermediate image, which will be the base for the next container to be launch (to execute the next line of your Dockerfile)
If said directive fails, that can leave a container in an Exited state, which in turn will block the intermediate image it was created from.
Simply cleanup all the containers then all the images, and try again.
If you have tried to build repeatedly your Dockerfile, you end up with a collection of intermediate images and containers.
That is why, when my build (finally) succeeds, I always cleanup extra containers, images and (with docker 1.10+) volumes in my 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
回答2:
The build process is creating an intermediate for each step in the dockerfile. Like you can see in this example:
...
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
To speed up the build process the intermediate container will be used as cache. Those containers will be deleted after a succesful build but when you try to build for multiple times the 'old' intermediate containers and image will still be on your system.
If you wish to keep the intermediate containers after the build is complete, you must use --rm=false
. By default it's true
so after a successful build the intermediate containers will be deleted. When a build fails during the use of an intermediate container, than this container will exit. The intermediate 'image for this container' has tags <none>:<none>
and can't be deleted normally because there is an (excited) container which is from this image. You can delete the image by using the -f (force) flag: docker rmi -f image-id
来源:https://stackoverflow.com/questions/36808476/why-docker-build-image-from-docker-file-will-create-container-when-build-exit-in