首先是一些关于图像、构建、注册表和客户端的信息。
图像和图层
Docker 镜像构建与层一起工作。您的每一步都Dockerfile
提交一个覆盖在前一个之上的层。
FROM node ---- a6b9ffdcf522
RUN apt-get update -y --- 72886b467bd2
RUN git clone whatever -- 430615b3487a
RUN npm install - 4f8ddac8d3b5 mynode:latest
构成图像的每一层都由 sha256 校验和单独标识。IMAGE ID
in是其中docker images -a
的一小段。
在构建主机上运行dockviz images -t
将使您更好地了解可以构建的层树。在构建运行时,您可以看到一个分支增长,然后最终层被标记,但该层保留在树中并保持与其父级的链接。
构建缓存
默认情况下,每个构建步骤都会缓存 Docker 构建。如果RUN
docker 文件中的命令未更改或COPY
您正在复制的源文件未更改,则该构建步骤不需要再次运行。该层保持不变,sha256 校验和 ID 和 docker 尝试构建下一层。
当 docker 进入需要重建的步骤时,dockviz 呈现的图像“树”将分支以创建具有新校验和的新层。此后的任何步骤都需要再次运行并在新分支上创建一个层。
登记处
注册管理机构也了解这种分层。如果您只更改新标记图像中的最顶层,那是唯一需要上传到注册表的层(有一些警告,它最适合使用最近的 docker-1.10.1+ 和注册表 2.3+ ) 注册表将已经拥有构成您的新“图像”的大部分图像 ID 的副本,并且只需要发送新图层。
客户
Docker 注册表客户端以相同的方式处理层。拉取图像时,它实际上会下载构成图像的各个层(blob)。docker pull
您可以从您或docker run
新图像时打印的图像 ID 列表中看到这一点。同样,如果大多数层都相同,那么更新将只需要下载那些已更改的最顶层,从而节省宝贵的时间。
最小化构建时间
所以你要关注的事情是
- 保持图像尺寸小
- 利用构建缓存
- 使用常见的“标记”父图像。
保持图像尺寸小
节省时间的主要方法是首先什么都不做。图像中的数据越少越好。
如果您可以避免使用完整的操作系统,请执行此操作。当您可以在busybox
oralpine
映像上运行应用程序时,它会让 Docker 之神微笑。alpine + 一个 node.js 构建小于 50MB。Go 二进制文件也是最小化大小的一个很好的例子。它们可以静态编译,并且没有依赖关系,因此甚至可以在空白scratch
图像上运行。
利用 Docker 构建缓存
将最频繁更改的人工制品(很可能是您的代码)作为Dockerfile
. 如果构建必须为一个小的文件更改更新完整的 50MB 数据,从而使构建步骤的缓存无效,则构建将变慢。
总会有一些更改使整个缓存无效(例如更新基础node
映像)。这些你只需要偶尔忍受一次。
构建中不经常更新的任何其他内容都应该放在Dockerfile
.
利用常见的“标记”父图像
尽管从 Docker 1.10 开始,镜像校验和已经得到了一定程度的修复,但使用公共父镜像可以保证您将从相同的共享镜像 ID 开始,无论何时使用该镜像FROM
。
在 Docker 1.10 之前,镜像 ID 只是一个随机的 uuid。如果您在多个主机上运行构建,则根据构建它们的主机,所有层都可能无效和替换。即使这些层实际上是同一回事。
当您有多个服务和多个Dockerfile
大致相同的 s 时,公共父图像也有帮助。每当您开始在多个 s 中重复构建步骤时Dockerfile
,将这些步骤拉出到一个公共父映像中,以便在您的所有服务之间绝对共享层。node
通过使用图像作为基础,您基本上已经得到了这个。
Node.js 技巧
如果您npm install
在代码部署每个构建之后运行,并且您有许多依赖项,那么npm install
会导致大量重复工作,而实际上每个构建并没有太大变化。node_modules
在代码更改之前建立一个工作流可能是值得的。然后npm install
只需要在package.json
更新时运行您
FROM node
WORKDIR /app
COPY package.json /app/package.json
RUN npm install && rm -rf ~/.npm
COPY . /app/
CMD [ "node", "/app/server.js" ]
分阶段构建
如果你依赖带有原生模块的 npm 包,你有时需要在容器中安装一个完整的构建链来运行npm install
. 分阶段构建现在可以轻松地将构建映像与运行映像分开。
FROM node:8 AS build
WORKDIR /build
RUN apt-get update \
&& apt-get install build-essential;
COPY package.json /build/package.json
RUN npm install; \
&& rm -rf ~/.npm;
# Stage 2 app image
FROM node:8-slim
WORKDIR /app
COPY --from=build /build/node_modules /app/node_modules
COPY . /app/
CMD [ "node", "/app/server.js" ]
其他事情
确保您的构建主机具有 ssd 和良好的互联网连接,因为有时您必须进行完整的重建,所以越快越好。AWS 通常运行良好,因为您拉取和推送的包和图像也可能托管在 AWS 上。AWS 还提供镜像注册服务 (ECR),仅用于存储成本。