在使用 Docker BuildKit 构建 Docker 映像时,我正在尝试生成并重新使用
yarn install
缓存。纱线缓存保存在目录 .yarn/cache
中,永远不应包含在最终图像中(.yarn/cache
相对于构建上下文根)。 .yarn/cache
目录应该在多个构建之间共享,以便始终从热缓存开始并具有快速的 yarn install
命令(即使我们由于 package.json
的更改而导致缓存未命中)。如果我们可以在 .yarn/cache
结束后访问 docker build
内容,将很容易在多个构建之间共享,例如将其上传到 Amazon S3 或 GCS 存储桶。
我考虑过两种选择:
RUN --mount=type=bind
RUN --mount=type=cache
下面描述了为什么这两种方法都不起作用。
(简化的)Dockerfile 如下所示:
ENV YARN_CACHE_FOLDER ".yarn/cache"
COPY package.json yarn.lock ./
RUN --mount=type=bind,source=.yarn/cache,target=.yarn/cache,rw yarn install --frozen-lockfile
不幸的是,在
.yarn/cache
命令结束后,docker build
目录中没有数据。
在
rw
选项documentation中描述了没有数据持久化的原因:Allow writes on the mount. Written data will be discarded
。如果写入的数据被丢弃,第一次生成缓存的工作方式是什么?
RUN --mount=type=cache
或者我考虑使用
RUN --mount=type=cache
。不幸的是,似乎没有一种简单的方法可以将缓存持久保存在构建主机的本地目录中,以便轻松保存到 Amazon S3 或 GCS 存储桶中。如果缓存没有持久化,如果 Docker 守护进程状态没有在它们之间共享,我们就不能在不同的 Cloud Builds 之间使用它。
换句话说:在不同机器上运行的不同
docker build
之间共享缓存目录的最佳方法是什么,而不在图像中包含此缓存?还有其他我在这里失踪的方式吗?
RUN --mount=type=bind
:允许像本地目录一样挂载目录,但实际上不允许写入该目录,所以我无法在第一次运行时生成缓存。RUN --mount=type=cache
:允许在同一台机器上的多个构建之间共享缓存,但是如果我们运行多个不同的docker build
(在不同的机器上)它不会有帮助,因为缓存总是空的。如果您使用默认的基本节点图像,例如
node:16
,你可以通过做这样的事情来完成你想要的:
FROM node:16
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN --mount=type=cache,target=/usr/local/share/.cache/yarn \
yarn install --frozen-lockfile --ignore-scripts --production
COPY . .
RUN yarn build
基于在您的 OP 中使用
docker build
,我建议您查看 docker build --help
的输出。您可以在命令行上传递一个 --cache-from
和 --cache-to
标志来告诉 docker build
将缓存保存在何处。