如何在GitHub Actions中缓存/var/lib/docker以避免重复拉取镜像?
解决GitHub Actions中Docker镜像缓存问题
为什么直接缓存/var/lib/docker行不通
/var/lib/docker是Docker守护进程的核心数据目录,默认由root用户拥有,GitHub Actions的runner进程没有足够权限直接读写这个目录,强行操作会触发权限错误。另外,这个目录和Docker daemon的运行状态强绑定,直接缓存整个目录容易导致镜像数据和daemon状态不一致,引发未知问题。
方案一:用Buildx配置镜像层缓存(推荐)
setup-buildx-action并非多余,它能创建支持高级缓存特性的Buildx构建器,让你可以把Docker镜像层缓存到GitHub Actions的缓存系统里,无需手动处理目录权限。
修改后的工作流示例:
jobs: foo: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 # 初始化Buildx构建器 - uses: docker/setup-buildx-action@v3 # 配置缓存:从GitHub缓存加载,构建后再存回去 - uses: docker/build-push-action@v6 with: context: . pull: true push: false tags: my-built-image:latest cache-from: type=gha cache-to: type=gha,mode=max # 后续的docker操作可以直接使用缓存的镜像层 - run: | # 这里的docker操作会自动复用缓存的foo/foo镜像层 docker run --rm my-built-image:latest
方案二:手动导出/导入镜像缓存(针对仅需缓存基础镜像场景)
如果你的需求只是缓存foo/foo基础镜像,不需要构建新镜像,可以用导出tar文件的方式避开权限问题:
jobs: foo: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 # 尝试从缓存加载镜像文件 - uses: actions/cache@v4 id: docker-cache with: path: /tmp/foo-image.tar key: foo-image-cache-v1 # 缓存不存在时,拉取镜像并导出 - if: steps.docker-cache.outputs.cache-hit != 'true' run: | docker pull foo/foo docker save -o /tmp/foo-image.tar foo/foo # 缓存存在时,导入镜像 - if: steps.docker-cache.outputs.cache-hit == 'true' run: docker load -i /tmp/foo-image.tar # 后续操作直接使用foo/foo镜像 - run: | # 这里使用foo/foo作为父镜像构建或运行容器 docker run --rm foo/foo
内容的提问来源于stack exchange,提问作者yegor256




