About Docker for experimental purposes was executed the following command:
sudo docker rmi -f ubuntu:20.04
which prints:
Untagged: ubuntu:20.04
Untagged: ubuntu@sha256:0b897358ff6624825fb50d20ffb605ab0eaea77ced0adb8c6a4b756513dec6fc
Deleted: sha256:5f5250218d28ad6612bf653eced407165dd6475a4daf9210b299fed991e172e9
Now if is executed the sudo docker ps -a
command is displayed
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
...
ed096064373f 5f5250218d28 "cat /etc/os-release" 19 hours ago Exited (0) 19 hours ago ubuntu-20.18-d-015
3bc4c52f0299 5f5250218d28 "cat /etc/os-release" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-015
8cd0502ff777 5f5250218d28 "ls -als ../etc" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-014
d3ce9a3fbd47 5f5250218d28 "ls -als /" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-013
c8889c44f3a9 5f5250218d28 "ls -als ." 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-012
1c6ff666c7ff 5f5250218d28 "ls -als /home/manue…" 19 hours ago Exited (2) 19 hours ago ubuntu-20.04-d-011
b5da7429b8b8 5f5250218d28 "ls -als /etc" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-010
f169712b9718 5f5250218d28 "ls -als /etc" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-009
5ea2001f47e2 5f5250218d28 "ls -als /home" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-008
cde6c940efb4 5f5250218d28 "ls -als /home/manue…" 19 hours ago Exited (2) 19 hours ago ubuntu-20.04-d-007
f75c3f7932cd 5f5250218d28 "ls -als ." 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-006
7d7154a21668 5f5250218d28 "cat /etc/os-release" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-005
a75b22a43af7 5f5250218d28 "echo hello" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-004
2fcfb4dea168 5f5250218d28 "cat /home/manueljor…" 19 hours ago Exited (1) 19 hours ago ubuntu-20.04-d-003
8c9def0115c8 5f5250218d28 "date" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-002
f2a7ad7904a8 5f5250218d28 "ls /etc" 19 hours ago Exited (0) 19 hours ago ubuntu-20.04-d-001
...
Observe the IMAGE
header value. It shows the 5f5250218d28
value where it is the first 12 characters of sha256:5f5250218d28ad6612bf653eced407165dd6475a4daf9210b299fed991e172e9
Now, I want to remove all these containers based on the Images's id shown in the IMAGE
header.
Thus I did do a research and I found:
Where is indicated the following command:
docker rm $(docker ps -a -q --filter "ancestor=ubuntu")
Now, just playing with the command substitution part and by applying the following variations as follows:
docker ps -aq --filter "ancestor=5f5250218d28"
docker ps -aq --filter "ancestor=sha256:5f5250218d28"
docker ps -aq --filter "ancestor=5f5250218d28ad6612bf653eced407165dd6475a4daf9210b299fed991e172e9"
docker ps -aq --filter "ancestor=sha256:5f5250218d28ad6612bf653eced407165dd6475a4daf9210b299fed991e172e9"
All of them returns nothing
Just in case if is executed
sudo docker ps -aq --filter "name=ubuntu-20.04-d-"
It prints the expected set of container's id but not always the containers would have the same pattern name
Question
So I need resolve first the command substitution part about the ps -aq --filter
command
I've read the official documentation about:
And it seems is not possible. But I am assuming would exists a trick/smart approach
Updated: I removed the recommendation of the -q
flag as of course the go template already returned the IDs only.
A Docker image is metadata + filesystem layers. What docker rmi
or docker image rm
does is removing the user-friendly tag from the images. When it has multiple tags, and you remove one, the command's output shows only "untagged". When there is no tag anymore, there is an additional line saying "deleted", which means the whole image, including the metadata and layers not part of other images.
But if something still refers to the image like a running container, the image cannot be deleted completely. since that would make the executable and libraries disappear used by the process in the container.
You can force it if for some reason you can't stop the container but you want to make sure nobody starts a container from that image anymore, although, indeed I don't have an example from real life, because I never even thought of using it. But when you do, the image remains as "dangling" and the docker rmi
command will show only "untagged" in the output and docker image ls
will reveal these by showing <none>
as repository and tag. You could actually filter to dangling images by running
docker image ls --filter=dangling
but docker image prune
will not let you delete it even though it is supposed to delete dangling images as a container still refers to it.
Since your containers were already stopped, Docker could delete the image metadata, however, the filesystem layers are still there as the containers exist and you could start them again, but the so-called "ancestor", which is the image is not actually there anymore.
I'm not sure if this was an intentional implementation or something the developers would fix, but I could confirm, that the ancestor filter works only if the ancestor exists. Instead of using that filter, you can use the following command to list the container started from the image with the a specific image ID which is "5f5250218d28" in your case and I used it in the example:
docker ps -a --format '{{ if eq .Image "5f5250218d28" }}{{ .ID }}{{ end }}' | grep "\S"
You don't need to add -q
to get only the container IDs as the go template solved that already so you can use it in the subshell instead of the one with the filter parameter. This relies only on the container's medata and uses Go template to show the container ID only when the Image id is what you want. The grep command will just remove empty lines since you still get as many lines as many container's you have without a filter.
If you don't know what objects you can work with, you can run
docker ps -a --format json
Or to get a shorter output, just get the first json line:
docker ps -a --format json | head -n1
And optionally format it with jq if you installed it:
docker ps -a --format json | head -n1 | jq
Example:
{
"Command": "\"httpd-foreground\"",
"CreatedAt": "2024-08-14 20:00:21 +0200 CEST",
"ID": "0ed21408c8b2",
"Image": "3c2285410b59",
"Labels": "",
"LocalVolumes": "0",
"Mounts": "",
"Names": "test2",
"Networks": "bridge",
"Ports": "",
"RunningFor": "23 hours ago",
"Size": "0B",
"State": "exited",
"Status": "Exited (0) 23 hours ago"
}
And if you are more familiar with jq
then go templates, you can just use jq to get the container IDs:
docker ps -a --format json \
| jq -r '. | select(.Image == "3c2285410b59") | .ID'
-q
is still not needed as jq took care of the formatting.
My original, much shorter answer is on the Docker forum, but I thought I would add some more details and alternatives.