Introduction and use of dockerfile

Documentation: https://docs.docker.com/engine/reference/builder/

dockerfile introduction

what is dockerfile

Dockerfile is a text file that contains all the commands to create an image. It contains instructions and instructions. Each instruction builds a layer. Through the docker build command, the image is built based on the contents of the Dockerfile. Therefore, the content of each instruction describes how the layer Build. With Dockerfile, you can formulate your own docker image rules. You only need to add or modify instructions on the Dockerfile to generate a docker image.

What problem does dockerfile solve?

Dockerfile contains the complete operation process of image production. Other developers can understand and reproduce the production process through Dockerfile. Each instruction in Dockerfile will create a new image layer, and these images can be cached by Docker Daemon. When making an image again, Docker will try to reuse the cached image layer (using cache) instead of building it layer by layer, which can save time and disk space. The operation process of the Dockerfile can be queried through docker image history [image name] to facilitate development. View change history

docker build build process

The docker build command will read the contents of the Dockerfile and send the contents of the Dockerfile to the Docker engine. Finally, the Docker engine will parse each instruction in the Dockerfile and build the required image.
In the first step, docker build will package the files in the context and pass them to the Docker daemon. If there are .dockerignore files in the context, files that satisfy the .dockerignore rules will be removed from the upload list. Note: If there are quite a few files in the context, the entire file sending process can be clearly felt.
There is an exception here. If there is .dockerignore or Dockerfile in the .dockerignore file, the docker build command will ignore these two files when excluding files. If the image tag is specified, the repository and tag will also be verified.
The second step, the docker build command sends an HTTP request to the Docker server, requesting the Docker server to build the image. The request contains the required context information.
The third step, after Docker server receives the build request, it will execute the following process to build the image:
1. Create A temporary directory and extract the files in context to this directory.
2. Read and parse the Dockerfile, traverse the instructions in it, and distribute them to different modules for execution according to the command type.
3. The Docker build engine creates a temporary container for each instruction, executes the instruction in the temporary container, and then commits the container to generate a new image layer.
4. Finally, merge the image layers built by all instructions to form the final result of the build. The image ID generated by the last commit is the final image ID.

In order to improve build efficiency, docker build will cache existing image layers by default. If it is found that a certain image layer has been cached when building the image, the cached image will be used directly without rebuilding. If you do not want to use the cached image, you can specify the --no-cache=true parameter when executing the docker build command.

Docker's rules for matching cached images are: traverse the base image and its sub-images in the cache, and check whether the construction instructions of these images are exactly the same as the current instructions. If they are not the same, the cache does not match. For ADD and COPY instructions, the checksum of the file will also be used to determine whether the files added to the image are the same. If they are not the same, it means that the cache does not match. Note here that the cache match check does not check files in the container. For example, when using the RUN apt-get -y update command to update files in the container, the cache policy will not check these files to determine whether the cache matches. Finally, you can view the build history of the image through the docker history command.

Keywords
FROM 设置镜像使用的基础镜像
MAINTAINER 设置镜像的作者
RUN 编译镜像时运行的脚步
CMD 设置容器的启动命令
LABEL 设置镜像标签
EXPOSE 设置镜像暴露的端口
ENV 设置容器的环境变量
ADD 编译镜像时复制上下文中文件到镜像中
COPY 编译镜像时复制上下文中文件到镜像中
ENTRYPOINT 设置容器的入口程序
VOLUME 设置容器的挂载卷
USER 设置运行 RUN CMD ENTRYPOINT的用户名
WORKDIR 设置 RUN CMD ENTRYPOINT COPY ADD 指令的工作目录
ARG 设置编译镜像时加入的参数
ONBUILD 设置镜像的ONBUILD 指令
STOPSIGNAL 设置容器的退出信号量

dockerfile practice

Basic Grammar Practice
mkdir example
cd example

vim Dockerfile

FROM golang
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
# 仅指定镜像元数据内容
LABEL hello 1.0.0
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
docker build -t hello:1.0.0 -f Dockerfile .
docker run -p 80:80 -d --name hello hello:1.0.0

Build successfully:​​​​​​​

docker build context 

1. Material preparation

# 创建一个目录,案例需要
mkdir example2
cd example2
# 下载nginx源码包,作为案例素材
curl https://nginx.org/download/nginx-1.21.6.tar.gz > ./nginx-1.21.6.tar.gz
# 下载app代码
git clone https://gitee.com/nickdemo/helloworld
# ./nginx*
# helloworld

 2. Useless context

FROM golang
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
# 仅指定镜像元数据内容
LABEL hello 1.0.0
RUN git clone https://gitee.com/nickdemo/helloworld.git
WORKDIR helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
# 调整为不同的上下文,查看不同的效果
docker build -t hello:1.0.0 -f Dockerfile .

3. The real role of context

FROM golang:1.18
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
LABEL hello 1.0.0
COPY ./helloworld /go/src/helloworld
WORKDIR /go/src/helloworld
RUN go env -w GOPROXY=https://proxy.golang.com.cn,https://goproxy.cn,direct
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o app .
EXPOSE 80
CMD ["./app","--param1=p1","--param2=p2"]
docker build -t hello:1.0.0 -f Dockerfile .

