TencentDB Agent Memory 的镜像用户:Dockerfile 里没有 USER 指令

2026-08-16

如果你在准备 TencentDB Agent Memory 的容器化部署,多半会先翻 README.docker.md。这个文件开头就有一张「镜像信息」表,看起来是最省事的速查表。其中一行写的是:

运行用户 tdai (uid 10001)

问题是:同一个仓库里,构建这个镜像的 MemoryCore/Dockerfile 共 164 行,里面没有 USER 指令,也没有 useradd / groupadd 这类建用户的语句。

先把口径说清楚:我们只是在快照里静态读了这些文件,没有构建镜像、没有拉镜像、没有启动过任何容器。下面所有判断都是「文件里写了什么」,不是「跑起来是什么样」。本文引用的所有路径都在该仓库的默认分支 feat/server_team 上——注意这个仓库的默认分支就是一个 feat/ 分支,不是 main 也不是 master,你贴任何 raw 链接时都得带上它。

现象:一张表里,有的行对得上,有的行对不上

这张表容易让人整张信任,但逐行核完会发现它是混着的。以 MemoryCore/Dockerfile 为参照:

表里写的MemoryCore/Dockerfile 里能不能对上
基础镜像 node:22-slim对得上,两个 stage(deps-builder / runtime)都是这个基底
端口 8420对得上,文件里有 EXPOSE 8420,HEALTHCHECK 也是 curl 本机 ${TDAI_GATEWAY_PORT:-8420}/health
PID 1 tini对得上,ENTRYPOINT ["/usr/bin/tini","--"]CMDnode --import tsx src/gateway/server.ts
运行用户 tdai (uid 10001)对不上,全文件没有 USER 行,也没有建这个用户的语句
大小 ~920MB无法核对,这是文档自述的数字,我们没有构建过镜像

所以结论不是「这张表不能用」,而是「这张表得逐行回 Dockerfile 核」。端口和 PID 1 这两行完全对得上,唯独运行用户这一行在构建文件里找不到落点。

怎么确认这是不是你遇到的那件事

判定动作很短,两步:

第一步,直接读构建文件。 打开仓库里的 MemoryCore/Dockerfile,从头到尾找有没有独立的 USER 行。这个文件 164 行,里面信息不少——两 stage 结构、build 期安装 python3 make g++ ca-certificates(注释说是给 sqlite-vec@node-rs/jieba 一类原生依赖用的)、runtime 装 curl tini ca-certificatesNODE_OPTIONS="--max-old-space-size=1536"——但没有一行是切运行用户的。

第二步,把范围扩到全仓。 这个快照里带 Docker 构建/编排语义的文件一共 7 个:MemoryCore/Dockerfile(164 行)、MemoryKnowledge/Dockerfile(89 行)、MemoryKnowledge/docker-compose.ymlMemoryPanel/docker/local/Dockerfile.local(80 行)、MemoryPanel/docker/local/Dockerfile.local.dockerignoreMemoryProxy/Dockerfile(108 行)、deploy/panel-knowledge-combined/Dockerfile(90 行)。我们逐个读过,其中唯一建了用户并切过去的是 MemoryProxy/Dockerfile:第 78 行 RUN groupadd -r app && useradd -r -g app -u 10001 -m app,第 87 行 USER app

也就是说,uid 10001 这个数字在仓库里确实存在,但它挂在 MemoryProxyapp 用户上;而 README.docker.md 那一行说的是 memory-core 镜像的 tdai 用户。两处位置分别是 README.docker.md 第 13 行和 MemoryProxy/Dockerfile 第 78、87 行,谁对谁错我们不做推断,也不去猜为什么会这样——只陈述这两处写的不一样,并以我们实读的仓库文件为准。

顺带说一句 Docker 的通用语义(这属于容器的常识、不是该项目文档里的内容):Dockerfile 里没有 USER 指令时,容器进程会以基础镜像的默认用户身份运行。具体是哪个用户,取决于你实际构建或拉取的那个镜像,我们没有构建、没有拉取,因此不下结论,也不替你判断这是否可接受。

这个文件里还有几处同类差异,一起核了省事

既然已经打开 README.docker.md,把它其余的引用一起核一遍更省时间。我们在快照里用 [ -e ] 逐个判定过它引用的路径,下面这些在快照里不存在

  • MemoryCore/tdai-gateway.service.yamlREADME.docker.md 第 33、42、161、257 行多次引用)
  • MemoryCore/tdai-gateway.real.yaml(第 75、258 行)
  • MemoryCore/docker-compose.local.yaml(第 84、255 行)
  • MemoryCore/deploy/k8s/tdai-memory.yaml(第 184、259 行)
  • MemoryCore/scripts/mock-shark-server.ts(第 71、260 行)

