介绍
报告应用的配置已为只读,但仍以 root 运行。你作为维护者,需要选择预置的应用用户,同时保持真实文档生成功能。
这个独立环境有自己的报告容器和数据。你会检查 UID 和输出所有权,编辑之前练习过的启动格式,再重建并测试服务。请先完成“保护挂载的配置”实验。
认识应用用户
在这一步中,建立正常服务行为,并区分维护用户与容器进程用户。这个新环境的配置挂载已只读,但生成器仍以 root 运行。
使用 Maintenance,起始目录是 /home/labex/project/report-desk。该终端只管理预置的 report-renderer 容器。必要时用 cd /home/labex/project/report-desk 返回。sudo docker exec 请求 Docker 在目标内执行命令。id 显示数字用户 ID(UID)和组 ID(GID):
sudo docker exec report-renderer id
uid=0(root) gid=0(root) groups=0(root)
容器内 UID 0 就是 root,对可访问文件的权限超过报告应用的需要。容器 root 不是另一台 VM 的管理员,容器共享宿主机内核。本练习减少应用文件访问,并不解决所有容器风险。
预置应用身份是 UID/GID 1200:1200。数字 ID 无需在镜像中添加具名账户即可使用。宿主机目录所有者必须允许该用户写入。ls -ldn 列出目录本身(-d)、详细权限(-l)和数字 ID(-n):
ls -ldn output
找到 drwxr-xr-x 和所有者/组 1200 1200。所有者有 rwx:读取、写入和目录遍历。其他人有 r-x:读取、遍历但不能写入。环境已为预期身份准备好这个目录。
使用已练习的 POST 请求生成基准文档。curl -fsS 报告 HTTP 错误,-X POST 请求业务操作:
curl -fsS -X POST http://localhost:8090/render/baseline
{"saved": "/output/baseline.json", "total": 37, "uid": 0}
报告可用,但仍由 UID 0 生成。打开 Document Desk 查看存储的文档;该页面列出真实输出文件。
选择预置身份
在这一步中,修改启动声明中的应用身份,保留必要的文件系统访问。cat 显示脚本:
cat launch.sh
sudo 授权宿主机管理操作。另一个选项 --user 决定容器应用的用户和组。0:0 表示 UID 0、GID 0;改成 1200:1200 就选择预置身份。保留端口 8090、预置镜像和两个挂载路径。配置行已包含 dst=/config,readonly,输出行必须保持可写。
打开终端编辑器:
nano launch.sh
用方向键将 --user 0:0 替换为 --user 1200:1200,只修改这一处。按 Ctrl+O、Enter 保存,Ctrl+X 退出。再次显示文件:
cat launch.sh
用户行应为:
--user 1200:1200 \
只修改声明不会更新运行进程。重建前,明确输出目录所需所有权。chown 设置数字所有者和组;这些 ID 与宿主机维护用户不同,因此需要 sudo。这只影响输出目录,不影响其中所有现有文件:
sudo chown 1200:1200 output
不要将所有内容都设为只读,文档生成需要写入输出。也不要用允许所有人写入来绕过所有权问题;现有目录权限 755 已允许预置所有者写入。
重建并保留业务结果
在这一步中,应用新身份,测试正常输出和受保护的输入边界。像之前一样,只移除目标容器,再启动替代容器:
sudo docker rm -f report-renderer
bash launch.sh
若启动失败,用 nano 修正 launch.sh,使用同一删除命令移除失败目标,再次运行脚本。宿主机数据仍保留。检查运行身份:
sudo docker exec report-renderer id
uid=1200 gid=1200 groups=1200
稍等片刻让服务启动,然后生成最终文档:
curl -fsS -X POST http://localhost:8090/render/final
{"saved": "/output/final.json", "total": 37, "uid": 1200}
Permission denied 通常表示输出目录所有者不正确,或之前的 root 运行创建了 final.json。用已学的 sudo chown 1200:1200 output 修正目录。如果存在旧的最终文件,sudo rm output/final.json 只删除该生成文档,然后重新请求。若 /output 返回 Read-only file system,说明误将输出挂载设为只读;需修正声明并重建容器。
检查生成的文件。ls -ln 显示数字文件所有者,cat 显示内容:
ls -ln output/final.json
cat output/final.json
找到所有者 1200、"uid": 1200、总额 37 和 Report for Harbor Books: 37 orders。刷新 Document Desk 查看新文件。最后确认配置保护仍在:
sudo docker exec report-renderer touch /config/probe.txt
touch: /config/probe.txt: Read-only file system
这个失败符合预期。非 root 身份与只读挂载解决不同问题:UID 选择减少进程权限,而挂载模式即使对容器 root 也会阻止配置写入。生成器仍能完成真实任务。
总结
你区分了宿主机维护权限与应用身份,选择 UID/GID 1200,并保留了输出目录。运行进程和新生成的文档现在使用 UID 1200,配置写入仍被拒绝。



