下一代使用Docker构建容器的方法是使用
Buildkit。我推荐使用它,特别是因为它对于缓存问题有一个优雅的解决方案。目前在原始的Docker中并没有一个很好的解决方案;虽然你可以绕过它,但非常麻烦。
我将在这里列出两种解决方案:
使用Buildkit
Tarun的答案是正确的方向,但有一种更简洁的方法。Buildkit支持
将挂载指定为缓存。一旦你
设置Docker使用Buildkit,我们只需要做以下操作:
...
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install
...
这将自动拉取上一次运行的缓存,如果缓存不存在或已过期,则会创建新的缓存。就是这么简单。
香草Docker
或者,如果无法使用Buildkit,您可以使用香草Docker。在这里,我们可以使用
COPY
指令将构建上下文中的某种“缓存”复制进来。例如,如果我们在构建上下文的根目录中创建一个
.yarn_cache
目录,那么我们可以提供一个缓存:
...
COPY .yarn_cache /root/.yarn
RUN yarn --frozen-lockfile
...
这个外部缓存在构建图像时
不会被更新,需要在图像之外进行初始化和定期更新。您可以使用以下shell命令来完成这个操作(
在第一次运行时清除任何本地的node_modules
以强制它预热缓存):
$ YARN_CACHE_FOLDER=.yarn_cache yarn install
现在虽然这个方法可以工作,但是它非常hack-y,并且有一些缺点:
- 您需要手动创建和更新缓存。
- 整个.yarn_cache目录需要包含在构建上下文中,这可能非常慢,更不用说它将在每次构建时执行此操作,即使没有任何更改。
因此,出于这些原因,前一种解决方案更受青睐。
额外专业提示:在上述任何情况下,包括纱线缓存仍会留在最终图像中,增加其大小。如果您使用多阶段构建,可以缓解此问题:
FROM node:12-alpine as BUILDER
WORKDIR /usr/app
COPY package.json ./
COPY yarn.lock ./
RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn --frozen-lockfile
FROM node:12-alpine
WORKDIR /usr/app
COPY --from=BUILDER node_modules ./node_modules
COPY package.json ./
COPY yarn.lock ./
COPY tsconfig.json ./
COPY nodemon.json ./
RUN apk add --no-cache tini
ENTRYPOINT [ "/sbin/tini", "--" ]
ENV __DEV__=1
CMD [ "yarn", "dev" ]
yarn cache dir
可以在主机上使用,以查看 yarn 缓存存储的具体位置。 - undefined