You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GitLab CI/CD中缓存pnpm store与node_modules并优化依赖安装

问题根源分析

  1. GitLab CI缓存配置无效:当前job使用docker:20.10.17镜像,该镜像无Node.js环境,node_modules和pnpm store是在Docker构建过程中生成于容器内部,而非job的工作目录,因此GitLab无法捕获这些文件进行缓存(日志中的警告已明确说明这点)。
  2. 未启用Docker构建缓存:即使package.json未变更,每次Docker构建都是全新环境,无法复用之前的依赖安装层。

解决方案

方案一:启用Docker构建缓存(最直接有效)

利用Docker自身的层缓存机制,结合--cache-from参数复用已构建的镜像层,跳过依赖安装步骤。

  1. 修改.gitlab-ci.yml的script部分,启用缓存拉取和构建缓存:
script:
  - docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
  # 拉取最新镜像作为缓存源,不存在则忽略
  - docker pull $TAG_LATEST_BACKEND_MANAGER || true
  # 构建时指定缓存源,复用已有的依赖安装层
  - docker build --cache-from $TAG_LATEST_BACKEND_MANAGER -f $BACKEND_MANAGER_DOCKERFILE_PATH -t $TAG_LATEST_BACKEND_MANAGER .
  - docker push $TAG_LATEST_BACKEND_MANAGER
  1. 保持Dockerfile层顺序最优:当前Dockerfile已将COPY package.json放在RUN pnpm install之前,这是正确的——只要package.json内容不变,Docker就会复用该层,跳过依赖安装。

方案二:缓存pnpm store(进一步加速依赖安装)

如果需要缓存pnpm的全局存储,减少重复下载包的时间,可通过以下配置实现:

  1. 修改Dockerfile,指定pnpm store路径到项目目录(方便GitLab缓存捕获):
FROM node:alpine As development

# 指定pnpm store路径为项目内的.pnpm-store
ENV PNPM_STORE_PATH="/usr/src/app/.pnpm-store"
ENV PNPM_HOME="/usr/local/bin"

WORKDIR /usr/src/app

COPY package.json ./

RUN npm i -g pnpm
# 安装时指定store目录
RUN pnpm install --store-dir $PNPM_STORE_PATH

COPY . .

RUN pnpm build:nbm

FROM node:alpine As production

ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
ENV PNPM_STORE_PATH="/usr/src/app/.pnpm-store"
ENV PNPM_HOME="/usr/local/bin"

WORKDIR /usr/src/app

COPY package.json ./

RUN npm i -g pnpm
RUN pnpm install --prod --store-dir $PNPM_STORE_PATH

COPY --from=development /usr/src/app/dist ./dist

CMD [ "node", "./dist/apps/backend-manager/main" ]
  1. 修改.gitlab-ci.yml的缓存配置,基于package.json内容生成缓存键,并缓存.pnpm-store:
cache:
  key:
    # 基于package.json内容生成唯一缓存键,仅当文件变更时更新缓存
    files:
      - ./apps/backend-manager/package.json
  paths:
    - .pnpm-store/
  # 保留缓存,避免被自动清理
  policy: pull-push

backend-manager-build:
  # 其他配置保持不变
  script:
    - docker login -u $CI_DEPLOY_USER -p $CI_DEPLOY_PASSWORD $CI_REGISTRY
    - docker pull $TAG_LATEST_BACKEND_MANAGER || true
    # 构建时挂载本地缓存的pnpm store到容器内
    - docker build --mount=type=bind,source=.pnpm-store,target=/usr/src/app/.pnpm-store --cache-from $TAG_LATEST_BACKEND_MANAGER -f $BACKEND_MANAGER_DOCKERFILE_PATH -t $TAG_LATEST_BACKEND_MANAGER .
    - docker push $TAG_LATEST_BACKEND_MANAGER

额外优化建议

  • 合并Dockerfile中重复的pnpm安装步骤:新增一个基础阶段,避免在development和production阶段重复安装pnpm:
FROM node:alpine As pnpm-base

ENV PNPM_HOME="/usr/local/bin"
RUN npm i -g pnpm

FROM pnpm-base As development
# ... 后续development阶段内容

FROM pnpm-base As production
# ... 后续production阶段内容
  • 确保$BACKEND_MANAGER_RULES_CHANGES_PATH包含./apps/backend-manager/package.json,这样只有当相关文件变更时才触发构建(按需配置)。

内容的提问来源于stack exchange,提问作者scripter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:25:55