在Docker中启用--read-only参数可使容器根文件系统(/)整体只读,有效防范后门写入;需配套使用--tmpfs挂载/tmp、/run等必要可写路径,并通过docker inspect验证ReadOnlyRootfs为true。

直接在容器启动时加 --read-only 参数,就能让整个根文件系统(/)变成只读,这是防后门写入最有效的一步。它不是只限制某个挂载卷,而是从内核挂载层面锁定所有系统路径,比如 /etc、/usr/bin、/lib 都无法被修改或新增文件。
用 docker run 设置只读根目录
命令里加上 --read-only 即可:
docker run --read-only -d nginx:alpine- 如果应用需要临时写入,必须配套加
--tmpfs,例如:--tmpfs /tmp --tmpfs /run --tmpfs /var/run - 避免漏掉关键路径:/tmp 是脚本解压和缓存常用位置;/run 和 /var/run 存 PID、socket,不挂 tmpfs 容器大概率启动失败
docker-compose.yml 中配置 read_only
Docker Compose v3.8+ 支持服务级 read_only: true 字段,写在服务定义下:
- 不是写在
volumes里,也不是用:ro——那是挂载卷只读,跟根文件系统无关 - 正确写法示例:
services: app: image: myapp:latest read_only: true tmpfs: - /tmp - /run - /var/run - 验证是否生效:容器运行后执行
docker inspect <container_id> | grep ReadOnlyRootfs,返回true即成功
配套必须做的几件事
只设只读不配可写空间,90% 的应用会静默退出或报错。以下三项建议同步配置:
- 用
--tmpfs或tmpfs:挂载内存卷到/tmp、/run、/var/run;如需日志落盘,单独挂/var/log并用 sidecar 收集,不要让它写宿主机磁盘 - 非 root 用户运行:
--user 1001:1001或 Dockerfile 里加USER 1001,避免提权风险 - 删掉默认能力:
--cap-drop=ALL,再按需加回,比如--cap-add=NET_BIND_SERVICE(绑定 80 端口)
常见误区提醒
很多人以为在 volumes 里写 :ro 就等于根目录只读,其实完全不是:
-
volumes: - ./conf:/etc/nginx:ro只让/etc/nginx只读,/etc/passwd、/bin/sh还是可写的 - 攻击者仍可往
/usr/local/bin写恶意二进制,或改/etc/crontab加持久化任务 - 真正起作用的是容器启动时的
--read-only或 Compose 的read_only: true,它控制的是 rootfs 的挂载属性


















