Github Runner构建Docker镜像后磁盘不足及报错问题咨询
问题背景
我有两个GitHub仓库(A和B),两者包含几乎完全相同的.github/workflows/build_and_test.yml工作流文件,内容如下:
name: Build and test on: push: branches: [ main ] pull_request: branches: [ main ] jobs: build-with-docker: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: docker/setup-buildx-action@v2 - uses: docker/build-push-action@v3 with: tags: my_tag:latest load: true context: . cache-from: type=gha cache-to: type=gha,mode=max - run: docker run my_tag pytest
仓库A情况
- Dockerfile基础镜像为
r-base:4.2.1(约782MB) - 构建完成镜像约1.71GB
- 工作流全程运行正常,无报错
仓库B情况
- Dockerfile基础镜像为
pytorch/pytorch(约5.82GB) - 构建完成镜像约6.4GB
- 工作流出现两个问题:
- 警告:
You are running out of disk space. The runner will stop working when the machine runs out of disk space. Free space left: 0 MB - 报错(
docker run my_tag pytest步骤):Unable to find image 'my_tag:latest' locally docker: Error response from daemon: pull access denied for my_tag, repository does not exist or may require 'docker login': denied: requested access to the resource is denied.
- 警告:
我怀疑报错是磁盘空间不足导致的次要问题(仓库A无此报错),但无法完全确定。想咨询:
- 是否可以在不修改仓库B的Dockerfile的前提下,减少
build-push-action步骤的磁盘占用? - 是否应该使用
docker/build-push-action文档中提到的no-cache-filters参数?
注:GitHub官方文档显示Linux Runner配备14GB SSD空间,我曾尝试在docker/build-push-action@v3中添加no-cache: true,但问题依旧,且该步骤在GitHub UI中显示运行成功,无法确定磁盘耗尽的具体时机。
解答
1. 不修改Dockerfile的磁盘占用优化方案
可以,以下是几个直接可行的方法:
- 清理Runner预装冗余文件:GitHub Linux Runner默认预装了Android SDK、.NET等大体积工具,可在工作流开头添加步骤删除无用文件释放空间:
sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/hostedtoolcache/CodeQL - 调整缓存策略:当前
cache-to: type=gha,mode=max会保存所有构建层缓存,改成mode=min仅保留最终镜像的缓存层,大幅减少缓存占用;也可通过cache-max-size限制缓存总大小,避免旧缓存堆积。 - BuildKit临时文件优化:在
docker/setup-buildx-action中添加环境变量,限制BuildKit日志和临时文件大小:- uses: docker/setup-buildx-action@v2 with: buildkitd-flags: --cache-reuse-mode=minimal env: BUILDKIT_STEP_LOG_MAX_SIZE: 10485760 BUILDKIT_STEP_LOG_MAX_SPEED: 1048576 - 定期清理Docker冗余资源:在构建前后加入清理命令,删除无用镜像、容器和缓存:
docker system prune -af --volumes
2. 是否使用no-cache-filters参数?
no-cache-filters的作用是指定哪些构建阶段不读取或写入缓存,适合过滤掉生成大体积临时文件且无需缓存的阶段。但它不能直接减少基础镜像+最终镜像本身的占用,只能避免冗余缓存层堆积。
如果磁盘耗尽是因为构建过程中某些临时阶段生成了额外大文件,且这些阶段不需要缓存,使用no-cache-filters可以间接减少磁盘占用;但如果是基础镜像+最终镜像的总大小接近Runner磁盘上限,这个参数作用有限。建议先尝试上述清理预装文件、调整缓存模式的方案,无效后再结合场景使用no-cache-filters。
另外,你遇到的镜像找不到报错,确实大概率是磁盘耗尽导致的:磁盘满后Docker无法完成镜像的本地存储/加载,解决磁盘空间问题后该报错会自动消失。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