Action:
1. Try to ignore different content in the .dockerignore file and observe the data sent to the daemon 
2. Try to use different context path to build the image
3. Try to copy content outside the context to build the image

Multi-stage build

After Docker version 17.05, Dockerfile multi-stage construction is added. The so-called multi-stage build actually allows multiple FROM instructions to appear in a Dockerfile. What's the point of doing this? The significance of multiple FROM instructions Multiple FROM instructions are not intended to generate multi-root layer relationships. The final generated image is still based on the last FROM. The previous FROM will be discarded, so what is the meaning of the previous FROM? Each FROM instruction is a build stage, and multiple FROM instructions are multi-stage builds. Although the final generated image can only be the result of the last stage, files in the previous stage can be copied to the later stages. This is the greatest significance of multi-stage construction. The biggest usage scenario is to separate the compilation environment and the running environment. For example, if we needed to build a Go language program before, we would need to use the go command and other compilation environments.

ADD and COPY

1. ADD and COPY cannot copy files outside the context
2. COPY command syntax format 

COPY <src> <dest> //将上下文中源文件,拷贝到目标文件
COPY prefix* /destDir/ //将所有prefix 开头的文件拷贝到 destDir 目录下
COPY prefix?.log /destDir/ //支持单个占位符,例如 : prefix1.log、prefix2.log 等

3. For directories, the COPY and ADD commands have the same characteristics: only copy the contents of the directory without including the directory itself.

COPY srcDir /destDir/ //只会将源文件夹srcDir下的文件拷贝到 destDir 目录下

4. The difference between COPY and ADD is the use of multi-stage in Dockerfile
5. ADD command syntax

ADD <src> <dest>

Except that the ADD command cannot be used in multistage scenarios, the ADD command can complete all the functions of the COPY command, and can also complete two types of functions:
a. Unzip the compressed file and Add them to the image. For local compressed files on the host, the ADD command will automatically decompress and add them to the image
b. Copy the file from the url to the image. Note: If the file where the url is located is Compressed package, ADD command will not automatically decompress

CMD and ENTRYPOINT
CMD
The CMD command has three formats
# shell 格式
CMD <command>
# exec格式,推荐格式
CMD ["executable","param1","param2"]
# 为ENTRYPOINT 指令提供参数
CMD ["param1","param2"]

1. The CMD instruction provides default values ​​when the container is running. These default values ​​can be an instruction or some parameters.
2. There can be multiple CMD instructions in a dockerfile, but only the last CMD instruction is valid.
3. The CMD parameter format is used when the CMD instruction is combined with the ENTRYPOINT instruction. The parameters in the CMD instruction will be added to the ENTRYPOINT instruction.
4. When using shell and exec formats, the command is run in the container in the same way as the RUN instruction. The difference is that the RUN instruction executes the command when building the image and generates a new image.
5. The CMD command does not execute any command when building the image. Instead, the CMD command is used as the first command to be executed by default when the container is started. If you specify command parameters when running the docker run command on the command line interface, the command in the CMD instruction will be overwritten.

ENTRYPOINT
The ENTRYPOINT command has two formats 
# shell 格式
ENTRYPOINT <command>
# exec 格式,推荐格式
ENTRYPOINT ["executable","param1","param2"]

1. The ENTRYPOINT instruction is similar to the CMD instruction. They both allow the container to execute the same command every time it is started, but there are differences between them. There can be multiple ENTRYPOINT instructions in a Dockerfile, but only the last ENTRYPOINT instruction is valid.
2. When using the shell format, the ENTRYPOINT command will ignore any CMD command and docker run command parameters, and will run in bin/sh -c.
3. It is recommended to use the exec format. Using this format, the command parameters passed in docker run will overwrite the content of the CMD command and be appended to the parameters of the ENTRYPOINT command.
4. CMD can be a parameter or an instruction, and ENTRYPOINT can only be a command; the running command parameters provided by the docker run command can override CMD, but not ENTRYPOINT.
5. You can replace the container’s entry program through docker run --entrypoint

build arg

1. dockerfile predefined parameters: HTTP_PROXY, http_proxy, HTTPS_PROXY, https_proxy, FTP_PROXY, ftp_proxy, NO_PROXY, no_proxy, ALL_PROXY, all_proxy. Predefined parameters can be used directly in the dockerfile without using arg to declare
2. Customize parameters through ARG

FROM alpine:latest as s1
ARG wd label tag
RUN echo $wd,$label,$tag
ENV env1=env1value
ENV env2=env2value
MAINTAINER zloser
LABEL $label $tag
WORKDIR $wd
COPY --from=stage0 /go/src/helloworld/app ./
EXPOSE 80
ENTRYPOINT ["./app","--param1=p1","--param2=p2"]
target and cache-from

For multi-stage builds, you can specify the stages that need to be rebuilt through --target. --cache-from can specify an image as the cache source. When the dockerfile instruction matches the cache image source instruction during the build process, the image layer in the cache image will be used directly to speed up the build process. The cached image can be pushed to the remote registration center for use in different build processes. It needs to be pulled locally before use.

onbuild

The onbuild directive adds instructions to the image that will trigger execution when the image is used as the base image for another build. The triggering instructions will be executed in the context of the downstream build. Note: the onbuild directive will not affect the current build, but will affect downstream builds

おすすめ

転載: blog.csdn.net/m0_68678128/article/details/134681238