To get a quick primer on Dockerfile let’s take a look at a simple example
First we pull down a mysql:5.7 image from the mirror repository
Start the container and enter the container
Then we try to ping www.baidu.com and find that there is no ping command
If we happen to have this need, it will be very awkward. 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 following Dockerfile content
FROM mysql:5.7
RUN apt-get update && apt install iputils-ping -y
RUN apt-get install vim -y
Copy the code
Here we have the ping and vim tools installed (note to check the distribution information by cat /etc/issue, the installation tool command will be different for different versions).
Start building the image from Dockerfile
We’ll start building with this Dockerfile:
docker build -t mysql:mumu .
Copy the code
We can see that the build process is divided into three steps, which correspond exactly to the three commands in our Dockerfile
When the build is complete, we can see that it is 53MB larger than mysql:5.7
Start the container we built
After mirroring 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
Copy the code
When we ping Baidu after startup, we can see that our tool is working normally
Through the above case we have a preliminary understanding of Dockerfile? Roughly have the following understanding
-
Dockerfile is used to build the image
-
Dockerfile Each instruction corresponds to a step
-
We can use Dockerfile to customize the image we need
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
Copy the code
Its construction process can be understood as the superposition process of multiple images
Each instruction in the Dockerfile creates a new layer, layer upon layer, to form the image we want
For example, this command creates three layers, each of which records only the changes made to its own layer, and these layers are read-only. When a container is started, Docker adds a read-write layer at the top, which is commonly referred to as the container layer.
Each container has its own independent container layer, so the changes will only exist in its own container layer and will not affect each other. This way, different containers can share a mirror layer.
Why a layered structure?
The biggest advantage is sharing resources. For example, many images are built from base images. After saving a copy to disk, all images can be shared
For example, if the image derived container changes the file inside it, such as modifying a file under /opt, will the /opt file in other containers also be changed?
We mentioned the container layer above, which is per-container independent. The modified data is stored directly in the container layer, and the mirror layer remains unchanged.
Introduction to the Dockerfile command
FROM: Specifies the base mirror. It must be the first command
FROM <image>:<tag>
FROM <image>@<digest>
Copy the code
Example:
The FROM elasticsearch: 7.6.0Copy the code
Note: Tag and digest are optional, and the latest version of the base image is automatically used if empty
MAINTAINER: MAINTAINER information
MAINTAINER <name>
Copy the code
Example:
MAINTAINER mumu
MAINTAINER [email protected]
MAINTAINER mumu<[email protected]>
Copy the code
RUN: indicates the command executed during image construction
RUN <command>
RUN ["executable", "param1", "param2"]
Copy the code
Example:
RUN apk update
RUN ["./test", "dev", "offline"]
Copy the code
Note: The intermediate image created by the RUN directive is 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 a build, such as docker build –no-cache
ADD: ADD local files to the container. Tar files are automatically decompressed (network compressed resources are not decompressed), and network resources can be accessed, similar to wget
ADD <src> <dest>
Copy the code
Example:
ADD mumu.txt /mydir/
Copy the code
Note: COPY is similar to ADD, but does not automatically extract files or access network resources
CMD: called after the container is built, that is, when the container is started.
CMD ["executable", "param1", "param2"] CMD ["param1", "param2"] CMD command param1 param2Copy the code
Example:
CMD ["java", "-jar" ,"/opt/server/product.jar"]
Copy the code
Note: CMD is used to specify the commands to be executed when the container is started, while RUN is used to specify the commands to be executed when the image is built. Each Dockerfile can have only one CMD command. If multiple commands are specified, only the last one will be executed. If you specify a run command when you start the container, the CMD command will be overwritten.
ENTRYPOINT: Configure the container to be executable, with CMD to omit application and use only parameters.
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param2Copy the code
Example:
ENTRYPOINT ["/bin/echo", "hello"]
Copy the code
Note: ENTRYPOINT is very similar to CMD, but the commands executed by Docker run do not overwrite ENTRYPOINT. However, if a docker run uses the — ENTRYPOINT option, The parameters of this option override the program specified by the ENTYPPOINT directive as the program to be run, and any parameters specified in the Docker run command are passed to ENTRYPOINT as parameters. Only one ENTRYPOINT command is allowed in a DockerFile. If multiple ENTRYPOINT commands are specified, the previous one will be overridden and only the last one will be executed.
When ENTRYPOINT is specified, the meaning of CMD changes. Instead of running the command directly, the contents of CMD are passed to the ENTRYPOINT directive as arguments. In other words, the actual execution will become “”.
If I’m getting a little confused here, what does CMD have to do with ENTRYPOINT?
In Dockerfile, you should specify at least one CMD and ENTRYPOINT;
Docker should be configured as an executable using ENTRYPOINT;
CMD can be used as the default argument to ENTRYPOINT or as the default command for Docker;
CMD can be overridden by arguments passed in by docker run;
Arguments passed in by docker Run are appended to ENTRYPOINT, provided the exec format is used
For example, let’s look at the following Dockerfile:
FROM nginx
ENTRYPOINT ["nginx", "-c"]
CMD ["/etc/nginx/nginx.conf"]
Copy the code
When we enable nginx: docker run nginx:mumu
The following command is executed: nginx -c /etc/nginx/nginx.conf
Docker run nginx:mumu -c /etc/nginx/new.conf
Run the following command: nginx -c /etc/nginx/new.conf
LABEL: adds metadata to an image
LABEL <key>=<value> <key>=<value> <key>=<value>
Copy the code
Example:
LABEL version="1.0" descriptioin=" This is descriptioin"Copy the code
Note: When using LABEL to specify metadata, a LABEL can specify one or more metadata, separated by Spaces. It is recommended to specify all metadata through a LABEL directive to avoid generating too many intermediate images.
ENV: Sets environment variables
ENV <key> <value> Only one variable can be set at a time. All variables following key are treated as value ENV <key>=<value>... Multiple variables can be set, each as a "<key>=<value>" key-value pair,Copy the code
If the character contains a space, you can use \ to escape
Example:
ENV username admin
ENV password 123456
ENV port=3306
Copy the code
EXPOSE: Specifies the port for external interaction
EXPOSE <port> [<port>...]
Copy the code
Example:
EXPOSE 80 443
EXPOSE 11221/tcp 11221/udp
Copy the code
Note that the EXPOSE command only states that the container should open ports and doesn’t actually open them. If you don’t specify the ports to map with -p, the container won’t map them out. To make them accessible, these ports need to be specified with -p during Docker run
VOLUME: specifies the persistent directory
VOLUME ["/path/to/dir"]
Copy the code
Example:
VOLUME ["/ect/nginx/con.d"]
VOLUME["/etc/nginx/con.d", "/etc/nginx/logs" ]
Copy the code
Description: container runtime should try to keep the container storage layer don’t write operation, in order to prevent users from runtime forget to save dynamic document directory mounted as volumes, we can advance in Dokcerfile specify certain directory mounted as anonymous, so even if the user does not specify a mount, its will not to write a lot of container storage layer data; It cannot specify the corresponding directory on the host and is automatically generated.
Note: Volumes can be shared with other containers, and their life cycle is independent of the container. Docker does not automatically delete volumes after the container is deleted, and there is no garbage collection mechanism for handling volumes referenced by any container if the container needs to be removed at the same time. You can use the docker rm -v command to delete containers
WORKDIR: working directory, similar to the CD command
WORKDIR /path/to/dir
Copy the code
Example:
WORKDIR /etc WORKDIR nginxCopy the code
Note: After the WORKDIR directory is set, all subsequent commands in the Dockerfile are executed in the specified directory. The working directory of the Dockerfile can be overwritten with -w while the container is running.
USER: Specifies the USER name or UID for running the container, which will be used in subsequent commands.
USER user
USER uid
USER uid:gid
USER user:gid
USER uid:group
USER user:group
Copy the code
Example:
USER mumu
Copy the code
Note: When you specify a USER using USER, all commands following Dockerfile will use that USER, but you can override the specified USER when running the container with the -u argument.
ARG: Used to specify variables passed to the build run time
ARG <name>[=<default value]
Copy the code
Example:
ARG site
ARG user=mumu
Copy the code
Note: If the ARG specifies a default value and no value is passed in during the build, the default value is used.
ONBUILD: Used to set the mirror trigger
ONBUILD [INSTRUCTION]
Copy the code
Example:
ONBUILD ADD . /etc/nginx
ONBUILD RUN
Copy the code
Note: Its parameters can be any A Dockerfile instruction, the instruction was not substantial influence on the current mirror (the current mirror called A), but if the mirror image based on A, B, then in the process of building image B will perform its instructions, but when A B C will not perform this instruction (can be understood as cannot atavism, ha ha).
Here is another case to test our learning achievements:
Let’s take a look at nginx:latest version of Dokcerfile, with the comments removed for neatness
FROM Debian: Bust-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;"]Copy the code
- Reference base mirror: Debian: Bust-Slim
- Add source data: Maintainer =”NGINX Docker Maintainers [email protected]”
- Three environment variables are introduced: NGINX_VERSION 1.19.6 NJS_VERSION 0.5.0 PKG_RELEASE 1~ BUSTER
- Execute the command set-x, which is the shell’s command to print the command to the screen.
- . Copies the three files to the specified location
- / docker-entrypoint. sh nginx -g daemon off
- Specify port 80
- STOPSIGNAL was introduced after Docker1.9. This command is sent to the system call signal pushed out by the container, for example, what operation should be performed before exiting the system