web*_*ter 4 caching build npm docker package.json
当 package.json 或 package-lock.json 中的某些内容发生更改时,Docker 不会使用构建缓存,即使这只是文件中的版本号,也不会更改任何依赖项。
我怎样才能实现它,以便 docker 每次都使用旧的构建缓存并跳过 npm install (npm ci)?我知道 docker 会查看文件的修改日期。但 package.json 根本没有改变,只是版本号改变了。
下面是我的 Dockerfile
FROM node:10 as builder
ARG REACT_APP_BUILD_NUMBER=X
ENV REACT_APP_BUILD_NUMBER="${REACT_APP_BUILD_NUMBER}"
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY .npmrc ./
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=builder /usr/src/app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Run Code Online (Sandbox Code Playgroud)
以下是一些有助于缓解此问题的解决方案。每种方法都需要权衡,但它们不一定是相互排斥的——它们可以混合在一起以获得更好的整体构建性能。
Docker BuildKit使用实验标志可以部分缓解此问题RUN --mount=type=cache。它支持在映像构建过程中安装可重用的缓存。
这里需要注意的是,对 Docker BuildKit 的支持在 CI/开发环境之间可能会有很大差异。检查文档和构建环境以确保它有适当的支持(否则,它将出错)。以下是一些要求(但不一定是详尽的列表):
DOCKER_BUILDKIT=1Docker BuildKit 需要通过守护进程/cli 配置显式启用或默认启用。Dockerfile以启用实验支持:# syntax=docker/dockerfile:1.2Dockerfile下面是一个利用此功能的示例,在本地缓存 npm 依赖项以便/usr/src/app/.npm在后续构建中重用:
# syntax=docker/dockerfile:1.2
FROM node
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json package-lock.json /usr/src/app
RUN --mount=type=cache,target=/usr/src/app/.npm \
npm set cache /usr/src/app/.npm && \
npm ci
Run Code Online (Sandbox Code Playgroud)
笔记:
npm仍然需要将它们安装到node_modules目录中。对中型项目的测试表明,这确实减少了一些构建时间,但构建node_modules仍然是不可忽略的。/usr/src/app/.npm不会包含在最终构建中,并且仅在构建期间可用(但是,将.npm存在一个挥之不去的目录)。node_modules不建议缓存。删除依赖项package.json可能无法正确传播。如果尝试的话,您的里程可能会有所不同。package.json在主机上,脚本仅从中提取dependencies和标签,并将这些标签复制到新文件中,例如.devDependenciespackage.jsonpackage-dependencies.json
例如package-dependencies.json:
# syntax=docker/dockerfile:1.2
FROM node
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json package-lock.json /usr/src/app
RUN --mount=type=cache,target=/usr/src/app/.npm \
npm set cache /usr/src/app/.npm && \
npm ci
Run Code Online (Sandbox Code Playgroud)
在Dockerfile、COPY和package-dependencies.json中package-lock.json安装依赖项。然后,复制原件package.json。package-lock.json除非或 的package.json/dependencies标签发生更改devDependencies,否则这些层将被缓存并从以前的构建中重用,这意味着对 的微小更改package.json将不需要运行npm ci/ npm install。
这是一个例子:
FROM node
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# copy dependency list and locked dependencies
COPY package-dependencies.json package-lock.json /usr/src/app/
# install dependencies
RUN npm ci
# copy over the full package configuration
COPY package.json /usr/src/app/
# ...
RUN npm run build
# ...
Run Code Online (Sandbox Code Playgroud)
笔记:
npm ci。package-dependencies.json将在图层历史记录中。虽然该文件的大小可以忽略不计/无关紧要,但它仍然是“浪费的空间”,因为最终图像中不需要它。package-dependencies.json. 根据构建环境的不同,这可能实施起来很烦人。这是使用 cli 实用程序的示例jq:
cat package.json | jq -S '. | with_entries(select (.key as $k | ["dependencies", "devDependencies"] | index($k)))' > package-dependencies.json
Run Code Online (Sandbox Code Playgroud)
解决方案我将在本地启用 npm 依赖项缓存,以便更快地获取依赖项。仅当更新依赖项或开发依赖项时,解决方案 II 才会触发npm ci/ 。npm install这些解决方案可以一起使用,以进一步加快构建时间。
| 归档时间: |
|
| 查看次数: |
6685 次 |
| 最近记录: |