GitHub Action中容器目录挂载失败问题排查
核心问题
你遇到的报错是因为Docker构建镜像时,RUN --mount=type=bind,source=_build中的source=_build是相对路径,它指向构建上下文的根目录(GitHub Runner上你的Action仓库或代码仓库的根目录),而该目录下不存在_build文件夹,所以Docker无法找到它。本地用act测试正常是因为你本地的对应目录下已经存在_build,但GitHub Runner拉取的代码里没有这个目录。
另外,你混淆了容器运行阶段的挂载(本地docker run命令里的挂载)和镜像构建阶段的挂载(Dockerfile中RUN --mount的作用),这两个逻辑完全不同。
具体修复方案
方案1:改用缓存挂载替代绑定挂载
如果你的--mount是为了缓存构建产物加速后续构建,不要用type=bind,改用Docker的type=cache,它不需要主机提前存在目录,由Docker自动管理缓存:
# 先确保容器内目标目录存在 RUN mkdir -p /home/user/mounted_home/_build # 用cache挂载替代bind RUN --mount=type=cache,target=/home/user/mounted_home/_build \ make BUILDDIR=/home/user/mounted_home/_build -j 4 html
方案2:在GitHub Action中提前创建所需目录
如果必须用type=bind,需要在GitHub Runner上先创建_build目录,在你的工作流pr-docs-check.yml中调用自定义Action之前添加步骤:
- name: Prepare build directory run: mkdir -p ${{ github.workspace }}/_build
同时修改Dockerfile中的source路径为绝对路径(指向Runner上的代码目录):
RUN --mount=type=bind,source=${GITHUB_WORKSPACE}/_build,target=/home/user/mounted_home/_build \ make BUILDDIR=/home/user/mounted_home/_build -j 4 html
注:GITHUB_WORKSPACE是GitHub Runner的环境变量,指向当前代码仓库的根目录。
方案3:调整镜像构建逻辑,移除不必要的挂载
如果你的构建不需要在镜像阶段挂载主机目录,直接在Dockerfile中完成构建,不需要--mount:
RUN mkdir -p /home/user/mounted_home/_build WORKDIR /home/user/mounted_home/my_code_repo/doc RUN make BUILDDIR=/home/user/mounted_home/_build -j 4 html
然后在GitHub Action运行容器时,再挂载主机目录来获取构建产物(和你本地docker run的逻辑一致)。
额外提示
- 本地
act测试时,会复用你本地的文件目录,所以容易忽略GitHub Runner上的目录缺失问题,下次测试可以先删除本地_build目录再测试,模拟Runner的干净环境。 - 自定义GitHub Action时,要明确区分镜像构建上下文和工作流的代码上下文,两者的根目录可能不同,避免路径混淆。
内容的提问来源于stack exchange,提问作者Sam R

