如何在Azure Pipeline中用Cache Task缓存npm加速Docker构建
问题描述
希望通过Azure Pipeline的Cache Task缓存npm依赖,在后续Docker镜像构建时复用该缓存以缩短构建时间。目前几乎不会修改package.json,但Docker构建中npm ci占据大部分耗时。现有尝试的配置如下:
azure-pipeline.yml
- "test" resources: - repo: self pool: vmImage: "ubuntu-latest" variables: tag: "$(Build.BuildId)" DOCKER_BUILDKIT: 1 npm_config_cache: $(Pipeline.Workspace)/.npm steps: - task: Cache@2 inputs: key: 'npm | "$(Agent.OS)" | package.json' path: "$(npm_config_cache)" cacheHitVar: "CACHE_RESTORED" displayName: Cache npm - script: npm ci - task: Docker@2 displayName: Build an image inputs: command: "build" Dockerfile: "**/Dockerfile.test" arguments: "--cache-from=$(npm_config_cache)" # 此处尝试使用缓存的写法不正确 tags: "$(tag)"
Dockerfile
FROM node:19-alpine as build WORKDIR /app COPY package.json . ENV REACT_APP_ENVIRONMENT=test RUN npm ci --cache $(npm_config_cache) # 此处写法不正确,希望实现复用外部缓存的功能 COPY . . RUN npm run build #Stage 2 FROM nginx:1.23.2-alpine WORKDIR /usr/share/nginx/html RUN rm -rf * COPY nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=build /app/build /usr/share/nginx/html EXPOSE 80 ENTRYPOINT ["nginx", "-g", "daemon off;"]
想在Docker构建步骤中复用之前Cache Task缓存的npm依赖,请问该如何实现?现有思路是否有误?
解决方案
你的思路方向是对的,但存在核心认知偏差:--cache-from是用来复用Docker镜像层缓存的,而非Agent机器上的本地npm缓存;同时Docker构建容器默认无法直接访问Agent的文件系统,需要通过挂载目录的方式把Agent的npm缓存传入容器。
步骤1:修改azure-pipeline.yml配置
- 移除多余的
script: npm ci步骤(Dockerfile中已经包含该操作,单独执行会重复耗时) - 在Docker构建的
arguments中添加绑定挂载参数,把Agent上的npm缓存目录挂载到Docker构建容器内部的npm默认缓存路径(或指定路径) - 确保
DOCKER_BUILDKIT=1已开启(你已经配置了,这是使用挂载特性的前提)
修改后的azure-pipeline.yml关键部分:
variables: tag: "$(Build.BuildId)" DOCKER_BUILDKIT: 1 npm_config_cache: $(Pipeline.Workspace)/.npm steps: - task: Cache@2 inputs: key: 'npm | "$(Agent.OS)" | package.json' path: "$(npm_config_cache)" cacheHitVar: "CACHE_RESTORED" displayName: Cache npm dependencies - task: Docker@2 displayName: Build Docker image inputs: command: "build" Dockerfile: "**/Dockerfile.test" arguments: > --mount=type=bind,source=$(npm_config_cache),target=/root/.npm --tag $(tag) tags: "$(tag)"
说明:
/root/.npm是node:19-alpine镜像中npm的默认缓存路径,如果你的镜像使用非root用户,需要调整为对应用户的缓存路径(比如/home/node/.npm)
步骤2:修改Dockerfile
不需要指定--cache参数,直接使用默认缓存路径即可,因为我们已经把Agent的缓存挂载到了容器内部的默认缓存路径:
FROM node:19-alpine as build WORKDIR /app COPY package.json . ENV REACT_APP_ENVIRONMENT=test # 直接执行npm ci,会自动使用挂载进来的缓存 RUN npm ci COPY . . RUN npm run build #Stage 2 FROM nginx:1.23.2-alpine WORKDIR /usr/share/nginx/html RUN rm -rf * COPY nginx/default.conf /etc/nginx/conf.d/default.conf COPY --from=build /app/build /usr/share/nginx/html EXPOSE 80 ENTRYPOINT ["nginx", "-g", "daemon off;"]
额外优化建议
如果想进一步加快Docker构建速度,可以配合Docker的镜像层缓存:
- 把
COPY package.json放在COPY . .之前,这样只要package.json不变,npm ci的镜像层就会被复用 - 可以把构建好的
build阶段镜像推送到仓库,后续构建时用--cache-from拉取该镜像作为缓存源,进一步减少重复操作
内容的提问来源于stack exchange,提问作者Huezzer
相关产品推荐
相关产品推荐

