Docker uses commit to understand how to build images

Posted by mdannatt on Sun, 23 Jan 2022 10:55:44 +0100

Docker uses commit to understand how to build images

The image is the basis of the container. Each time docker run is executed, which image will be specified as the basis for the container to run. When the image of Docker Hub cannot meet our needs, we need to customize the image to meet our needs.

Image is multi-layer storage, and each layer is modified based on the previous layer; The container is also a multi-layer storage, which takes the image as the base layer and adds a layer on the base layer as the storage layer when the container runs.

An example illustrates how a mirror is built.

[root@server ~]# docker run --name webServer -d -p 80:80 nginx:1.11  #Start a container based on nginx:1.11 image above docker hub

This command will start a container with nginx:1.11 image, named webServer, and mapped port 80, so that you can access the Nginx server. Then we can directly access the IP of the host to see the welcome page of Nginx

Now, if we don't like the welcome page and we like to change it to other text, we can use the docker exec command to enter the container and modify its content to

root@714830c04e5e:/# echo '<h1>Hello Docker Nginx Server</h1>' >/usr/share/nginx/html/index.html   #Modify the content of the default home page
root@714830c04e5e:/# exit
exit

You have entered the webServer container in the interactive terminal mode and executed the bash command, that is, you have obtained an operable shell. Then it overwrites the index HTML content, refresh the browser again, and you will find that the content has been changed.


The file of the container is modified, that is, the storage of the container is changed. You can view the specific changes through the docker diff command

[root@server ~]# docker diff webServer  #View changes to the webServer container
C /var
C /var/cache
C /var/cache/nginx
A /var/cache/nginx/scgi_temp
A /var/cache/nginx/uwsgi_temp
A /var/cache/nginx/client_temp
A /var/cache/nginx/fastcgi_temp
A /var/cache/nginx/proxy_temp
C /root
A /root/.bash_history
C /usr
C /usr/share
C /usr/share/nginx
C /usr/share/nginx/html
C /usr/share/nginx/html/index.html
C /run
A /run/nginx.pid

Now that we have customized the changes, we hope to save them to form an image. You know, when we run a container (if we don't use volumes), any file changes we make will be recorded in the container memory. Docker provides a docker commit command, which can save the storage layer of the container, which is called image. That is, on the basis of the original image, the storage layer of the container is superimposed to form a new image. In the future, when we run this new image, we will have the last file changes of the original container.

docker commit syntax format:

docker commit [option] <container ID Or container name> [<Warehouse name>[:<label>]]

Example: save the webServer container that changed the front page above as an image:

[root@server ~]# docker commit \
--author "Bu Ji <381347268@qq.com>" \
--message "Fixed default home page" \
webServer \
nginx:v1

[root@server ~]# docker images nginx   #View the finished nginx image
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               v1                  b639fbcc5ec4        2 minutes ago       183MB
nginx               1.11                5766334bdaa0        21 months ago       183MB

Where -- author is the author of the specified modification, and -- message records the content of this modification. This is similar to the git version controller. You can also use docker history to view the history in the image

[root@server ~]# docker history nginx:v1  #View the history of nginx:v1 images
IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
b639fbcc5ec4        5 minutes ago       nginx -g daemon off;                            157B                Fixed default home page
5766334bdaa0        21 months ago       /bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon...   0B                  
<missing>           21 months ago       /bin/sh -c #(nop)  EXPOSE 443/tcp 80/tcp        0B                  
<missing>           21 months ago       /bin/sh -c ln -sf /dev/stdout /var/log/nginx...   22B                 
<missing>           21 months ago       /bin/sh -c echo "deb http://nginx.org/packag...   59.1MB              
<missing>           21 months ago       /bin/sh -c set -e;  NGINX_GPGKEY=573BFD6B3D8...   4.9kB               
<missing>           21 months ago       /bin/sh -c #(nop)  ENV NGINX_VERSION=1.11.13...   0B                  
<missing>           21 months ago       /bin/sh -c #(nop)  MAINTAINER NGINX Docker M...   0B                  
<missing>           21 months ago       /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  
<missing>           21 months ago       /bin/sh -c #(nop) ADD file:4eedf861fb567fffb...   123MB

After the new image is customized, let's run the image

[root@server ~]# docker run --name web1 -d -p 81:80 nginx:v1  #Start a container named web1 based on the newly created nginx:v1 above

When we access the host IP:81, the content is the same as the modified webServer

So far, a customized image has been completed. The docker commit command is used to manually add a new layer to the old image to form a new image. You should have a very intuitive feeling of image multi-layer storage.

Use docker commit with caution

Although the docker commit command can intuitively help understand the concept of mirrored tiered storage, it is rarely used in the actual environment.

First of all, from the results of docker diff webServer above, you can find that in addition to / usr / share / nginx / HTML / index In addition to HTML files, many files have been changed or added due to the execution of commands. This is only the simplest operation. If you install the software package and compile the build, a large number of irrelevant content will be added. If you clean it carelessly, the image will become bloated.

In addition, using docker commit means that all operations on the image are black box operations, and the generated image is also called black box image. In other words, except that the person making the image knows what commands have been executed and how to generate the image, others simply can't know. Although the hot docker diff may tell you some clues, it is far from ensuring the generation of a consistent image. The maintenance of this black box image is very painful.

Moreover, except for the current layer, each previous layer will not be changed, that is, the result of any modification is only to mark, add and modify the current layer, and will not change the previous layer. If you use docker commit to create an image and modify it later, each modification will make the image more bloated. The deleted upper layer will not be lost. It will always follow the image, even if it can't be accessed at all. This makes the image more bloated.

Topics: Linux Docker