Update docker image resulting in orphan image - docker

I can use
docker build -t yzx2003209/my_image .
to build a new image tagged by yzx2003209/my_image:latest
However, the original yzx2003209/my_image:latest will become a <none> image and I have to manually rmi this orphan image.
Is there any way I can just update a image without manually removing orphan images?

There is no way to update an image - images are immutable - when you execute docker build which produce different image it also moving tag there - nothing changed in old image itself - it just don't have a tag anymore. If you want to remove all such images you could execute next command after docker build:
docker build -t yzx2003209/my_image .
docker rmi `docker images -q --filter "dangling=true"`
This command will delete ALL images without tag. Or you could do it in a different order - remove your old image before docker build - while it is still have a tag:
docker rmi yzx2003209/my_image
docker build -t yzx2003209/my_image .
But if your build will fail you will have no image. You could get image id before build and remove image after successful build:
old=`docker images -q yzx2003209/my_image`
docker build -t yzx2003209/my_image .
docker rmi $old
You could also use --rm option to remove intermediate containers after a successful build:
docker build --rm -t yzx2003209/my_image .
docker rmi `docker images -q --filter "dangling=true"`

Related

How to delete a docker image?

My project includes a Dockerfile to build an image. I've made modifications to that Dockerfile and want to see if it works. So i closed my program and listed all docker images in powershell using docker image ls -a. I deletetd all unused images using docker rmi -f $(docker images -a -q) and docker image prune -a.
But my image keeps not getting deleted, but simply 'untagged':
Untagged: my_image:latest
Untagged: my_image#sha256:16eb92a476be0...
All containers are stopped and deleted before trying to remove the image.
When i restart my application to build a new image, the old one keeps getting used:
> docker image ls -a
REPOSITORY TAG IMAGE ID CREATED
/my_image latest 0d79904a74b0 2 months ago
How do i actually physically remove the old image so my application can build a new one?
At first, you need to delete/stop the running container that is using your image(which one you want to remove).
docker ps -a: To see all the running containers in your machine.
docker stop <container_id>: To stop a running container.
docker rm <container_id>: To remove/delete a docker container(only if it stopped).
docker image ls: To see the list of all the available images with their tag, image id, creation time and size.
docker rmi <image_id>: To delete a specific image.
docker rmi -f <image_id>: To delete a docker image forcefully
docker rm -f (docker ps -a | awk '{print$1}'): To delete all the docker container available in your machine
docker image rm <image_name>: To delete a specific image
To remove the image, you have to remove/stop all the containers which are using it.
docker system prune -a: To clean the docker environment, removing all the containers and images.

Difference between docker rm IMAGE vs docker rmi IMAGE

According to Docker documentations, docker image rm "Remove one or more images" [1]. docker rmi has a same description [2], but then it goes on to say "Removes (and un-tags) one or more images from the host node."
Do docker image rm IMAGE and docker rmi IMAGE have an identical effect under any scenario? IMAGE is ID of the particular image that is to be removed.
The man page for docker rmi specifies that docker rmi is an alias for docker image rm. I suppose the documentation from docker is a little bit inconsistent in that regard. They write all the details for docker rmi while the documentation for docker image rm is lackluster.
It looks like docker rm is for containers and docker rmi is for images.
PS C:\Users\3des> docker rm httpd --force
Error: No such container: httpd
PS C:\Users\3des> docker rm httpd
Error: No such container: httpd
______________________________________________
PS C:\Users\3des> docker rmi httpd --force
Untagged: httpd:latest
Untagged: httpd#sha256:2fab99fb3b1c7ddfa99d7dc55de8dad0a62dbe3e7c605d78ecbdf2c6c49fd636
``
1). The docker image rm command "Remove one or more containers" not container image.
to check for container and its ID "docker ps -a" command
2). However, the docker rmi command means rm = remove i = image.
it is used to removing docker images. remembers that containers are created from images.
the "docker images or docker image ls" shows images, repository, TAG, and image ID.
docker rmi <image_ID> to remove image.
NOTE even when it is possible to create a new image from the existing image using the "docker commit" command, such image will come it its unique image id.

How to build an image with a custom name?

