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

GitHub Actions中Docker缓存异常:npm install层未被缓存

GitHub Actions Docker构建缓存异常:npm依赖层未命中缓存

问题概述

使用Docker官方的GitHub Actions缓存构建层方案,大部分缓存功能正常,但npm依赖层(npm ci步骤)始终无法命中缓存。尽管package.json和package-lock.json未做任何修改,理论上这部分应该100%复用,能节省约1.5分钟构建时间。

现有配置

Workflow片段

- name: Setup Docker `buildx`
  uses: docker/setup-buildx-action@v2

- name: Build & Push Docker Image 🔨
  uses: docker/build-push-action@v4
  with:
    context: .
    file: Dockerfile.development
    push: true
    tags: |
      ${{ steps.docker-tags.outputs.tag }}
    cache-from: type=gha
    cache-to: type=gha,mode=max

Dockerfile依赖阶段片段

# ------------------------------------------------------------------------------------------
# LAYER 2: Install dependencies only when needed
FROM base AS deps

# 参考nodejs docker镜像文档了解libc6-compat的作用
RUN apk add --no-cache libc6-compat

# 创建应用目录
WORKDIR /usr/src/app

# 复制依赖相关文件
COPY .env.test .npmrc ./
COPY package.json package-lock.json ./

# 仅安装生产依赖
RUN npm ci --omit dev

构建日志情况

已命中缓存的步骤

#8 [deps 1/5] RUN apk add --no-cache libc6-compat
#8 CACHED

#9 [deps 2/5] WORKDIR /usr/src/app
#9 CACHED

#10 [deps 3/5] COPY .env.test .npmrc ./
#10 CACHED

未命中缓存的关键步骤

#11 [deps 4/5] COPY package.json package-lock.json ./
# .....省略日志内容.....
#11 sha256:bc7465dc4da3894941da9beb13e53fea672b4167e0031a049feea4cd6ed2cd79 40.11MB / 40.11MB 1.1s done
#11 DONE 2.2s

#.....省略复制package.json的日志内容.....

#12 [deps 5/5] RUN npm ci --omit dev
#12 23.50 npm WARN deprecated @babel/plugin-proposal-class-properties@7.18.6: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
#.....省略日志内容.....
#12 75.77 added 1929 packages, and audited 1930 packages in 1m
#.....省略日志内容.....
#12 DONE 76.9s

异常现象:后续引用依赖的步骤却命中缓存

Dockerfile后续阶段代码:

# ------------------------------------------------------------------------------------------
# LAYER 3: Rebuild the source code only when needed
FROM node:18-alpine AS builder
WORKDIR /usr/src/app
COPY --from=deps /usr/src/app/node_modules ./node_modules

对应构建日志:

#14 [builder 3/6] COPY --from=deps /usr/src/app/node_modules ./node_modules
#14 CACHED

排查与解决方案

1. 验证依赖文件哈希一致性

GitHub Actions缓存基于文件内容哈希匹配,即使肉眼看不到变化,也可能存在隐性差异:

  • 执行git diff package.json package-lock.json确认文件无隐性变更(如换行符、空格)
  • 检查Git的core.autocrlf配置,避免跨平台换行符转换导致哈希变化

2. 调整COPY指令顺序

将依赖文件的COPY指令提前,与其他配置文件分离,确保依赖文件的变更仅影响自身缓存层:

# 先单独复制依赖文件,确保这层缓存只受package.json/lock影响
COPY package.json package-lock.json ./
# 再复制其他配置文件
COPY .env.test .npmrc ./

原配置中先复制.env.test和.npmrc,若这两个文件的哈希发生变化(哪怕内容未修改),会导致后续依赖文件的COPY层缓存失效。调整顺序后,依赖文件的缓存层独立性更强。

3. 检查Buildx缓存配置

  • 确保docker/setup-buildx-action配置正确,可添加driver-opts: network=host适配部分网络环境
  • 确认cache-to: type=gha,mode=max已配置,mode=max会缓存所有中间层,包括依赖安装层

4. 本地测试缓存命中

使用Buildx本地构建测试缓存逻辑,排除GitHub Actions环境问题:

docker buildx build --cache-from=type=gha --cache-to=type=gha,mode=max -f Dockerfile.development .

5. 清理无效缓存

GitHub Actions缓存有存储限额,若缓存已满会自动清理旧缓存。可在仓库Settings > Actions > Cache中查看缓存占用,清理无用的旧缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:10:41