[Docker series] Dockerfile introduction

In order to quickly have a preliminary understanding of Dockerfile, let's first look at a simple example

First, we pull a mysql:5.7 image from the mirror warehouse, we start the container and enter the container, but when we want to ping a certain ip in it, we find that there is no ping command
Insert picture description here

If we happen to have this need, it would be very embarrassing. What can be done to solve it?
We can rebuild a new image based on mysql:5.7 and add what we want; let’s take a look at the content of the following Dockerfile

FROM mysql:5.7

RUN apt-get update \
&& apt install iputils-ping -y

RUN apt-get install vim -y

Here we have installed the ping and vim tools (note that you need to view the release information through cat /etc/issue, and the commands for the installation tools are different for different versions)

Let's start building with this Dockerfile :docker build -t mysql:mumu .
Insert picture description here

We can see that the build process is divided into three steps, which correspond to the three commands of our Dockerfile.
After the build is completed, we can see that it is 53MB larger than mysql:5.7
Insert picture description here

After the image is played, we can start the container:
docker run -p 3306:3306 --name mysql -v /data/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:mumu
After starting, we can ping www.baidu.com, and we can see that our tools are normally available
Insert picture description here

Through the above case, do we have a preliminary understanding of
Dockerfile : Dockerfile is a Dockerfile used to build a mirror.
One instruction corresponds to a step.
Through the Dockerfile and the basic mirror, we can build a mirror that is more in line with our requirements.

We use another Dockerfile to understand the concept of image layering:

FROM debian
RUN apt-get update && apt-get -y -f install emacs
RUN apt-get update && apt-get -y -f install apache2

Each instruction in the Dockerfile is a new layer, layer by layer, and finally constitute the image we want
Insert picture description here

For example, the above command will create three layers, each layer only records the changes made in this layer, and these are read-only. When a container is started, Docker will add a read-write layer at the top, which is generally called the container layer.
Insert picture description here

Each container has its own independent container layer, so the modification will only have its own container layer, and there is no impact between containers. In this way, different containers can share a mirroring layer.
Insert picture description here

Why use a hierarchical structure?
The biggest advantage is sharing resources. For example, many mirrors are built from base mirrors. After we save a copy to disk, it can be shared by all mirrors.

But for example, some people have questions. If this image-derived container changes the files in it, for example, if a file under /opt is modified, will the /opt of other containers also be modified?
We mentioned above that the container layer is independent of each container. The modified data will be stored directly in the container layer, and the image layer will remain unchanged.

Introduction to Dockerfile instructions

FROM: Specify the base image, must be the first command
FROM:
FROM @
Example:
FROM elasticsearch: 7.6.0
Note: tag and digest are optional, if they are empty, the latest version of the base image will be used automatically

MAINTAINER: Maintainer information
MAINTAINER
example:
MAINTAINER mumu
MAINTAINER [email protected]
MAINTAINER [email protected]

RUN: The command executed when building the image
RUN
RUN ["executable", "param1", "param2"]
Example:
RUN apk update
RUN ["./test", "dev", "offline"]
Note: Created by the RUN instruction The intermediate image will be cached and used in the next build. If you don’t want to use these cache images, you can use the –no-cache parameter when building the build, such as: docker build --no-cache

ADD: Add local files to the container, tar files will be automatically decompressed (network compressed resources will not be decompressed), you can access network resources, similar to wget
ADD
example:
ADD mumu.txt /mydir/
Note: COPY: similar in function ADD, but it will not automatically decompress the file, nor can it access network resources

CMD: Called after the container is built, that is, it is called when the container is started.
CMD ["executable", "param1", "param2"]
CMD ["param1", "param2"]
CMD command param1 param2 (shell internal command)
example:
CMD ["java", "-jar" ,"/opt/ server/product.jar"]
Note: CMD is different from RUN. CMD is used to specify the command to be executed when the container is started, and RUN is used to specify the command to be executed when the image is built; each Dockerfile can only have one CMD command If more than one is specified, only the last one will be executed. If the user specifies a run command when starting the container, the command specified by CMD will be overwritten.

ENTRYPOINT: Configure the container to make it executable. With CMD, application can be omitted and only parameters are used.
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2 (shell internal command)
Example:
ENTRYPOINT ["/bin/echo", "hello"]
Note: ENTRYPOINT is very similar to CMD, but docker run execution The command will not overwrite ENTRYPOINT, but if docker run uses the -entrypoint option, the parameter of this option can be used as the program to be run to override the program specified by the ENTYPPOINT instruction, and any parameters specified in the docker run command will be treated as parameters Pass it to ENTRYPOINT again; only one ENTRYPOINT command is allowed in DockerFile, and if more than one is specified, the previous one will be overwritten and only the last one will be executed.
When ENTRYPOINT is specified, the meaning of CMD changes. It is no longer a direct running command, but the content of CMD is passed as a parameter to the ENTRYPOINT instruction, in other words it will become "" when it is actually executed.

Isn't it a little confused here, what is the connection between CMD and ENTRYPOINT?
In Dockerfile, at least one CMD and ENTRYPOINT should be specified;
when Docker is used as an executable program, ENTRYPOINT should be used for configuration;
CMD can be used as the default parameter of ENTRYPOINT, or as the default command of Docker;
CMD can be passed in by docker run Parameter override;
the parameters passed in by docker run will be appended to ENTRYPOINT, provided that the exec format is used

