直接挂载为只读必须用 --mount,-v 不支持创建时声明只读;:ro 仅限当前容器且行为不可靠,--mount 可显式设 readonly 确保挂载级只读。

直接挂载为只读是可行的,但必须用 --mount,-v 语法不支持在创建时声明只读(它只支持运行时加 :ro,且行为有歧义)。
为什么 -v myvol:/data 加 :ro 不可靠?
很多人试过 -v myvol:/data:ro,看似生效,但实际存在两个问题:
-
:ro是挂载选项,不是卷属性——它只影响当前容器对该卷的访问权限,不阻止其他容器以读写方式挂载同一卷 - 在 Docker Desktop(尤其是 Windows/macOS)上,
-v的:ro有时被忽略或与文件系统层权限叠加出意外行为(比如容器内touch报错但echo >成功) - 更关键的是:
-v无法表达“该卷本身应被所有挂载者视为只读”的语义,而--mount可以显式控制
--mount 挂载命名卷为只读的正确写法
使用 --mount 是 Docker 官方推荐的明确、可复现的方式。只读挂载需同时满足两个条件:
- 指定
type=volume+source=卷名+target=容器路径 - 显式添加
readonly或read_only(两者等价,Docker 接受)
示例命令:
docker run -d \ --name nginx-ro \ --mount type=volume,source=my-static-content,target=/usr/share/nginx/html,readonly \ -p 8080:80 \ nginx:alpine
验证是否生效:
- 进入容器:
docker exec -it nginx-ro sh - 尝试写入:
echo test > /usr/share/nginx/html/test.txt→ 应报错Read-only file system - 检查挂载信息:
mount | grep html→ 输出含ro,标志
Docker Desktop 图形界面里没法设只读?
是的,Docker Desktop 的 Volume 挂载 UI(Containers → Edit → Volumes)目前不提供只读开关。它只允许你选择卷名和容器路径,底层仍生成 -v 语法,无法注入 readonly。
所以如果你依赖 GUI 操作,必须:
- 改用 CLI 启动容器(推荐)
- 或先用 GUI 创建卷,再用 CLI 命令挂载(GUI 本身不管理挂载选项)
- 注意:不要试图在 GUI 的“Host path”字段填
myvol:ro—— 它会当成主机路径字面量解析,导致挂载失败
只读卷的典型误用和边界
只读是挂载层面的限制,不是数据保护机制:
- 宿主机上仍可直接修改
/var/lib/docker/volumes/my-static-content/_data/下的文件(Linux/macOS),容器下次读取会看到新内容 - 如果多个容器挂载同一卷,一个容器以读写方式启动(如
--mount source=myvol,target=/data无readonly),它就能改写数据,其他只读容器会立刻看到变更(但自己仍不能写) - 卷本身没有“只读属性”,只读只存在于某次挂载上下文中——这是设计使然,也是灵活性来源
真正需要防篡改的场景(比如分发静态资源包),应该在构建镜像时把内容 COPY 进只读层,而非依赖运行时挂载控制。











