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

如何在GitHub Actions中为多Docker构建缓存NuGet包?

解决GitHub Actions中Docker构建跨运行缓存NuGet包的问题

核心问题分析

你之前的尝试失败主要有两个原因:

  • GitHub Runner默认以普通用户(非root)运行,直接访问/root/.nuget/packages会触发权限拒绝;
  • Docker构建时的NuGet包默认下载到容器内部的/root/.nuget/packages,而非Runner主机的~/.nuget/packages,所以主机侧的这个目录是空的,无法缓存。

BuildKit的--mount=type=cache本身用法没错,但它是Docker daemon管理的本地缓存,在GitHub Actions的临时Runner环境中,每次Job结束后Runner会被销毁,这种缓存无法跨工作流运行复用,必须结合actions/cache将缓存持久化到GitHub的远程存储中。

正确的缓存方案

1. 选择Runner主机的可写目录作为缓存中转

GitHub Runner提供了${{ runner.temp }}环境变量,指向一个当前用户有完全读写权限的临时目录,我们可以用这个目录作为NuGet包的中转缓存目录。

2. 将容器内的NuGet包目录绑定挂载到Runner主机目录

在Docker构建命令中,用--mount=type=bind将Runner主机的中转目录挂载到容器内的NuGet包存储目录,让dotnet restore下载的包直接落到主机侧的目录中。

3. 用actions/cache缓存主机侧的中转目录

通过actions/cache将主机侧的中转目录上传到GitHub缓存,后续工作流运行时自动恢复,实现跨构建复用。

具体实现示例

GitHub Actions工作流配置

jobs:
  docker-build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      # 缓存NuGet包到GitHub远程存储
      - name: Cache NuGet packages
        uses: actions/cache@v3
        with:
          path: ${{ runner.temp }}/nuget-packages
          # 用项目依赖文件的哈希作为缓存键,依赖不变则命中缓存
          key: nuget-${{ hashFiles('**/*.csproj', '**/*.lock.json') }}
          # 依赖变化时回退到最近的缓存版本
          restore-keys: |
            nuget-

      # 执行Docker构建,绑定挂载缓存目录
      - name: Build Docker image
        run: |
          docker build \
            --build-arg NUGET_PACKAGES_DIR=/root/.nuget/packages \
            --mount=type=bind,source=${{ runner.temp }}/nuget-packages,target=/root/.nuget/packages \
            -t your-image-name .

Dockerfile配置

在Dockerfile中指定NuGet包的存储目录,确保dotnet restore使用挂载的目录:

# 接收从构建命令传入的NuGet包目录参数
ARG NUGET_PACKAGES_DIR
# 设置环境变量,让NuGet使用指定目录存储包
ENV NUGET_PACKAGES=$NUGET_PACKAGES_DIR

WORKDIR /app

# 先复制项目文件,利用Docker的分层缓存
COPY *.csproj ./
RUN dotnet restore

# 复制剩余代码并构建
COPY . .
RUN dotnet build -c Release --no-restore

额外说明

  • 如果你的Dockerfile中使用了非root用户运行dotnet命令,需要将容器内的挂载目录改为对应用户的~/.nuget/packages(比如/home/app/.nuget/packages),同时确保Runner主机的中转目录有足够权限;
  • 缓存键使用hashFiles生成,确保只有当项目依赖文件变化时才会重新生成缓存,最大化缓存命中率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 00:48:36