Docker构建时出现‘Read-only filesystem’错误的原因排查
Docker构建时Bind Mount写入失败:只读文件系统问题解析
问题原因解析
这个错误和Docker的安装方式无关,主要由两个核心因素导致:
scratch镜像的特性scratch是完全空的基础镜像,没有任何可写文件系统层,也没有基础工具组件。在scratch镜像中执行写入操作时,即使绑定了本地目录,底层根文件系统本身是只读的,直接写入.(根目录)会触发权限错误。BuildKit Bind Mount的默认权限
Docker BuildKit的RUN --mount=type=bind默认以只读模式挂载本地目录,就算使用带有可写层的基础镜像,默认也无法向挂载目录写入内容,必须显式开启可写权限。
解决方案
根据你生成文件并导出到本地的需求,有两种可行的修正方式:
方式1:使用带可写文件系统的基础镜像 + 开启Bind Mount可写权限
把基础镜像换成alpine这类轻量且带有可写层的镜像,同时给bind mount添加readonly=false参数:
FROM alpine:latest as lint-base RUN --mount=type=bind,target=/workspace,readonly=false \ cd /workspace && echo "test" > lint-result
方式2:更推荐的文件导出方式(无需Bind Mount写入)
直接在构建容器内生成文件,通过--output参数自动导出到本地,这是Docker Build导出产物的标准用法:
FROM alpine:latest as lint-base # 在容器内生成文件 RUN echo "test" > /lint-result
构建命令保持不变:
docker build --output=. --target=lint-base -t lint-debug --progress=plain .
执行后,本地目录会自动得到导出的lint-result文件。
总结
- 避免在
scratch镜像中执行写入操作,它仅适合作为静态二进制文件的最终镜像。 - BuildKit的Bind Mount默认只读,写入需显式声明
readonly=false。 - 导出构建产物优先使用
--output机制,比直接写入Bind Mount更符合Docker构建的设计逻辑。
内容的提问来源于stack exchange,提问作者Ragg
相关产品推荐
相关产品推荐