For example, the Dockerfile is as follows
FROM nginx
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
When we enable nginx: docker run nginx:mumu is
equivalent to executing the following command: nginx -c /etc/nginx/nginx.conf
When we change the startup command to: docker run nginx:mumu -c /etc/nginx/new.conf is
equivalent to executing the following command: nginx -c /etc/nginx/new. conf

LABEL: Used to add metadata to the mirror image
LABEL == =
Example:
LABEL version=“1.0” descriptioin=“This is a service of Mumu”
Note: When using LABEL to specify metadata, a LABEL can specify one or more pieces of metadata , Separated by spaces. It is recommended to specify all metadata through a LABEL command to avoid generating too many intermediate images.

ENV: Set the environment variable
ENV can only set one variable at a time, the content after the key will be regarded as value
ENV =… Multiple variables can be set, each variable is a "=" key-value pair, if it contains spaces Special characters, you can use \ to escape
Example:
ENV username admin
ENV password 123456
ENV port=3306

EXPOSE: Specify the port for external interaction
EXPOSE […]
Example:
EXPOSE 80 443
EXPOSE 11221/tcp 11221/udp
Note: The EXPOSE command only declares that the port that the container should open is not actually opened, if you don’t specify the port to be mapped without -p , The container will not map the port out; to make it accessible, you need to specify these ports through -p when docker run

VOLUME: Used to specify the persistent directory
VOLUME ["/path/to/dir"]
Example:
VOLUME ["/ect/nginx/con.d"]
VOLUME["/etc/nginx/con.d", "/etc /nginx/logs”]
Note: When the container is running, try to keep the storage layer of the container from being written. In order to prevent users from forgetting to mount the directory where the dynamic file is saved as a volume when running, we can specify certain directories in the Dokcerfile in advance. The mount is an anonymous volume, so that even if the user does not specify the mount, it will not write a large amount of data to the container storage layer; it cannot specify the corresponding directory on the host, and it is automatically generated.
Note: The volume can be shared with other containers, and its life cycle is independent of the container. Docker will not automatically delete the data volume after the container is deleted, and there is no garbage collection mechanism to deal with any data volume referenced by the container, if necessary Remove the data volume while deleting the container. You can use the docker rm -v command when deleting the container.
Here is the focus on what is mounting:

WORKDIR: working directory, similar to the cd command
WORKDIR /path/to/dir
Example:
WORKDIR /etc (working directory is etc)
WORKDIR nginx (working directory becomes /etc/nginx)
Note: After setting the directory through WORKDIR, the back in the Dockerfile The commands are executed in the specified directory. When running the container, you can pass -w to overwrite the working directory of the Dockerfile.

USER: Specify the user name or UID when running the container, and the subsequent series of commands will use this user.
USER user
USER uid
USER uid:gid
USER user:gid
USER uid:group
USEr user:group
Example:
USER mumu
Note: After USER is used to specify a user, the commands following the Dockerfile will use this user, but when running the container, you can pass- u parameter to overwrite the specified user.

ARG: Used to specify the variables passed to the build runtime, similar to EVN
ARG [=<default value]
Example:
ARG site
ARG user=mumu
Note: If ARG specifies a default value and no value is passed during the build, then Just use the default value.

ONBUILD: Used to set the mirroring trigger
ONBUILD [INSTRUCTION]
Example:
ONBUILD ADD. /Etc/nginx
ONBUILD RUN
Note: The parameter can be any Dockerfile instruction, which will not have a substantial impact on the current mirror (change the current mirror Named A), but if mirror B is based on mirror A, then its instructions will be executed during the construction of mirror B, but when C is based on B, the instruction will not be executed (it can be understood that it cannot be inherited from generation to generation, haha ).

Let's review it with another case:
Let's take a look at the Dokcerfile of nginx:latest version, the comment part has been deleted

FROM debian:buster-slim

LABEL maintainer="NGINX Docker Maintainers <[email protected]>"

ENV NGINX_VERSION   1.19.6

ENV NJS_VERSION     0.5.0

ENV PKG_RELEASE     1~buster

RUN set -x \

COPY docker-entrypoint.sh /

COPY 10-listen-on-ipv6-by-default.sh /docker-entrypoint.d

COPY 20-envsubst-on-templates.sh /docker-entrypoint.d

ENTRYPOINT ["/docker-entrypoint.sh"]

EXPOSE 80

STOPSIGNAL SIGQUIT

CMD ["nginx", "-g", "daemon off;"]

Reference the basic image: debian: buster-slim
Add source data: maintainer= "NGINX Docker Maintainers [email protected]"
Introduce three environment variables: NGINX_VERSION 1.19.6 NJS_VERSION 0.5.0
PKG_RELEASE 1~Buster
execute the command set -x , This is the command in the shell to print the command to the screen.
Copy the three files to the specified place
. The combination of ENTRYPOINT and CMD is: /docker-entrypoin.sh nginx -g daemon off
Specify port 80
STOPSIGNAL: This is introduced after docker1.9, and this instruction is sent to the system launched by the container Invoke signals, such as what to do before exiting the system.

Guess you like

Origin blog.csdn.net/qq_41979344/article/details/113405668