存在的则有 MemoryCore/tdai-gateway.standalone.yamlMemoryCore/tdai-gateway.yamlMemoryCore/src/gateway/server.tsMemoryProxy/config.example.yamlMemoryKnowledge/openapi.yaml 等。缺的那几个里,tdai-gateway.service.yaml 尤其值得注意:README.deployment.md 描述的 Service 模式(Redis 做分布式锁与任务队列、TCVDB 做向量、COS 做对象存储、Shark 配置服务)要用的配置模板正是这一个,而它不在快照里。我们没有去逐个验证这套依赖在 MemoryCore/src 里的代码路径是否完整,只记录「文档描述了这套依赖,模板文件缺失」这一个事实。

还有一处口径也在这个文件里:README.docker.md 第 264 至 266 行的 ## License 小节原文写的是 Proprietary — Tencent Cloud;而仓库 LICENSE 文件第 5 行写的是「TencentDB Agent Memory is licensed under the MIT.」,README_CN.md 第 11 行挂的也是 MIT 徽章;GitHub 侧则未能自动识别其协议,显示 NOASSERTION。三处口径不同,以官方 LICENSE 原文为准,我们不解读、也不延伸。

核完之后怎么办,以及什么情况说明不是这一处

核对的产出应该是「你知道该信哪份文件」,而不是「谁写错了」。具体到这一处:

如果你是按 MemoryCore/Dockerfile 自己构建镜像,那么运行用户这件事在这份构建文件里没有任何交代,README.docker.md 那一行不能作为依据。你要不要让容器以非 root 用户运行、怎么做,那是你自己的部署决定——这属于通用运维范畴,不是该项目文档给出的做法,本文也不构成安全方案建议。

下面这几种情况,说明你遇到的不是这一处差异:

  • 你拉的是文档里提到的公开镜像(agentmemory/memory-core 等),而不是自己构建的。我们没有拉取过任何镜像,无法核实它内部实际以哪个用户运行,这一节的结论对它不成立,请自行在镜像里核。
  • 你的容器其实是 memory-proxy。那份 Dockerfile 里 USER app 是明确存在的,不存在这处差异。
  • 你比对的是版本号而不是用户。这个仓库的版本口径本身就有四处:CHANGELOG.md 第 12 行是 2.0.1-beta.1ROADMAP_CN.md 第 5 行写「当前版本 v2.0.1-beta.1」、README_CN.md 第 299 行写「当前版本 v2.0.0」、MemoryCore/package.json 里是 2.0.0-beta.1CHANGELOG.md 第 156 行还写明「Docker 镜像 tag 独立于 npm 版本」。那是另一件事。
  • 你在找端口对不上的原因。Knowledge 在独立镜像里是 8421MemoryKnowledge/Dockerfile),在合并镜像与三件套脚本里是 8424;Panel 独立镜像是 8123,合并镜像是 8125。这也是另一件事。

一句必须说在前面的话

这个项目会采集并存储团队的对话、文档与代码:Wiki 从导入的文档生成,CodeGraph 索引导入的代码库,Chat Memory 与 Skill 从对话 Session 里提取。仓库自己在 deploy/global-images/README.md 第 112 至 113 行也提醒过,三个默认凭据「只适合个人本地跑通流程,生产/联调/公网暴露前必须替换成随机长串」。这些是敏感数据,是否部署、怎么部署,请结合你自己的合规要求评估。

最后提醒版本状态:截至我们采集时,主模块 MemoryCore 的版本是 2.0.0-beta.1MemoryKnowledge / MemoryPanel / MemoryProxy 三个模块的 package.json 版本都还是 0.1.0ROADMAP_CN.md 第 7 行自己写明路线图「不是承诺,范围与时间可能调整」。本文核到的行号、字段与文件结构随版本变动,用之前请以仓库当前内容为准。

延伸阅读


本文依据 TencentDB Agent Memory 官方仓库(github.com/TencentCloud/TencentDB-Agent-Memoryfeat/server_team 分支上的 README、INSTALL、CHANGELOG、ROADMAP 与四个模块的源码整理, 核对日 2026-08-16,对应仓库快照 97f9465。该仓库的默认分支即为 feat/server_team。 本文内容为仓库源码与文档口径,我们没有部署、也没有运行过该项目的任何一个模块, 因此不涉及运行效果、检索质量与性能的任何描述。 该项目主模块处于 beta 阶段、其余模块版本号仍为 0.1.0,参数与接口随版本变动,请以仓库最新内容为准。 该项目会采集并存储团队的对话、文档与代码,属于敏感数据,是否使用请结合自身合规要求评估。 许可条款请以官方 LICENSE 原文为准,本文不构成法律意见。 安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。