When I build an image using docker build:
docker build .
I get an image with a random name.
How to create a docker image with a custom name?
I already know how to set the name in the Dockerfile, but I'm not sure how to use it in the build command.
You can use the -t flag, as shown in the documentation (or run docker build --help to learn about the options you have).
You should do:
docker build -t my-image .
Now the image is created with the name my-image:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-image latest 43070bef9dfa 2 minutes ago 464MB

Docker image versioning and lifecycle management

I am getting into Docker and am trying to better understand how it works out there in the "real world".
It occurs to me that, in practice:
You need a way to version Docker images
You need a way to tell the Docker engine (running on a VM) to stop/start/restart a particular container
You need a way to tell the Docker engine which version of a image to run
Does Docker ship with built-in commands for handling each of these? If not what tools/strategies are used for accomplishing them? Also, when I build a Docker image (via, say, docker build -t myapp .), what file type is produced and where is it located on the machine?
docker has all you need to build images and run containers. You can create your own image by writing a Dockerfile or by pulling it from the docker hub.
In the Dockerfile you specify another image as the basis for your image, run command install things. Images can have tags, for example the ubuntu image can have the latest or 12.04 tag, that can be specified with ubuntu:latest notation.
Once you have built the image with docker build -t image-name . you can create containers from that image with `docker run --name container-name image-name.
docker ps to see running containers
docker rm <container name/id> to remove containers
Suppose we have a docker file like bellow:
->Build from git without versioning:
sudo docker build https://github.com/lordash/mswpw.git#fecomments:comments
in here:
fecomments is branch name and comments is the folder name.
->building from git with tag and version:
sudo docker build https://github.com/lordash/mswpw.git#fecomments:comments -t lordash/comments:v1.0
->Now if you want to build from a directory: first go to comments directory the run command sudo docker build .
->if you want to add tag you can use -t or -tag flag to do that:
sudo docker build -t lordash . or sudo docker build -t lordash/comments .
-> Now you can version your image with the help of tag:
sudo docker build -t lordash/comments:v1.0 .
->you can also apply multiple tag to an image:
sudo docker build -t lordash/comments:latest -t lordash/comments:v1.0 .

If I build a new docker image with the same name as existing ones, will the old ones be overwritten?

If I build a new docker image with the same name as existing ones, will the old ones be overwritten?
Images in Docker don't have a name, they have tags.
A tag is a reference to an image. Multiple tags may refer to the same image.
If you reassign a tag that is already used, then the original image will lose the tag, but will continue to exist (it will still be accessible by its image ID, and other tags might refer to it).
An easy way to clean up unused images and save disc space is to alias a cleanup command in your terminal by adding it to ~/.bashrc or ~/.bash_profile:
alias docker_rmi_dangling="docker rmi $(docker images -qa -f 'dangling=true')"
Then run docker_rmi_dangling in your shell.
(Inspiration from this comment)
It is not possible to overwrite docker image that has the same name in the name:tag format, but you could remove it automatically after the build if you set label my-label for the image my-image:latest:
docker build --tag my-image:latest --label my-label ubuntu:latest
docker image prune --force --filter='label=my-label'
Update: It is mandatory to follow strict sequence:
docker build ...
docker image prune ..
docker build ...
docker image prune ..
If you run:
docker build ...
docker image prune ..
docker build ...
docker build ...
docker image prune ..
you will get image from step 3. not removed.
You can use versions with your tags e/g/:
docker build -t <USER>/<CONTAINER>:<VERSION>
docker build -t maluuba/haproxy:2
docker build -t maluuba/haproxy:latest #Default behavior when you don't use version
docker build -t maluuba/haproxy:old
Two quick aliases for deleting all containers and images.
#Containers
$ alias rmdockerall="docker rm $(docker ps -a -q)"
#Images
$ alias rmidockerall="docker rmi $(docker images -a -q)"
If the base image is the same, the existing image will be overwritten.
Else building a new docker image with the same name as the existing ones will NOT delete or overwrite the existing image. It will remove the same (name) tag from the existing image and create a new image with that name.
The old/existing image will have no tags. It will be shown as <none>.
You can rename the existing image before creating an image with the same name by using the following command:
docker tag oldNameTag newNameTag
You can delete the images with <none> tag using the following command. It will delete all the dangling images.
docker image prune
or
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
More details can be found here.

Resources