Docker rmi - Is it okay to use --force?

Docker doesn't copy the image data to each container, all the containers running the image have a read only pointer to that part of the filesystem (with their own local RW layer for the individual containers). So if you delete an image while a container is using it, you would break the container and overlay filesystem that it depends on.

Instead, just remove the container first. It may be exited rather than running, so you can do a docker ps -a | grep $image_id for a quick list of containers running that specific image id, but the preferred list would include any descendants:

docker rm $(docker ps -aq --filter "ancestor=747cb2d60bbe")

Then you'll be able to run your docker image rm (or docker rmi) command.


Update: If you force remove an image, all docker does is untag it. The image layers still exists on the filesystem until the container is deleted and then you can delete those image layers. E.g.:

/ $ docker run -d --rm busybox tail -f /dev/null
dac68c445371feab453ba3e3fc80efee52043f6b177fd0a71d0b55b38753f2cf

/ $ docker image rm busybox
Error response from daemon: conflict: unable to remove repository reference "busybox" (must force) - container dac68c445371 is using its referenced image 020584afccce

/ $ docker image rm --force busybox
Untagged: busybox:latest
Untagged: busybox@sha256:1303dbf110c57f3edf68d9f5a16c082ec06c4cf7604831669faf2c712260b5a0

/ $ docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              020584afccce        2 weeks ago         1.22MB

Even after deleting the container the layers are still there:

/ $ docker ps -l
CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS               NAMES
dac68c445371        020584afccce        "tail -f /dev/null"   52 seconds ago      Up 50 seconds                           brave_yalow

/ $ docker stop dac
dac

/ $ docker image ls -a
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              020584afccce        2 weeks ago         1.22MB

But after the container has been removed you can cleanup the layers:

/ $ docker image prune
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:020584afccce44678ec82676db80f68d50ea5c766b6e9d9601f7b5fc86dfb96d
deleted: sha256:1da8e4c8d30765bea127dc2f11a17bc723b59480f4ab5292edb00eb8eb1d96b1

Total reclaimed space: 1.22MB

By default docker ps will only show running containers. You can show the stopped ones using docker ps --all.

You can then remove the container first with docker rm <CONTAINER_ID>

If you want to remove all of the containers, stopped or not, you can achieve this from a bash prompt with

$ docker rm $(docker ps --all -q)

The -q switch returns only the IDs


Since everyone else seemed unwilling to test yet willing to preach, I decided to test this out myself:

  • I downloaded a new image so I knew it wasn't in use
  • I ran a new container
  • I deleted the image using docker rmi --force <name>
  • Image was only untagged, not deleted
  • I failed to delete the image using docker rmi --force <ID> as docker rebuked with "image is being used by running container 922a12161de6"

So the results are:

  • The image gets untagged when you name it, but Docker (at least the version I'm using, 19.03.5 build 633a0ea) is smart enough to not actually delete the layers when they are in use.
  • As a result, the container continues to run fine as the layers are still there, they're simply untagged. You can docker rmi <ID> or docker images prune (without -a it will only delete "dangling" images, I. E. not including unused ones).

Thus the answer is "yes, but it won't delete containers if that's what you're hoping for", but now you know why.

I'm not satisfied with how most of the other answers tell you to find running containers, however, since they seem to say "list all images" -- why? You're trying to delete a specific image.

Stefano's answer is more accurate but here are some tweaks to it:

imageName=ubuntu
containerIds=$(docker ps -a | grep "$imageName" | awk '{ print $1 }')
docker stop $containerIds
docker rm $containerIds
docker rmi "$imageName"

Basically, I added a variable for the image naem and a stop step.

Tags:

Docker