在docker compose中配置read_only: true可使容器根文件系统(/)整体只读,有效阻止后门向/bin、/etc、/usr等关键路径写入;需配套挂载tmpfs到/tmp、/run等路径提供必要可写空间,并通过mount和touch命令验证生效。

直接在服务配置里加 read_only: true,就能让整个容器根文件系统(/)变成只读,这是防后门写入最有效的手段之一。它不是只限制某个挂载目录,而是从内核层阻止对 /bin、/etc、/usr、/var 等关键路径的任何写操作。
核心配置:启用容器级只读根文件系统
这个设置必须放在服务(service)层级,不是卷(volumes)里——很多人误把 volumes: - ./conf:/etc/app:ro 当成根目录只读,其实那只保护了那个挂载点,/etc 下其他文件仍可被篡改。
- 使用 Docker Compose v3.8 或更高版本
- 在 service 下直接添加
read_only: true - 示例片段:
web:
image: nginx:alpine
read_only: true
# 其他配置…
必须配套:挂载 tmpfs 提供必要可写空间
开启 read_only: true 后,应用若尝试往 /tmp、/run、/var/run 写临时文件或 PID,会直接报错 “Read-only file system”。所以得主动挂载 tmpfs 替代这些路径:
-
tmpfs: /tmp—— 用于脚本解压、缓存、socket 文件 -
tmpfs: /run—— 存放运行时状态、supervisord socket、systemd 临时文件 - 如需本地日志,可加
tmpfs: /var/log,但更推荐统一输出到 stdout/stderr
完整写法示例:
web:
image: nginx:alpine
read_only: true
tmpfs:
- /tmp
- /run
- /var/log
敏感挂载点也要单独设只读
即使根目录已只读,如果还挂了宿主机上的配置或密钥目录,默认仍是可写的,攻击者可能通过挂载点反向污染宿主机:
- 所有 bind mount 必须显式加
:ro,例如:- ./nginx.conf:/etc/nginx/nginx.conf:ro - 避免整目录挂只读陷阱,比如不要
- /etc:/etc:ro,因为 /etc/resolv.conf 等是动态生成的;应拆细到具体文件 - 密钥类挂载优先用
secrets,它默认以只读方式挂载到/run/secrets/,权限更可控
验证是否生效
启动后别忘了确认效果,两步检查最可靠:
- 进容器执行:
mount | grep " / " | grep ro→ 应看到类似overlay on / type overlay (ro,relatime,…) - 尝试写测试:
touch /test && echo ok || echo fail→ 必须返回 fail











