Docker可以通过Dockerfile构建镜像。当执行docker build 命令时,当前的工作目录称为build context

默认,Dockerfile会位于当前目录,但是也可以通过-f选项指定不同的位置。

简单的构建Dockerfile过程如下

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

其中,构建文件是Dockerfile,构建环境是当前目录.

如果此时将Dockerfile与hello文件移动到不同的路径,则操作改为

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

其中,构建文件是dockerfiles/Dockerfile,构建环境是context目录。

如果需要指定多个标签,可以

$ docker build -t shykes/myapp:1.0.2 -t shykes/myapp:latest .

如果要查看build context的大小,可以在构建Dockerfile时,注意输出日志

Sending build context to Docker daemon  187.8MB

.dockerignore

排除与构建无关的文件,可以使用.dockerignore 文件,它与.gitignore 类似。

multi-stage构建

如果使用Docker 17.05+,可以选择使用multi-stage build,从而显著减少镜像的体积。

一个go应用的Dockerfile如下所示

FROM golang:1.9.2-alpine3.6 AS build

# Install tools required to build the project
# We need to run `docker build --no-cache .` to update those dependencies
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep

# Gopkg.toml and Gopkg.lock lists project dependencies
# 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 all project and build it
# This layer is rebuilt when ever a file has changed 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"]

最小化layer数量

在Docker 17.05之前,甚至是Docker 1.10之前,镜像的layer数目需要最小化。

在Docker 1.10+,只有RUNCOPYADD 会创建layer;其他命令只会创建临时的中间层镜像,不会直接增加构建体积。

在Docker 17.05+,支持multi-stage builds,允许将所需要的artifacts拷贝到最后的镜像;而在中间层构建过程中可以包含工具和debug信息,但它不会增加最后镜像的体积。

多行参数

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

构建缓存

在使用Dockerfile构建镜像时,在每次命令执行时都会检查缓存中是否有存在的镜像,如果不想使用缓存构建,可以在执行docker build 命令时,添加选项--no-cache=true

Docker镜像构建时的缓存规则:

  • 如果cache存在parent image,则下一条命令执行时会比较所有派生自parent image的child images,是否执行了相同的命令;如果没有,则cache失效。

  • 在大多数情况下,仅仅是用指令比较child images就可以了。但是存在某些指令需要额外的检验。

  • ADD和COPY指令会验证文件内容并计算checksum。如果比较中的checksum与已存在镜像的checksum不同,则cache失效。

results matching ""

    No results matching ""