DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

scratch 镜像设置 USER nobody 后无法启动:镜像里没有用户记录

scratch镜像没有默认账号记录,USER只选择身份。检查数字UID/GID、最小passwd/group映射与目录权限。

程序在 scratch 镜像里能启动,增加 USER nobody 后却报 Unable to find user nobody 或找不到 /etc/passwd 中的用户。先检查最终镜像是否提供了名字到 UID/GID 的映射。USER 选择运行身份,不会替镜像创建账号。

本文适用于 Linux 容器中的 scratch 最终阶段。前提是程序本身已经能在这个运行环境中执行;动态加载器、证书和时区等依赖缺失是另外的问题。

builder 中创建的账号不会自动进入 scratch

scratch 没有普通发行版的默认文件系统。只复制应用二进制时,不会同时得到 builder 的 /etc/passwd、/etc/group、shell 或 useradd。

查看最后一个 FROM 之后的全部 COPY 和 USER。如果只有二进制与静态资源,名字 nobody 没有记录可供解析。不要在 scratch 中追加 RUN useradd nobody:普通 shell 形式的 RUN 还需要 /bin/sh,空环境也没有 useradd 可执行文件。

只需要进程身份,可以指定数字 UID 和 GID

应用不依赖按用户名查询账号时,可以显式指定数字身份。下面是结构示例,app 表示构建上下文内已经准备好、适合 scratch 运行的程序:

FROM scratch
COPY app /app
USER 65534:65534
ENTRYPOINT ["/app"]

65534:65534 是示例身份,须按项目约定选择。同时指定 GID,避免只设置 UID 后组身份与预期不同。它不会创建 home 目录或账号记录,程序若调用按 UID 查询用户名等接口,仍可能失败。

配置身份前检查程序需要读写的路径。普通文件权限按数字身份判断;需要写入的挂载目录也应与部署方式相容。不要为了启动成功把整个持久数据目录改成全员可写。使用 rootless 或用户命名空间映射时,宿主机看到的 UID 可能经过映射,应按实际部署规则配置。

程序需要用户名时,补最小记录

若应用确实需要 nobody 这个名字,可以准备项目自己的最小文件并复制进入镜像。以下是示例内容,放在构建上下文中:

passwd:

nobody:x:65534:65534:nobody:/nonexistent:/sbin/nologin

group:

nobody:x:65534:

对应 Dockerfile 片段:

FROM scratch
COPY passwd /etc/passwd
COPY group /etc/group
COPY app /app
USER nobody:nobody
ENTRYPOINT ["/app"]

这里的 home 和登录 shell 字段只是账号记录,不会让对应目录或程序自动出现;容器入口直接执行 /app,不通过登录 shell。若应用需要真实 home 目录,应额外提供目录并配置权限。

从 builder 复制整个账号文件也能提供映射,但会带入额外账号。确认确实需要哪些身份,再决定使用最小文件还是已经维护好的兼容运行基础镜像。

验收身份和文件访问

重建后应不再出现用户解析错误,应用以约定 UID/GID 运行,并能按预期访问资源和写入目录。scratch 通常不能直接执行 sh 或 id,不要把这些工具不存在误认为修复失败;使用部署平台的进程信息或应用提供的身份诊断。

保留旧镜像和部署配置再切换。新增非 root 身份可能使原来可写的目录不再可写,先在验收环境检查;生产切换失败时恢复旧镜像,不删除或重置持久数据。