5 篇文章 0 订阅

# Dockerfile的作用

Docker builds images automatically by reading the instructions from a Dockerfile – a text file that contains all commands, in order, needed to build a given image.
A Docker image consists of read-only layers each of which represents a Dockerfile instruction. The layers are stacked and each one is a delta of the changes from the previous layer.
Docker通过读取Dockerfile的指令来自动的构建镜像，Dockerfile包含了构建镜像所需的所有命令，Docker镜像由只读层组成，每个层都代表一个Dockerfile指令，这些层是堆叠的，每个层都是前一层变化的增量。如下Dockerfile：

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py


• FROM 以ubuntu:18.04镜像为基础创建新的镜像
• COPY 把当前的目录复制到镜像中的app目录下，添加文件
• RUN 执行make命令编译/app文件夹下的所有文件
• CMD 运行python命令，即运行/app/app.py该python文件

Dockerfile的编写，每一层都是对上一层的修改，写入新文件，修改现有文件和删除文件。

# 一些参考和建议

##### 创建“短暂”容器(Create ephemeral containers)

The image defined by your Dockerfile should generate containers that are as ephemeral as possible. By “ephemeral”, we mean that the container can be stopped and destroyed, then rebuilt and replaced with an absolute minimum set up and configuration.

(这段的意思我理解为，创建出的容器尽量可以自己运行，不需要依赖其他的程序，将应用程序作为一个或多个无状态进程执行，类似于微服务，每个镜像容器都是运行单独的一个进程)

##### 理解构建上下文(Understand Build Context)

When you issue a docker build command, the current working directory is called the build context.

mkdir myproject && cd myproject
echo "hello" > hello
echo -e "FROM busybox\nCOPY /hello /\nRUN cat /hello" > Dockerfile
docker build -t helloapp:v1 .


(-t是指定构建的镜像名称，:后的是版本号，若未指定则是latest)

mkdir -p dockerfiles context
mv Dockerfile dockerfiles && mv hello context
docker build --no-cache -t helloapp:v2 -f dockerfiles/Dockerfile context


##### 通过stdin管道构建Dockerfile(Pipe Dockerfile through stdin)
echo -e 'FROM busybox\nRUN echo "hello world"' | docker build -

docker build -<<EOF
FROM busybox
RUN echo "hello world"
EOF


docker build [OPTIONS] -


docker build -t myimage:latest -<<EOF
FROM busybox
RUN echo "hello world"
EOF


# create a directory to work in
mkdir example
cd example

# create an example file
touch somefile.txt

docker build -t myimage:latest -<<EOF
FROM busybox
COPY somefile.txt .
RUN cat /somefile.txt
EOF

# observe that the build fails
...
Step 2/3 : COPY somefile.txt .
COPY failed: stat /var/lib/docker/tmp/docker-builder249218248/somefile.txt: no such file or directory


docker build [OPTIONS] -f- PATH


docker build -t myimage:latest -f- https://github.com/docker-library/hello-world.git <<EOF
FROM busybox
COPY hello.c .
EOF


##### 使用 .dockerignore

.dockerignore类似于.gitignore，将文件在构建镜像中排除，这些文件不被docker传入镜像内。

##### 使用多段式的构建(Use multi-stage builds)

Multi-stage builds allow you to drastically reduce the size of your final image, without struggling to reduce the number of intermediate layers and files.

• 安装构建应用需要的工具
• 安装或更新依赖库
• 生成你的应用

FROM golang:1.11-alpine AS build

# Install tools required for project
# Run docker build --no-cache . to update dependencies
RUN go get github.com/golang/dep/cmd/dep

# List project dependencies with Gopkg.toml and Gopkg.lock
# These layers are only re-built when Gopkg files are updated
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/
# Install library dependencies
RUN dep ensure -vendor-only

# Copy the entire project and build it
# This layer is rebuilt when a file changes in the project directory
COPY . /go/src/project/
RUN go build -o /bin/project

# This results in a single layer image
FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]

##### 不安装不必要的包

To reduce complexity, dependencies, file sizes, and build times, avoid installing extra or unnecessary packages just because they might be “nice to have.” For example, you don’t need to include a text editor in a database image.

##### 解耦应用 (Decouple applications)

(该部分也类似于微服务场景，将容器分开部署。)

##### 层数最小化（Minimize the number of layers）

In older versions of Docker, it was important that you minimized the number of layers in your images to ensure they were performant. The following features were added to reduce this limitation:

• Only the instructions RUN, COPY, ADD create layers. Other instructions create temporary intermediate images, and do not increase the size of the build.

只有在RUN COPY ADD命令上创建新的层，其他的命令创建临时中间镜像，并且不会增加构建的大小。

• Where possible, use multi-stage builds, and only copy the artifacts you need into the final image. This allows you to include tools and debug information in your intermediate build stages without increasing the size of the final image

在可能的情况下使用多层构建，将仅需的文件复制到最终镜像中，允许您在中间构建阶段中包含工具和调试信息，而不会增加最终镜像的大小。

##### 多行参数排序 (Sort multi-line arguments)

Whenever possible, ease later changes by sorting multi-line arguments alphanumerically. This helps to avoid duplication of packages and make the list much easier to update.

RUN apt-get update && apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion

##### 利用构建缓存（Leverage build cache）

When building an image, Docker steps through the instructions in your Dockerfile, executing each in the order specified. As each instruction is examined, Docker looks for an existing image in its cache that it can reuse, rather than creating a new (duplicate) image.

If you do not want to use the cache at all, you can use the--no-cache=true option on the docker build command. However, if you do let Docker use its cache, it is important to understand when it can, and cannot, find a matching image.

Docker的基本规则：

• Starting with a parent image that is already in the cache, the next instruction is compared against all child images derived from that base image to see if one of them was built using the exact same instruction. If not, the cache is invalidated.

在缓存里的父镜像开始，将下一条指令与基于该镜像得到的所有子镜像对比，是否使用到了相同的指令构建，否则缓存失效。

• In most cases, simply comparing the instruction in the Dockerfile with one of the child images is sufficient. However, certain instructions require more examination and explanation.

在大多数情况下，将Dockerfile其中一个子图像中的指令简单地进行比较就足够了。但是，某些说明需要更多的检查和解释

• For the ADD and COPY instructions, the contents of the file(s) in the image are examined and a checksum is calculated for each file. The last-modified and last-accessed times of the file(s) are not considered in these checksums. During the cache lookup, the checksum is compared against the checksum in the existing images. If anything has changed in the file(s), such as the contents and metadata, then the cache is invalidated.

对于ADDCOPY指令，检查镜像中文件的内容，并计算每个文件的校验和。在这些校验和中不考虑文件的最后修改时间和最后访问时间。在查找缓存期间，将校验和与现有映像中的校验和进行比较。如果文件中的任何内容（例如内容和元数据）发生了修改，则缓存将失效。

• Aside from the ADD and COPY commands, cache checking does not look at the files in the container to determine a cache match. For example, when processing a RUN apt-get -y update command the files updated in the container are not examined to determine if a cache hit exists. In that case just the command string itself is used to find a match.

除了ADDCOPY命令之外，缓存检查不会查看容器中的文件来确定缓存匹配。例如，在处理RUN apt-get -y update命令时，不检查容器中更新的文件以确定是否存在缓存命中。在这种情况下，只需使用命令字符串本身来查找匹配项。

• 0
点赞
• 0
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

04-10 2247
06-06 99
08-20 2206
09-19 2040
01-24 1173
12-13 77
05-08 115
11-20 44
11-28 54
10-15 3353