agentmemory on NAS 完整部署文档(Tailscale + DeepSeek 压缩 + 局域网 viewer)

agentmemory on NAS 完整部署文档(Tailscale + DeepSeek 压缩 + 局域网 viewer) 已对照rohitg00/agentmemory源码核对(npm 最新0.9.26,引擎锁定iii v0.11.2,Apache-2.0)。架构:NAS 跑一个全功能 agentmemory 服务器(数据在/data卷)。API(3111):经 Tailscale sidecar 接入 tailnet → 多设备/远程访问,不暴露局域网/公网。viewer(3113):发布到 NAS 局域网 → 同一内网用浏览器直接打开。压缩 LLM:走 OpenAI 兼容通道接 DeepSeekdeepseek-v4-flash。每台开发机只装 Claude Code 插件 轻量 MCP shim,经 tailnet 指向 NAS,共享同一份记忆。⚠️安全须知:viewer(3113)是免密特权界面(它代理请求时自动附带你的AGENTMEMORY_SECRET)。绑到局域网意味着同一内网任何设备都能全权读写你的记忆。家庭内网可接受;公共/办公网请改用 SSH 隧道(见附录 B)。下面是整体架构图帮你快速理解各组件之间的关系云端NAS 局域网Tailscale TailnetNAS群晖/任意 Linuxhttp://NAS_LAN_IP:3113OpenAI 兼容agentmemory 服务器API(3111) viewer(3113)Tailscale sidecarts-agentmemory/data 卷记忆持久化开发机 AClaude Code MCP shim开发机 BClaude Code MCP shim浏览器访问 viewer(3113)DeepSeek APIdeepseek-v4-flash0. 前置准备# 在 NAS 上(SSH;需 Docker / Container Manager / Portainer 能跑 compose)cd/volume1/docker# 群晖示例,换成你的路径gitclone--depth1https://github.com/rohitg00/agentmemory.gitTailscale auth key:登录 https://login.tailscale.com/admin/settings/keys → Auth keys →Generate auth key,设置:Reusable:开(容器重建可再次认证)Ephemeral:关(NAS 是常驻节点,别让它离线被清除)Expiration:默认 90 天即可(只在首次认证用一次)Tags:可不打生成的tskey-auth-xxxx一会儿填进.env。收尾:容器连上后,去 Tailscale 后台Machines→ 找到agentmemory节点 →Disable key expiry,否则约 180 天后节点会因 node key 过期掉线。DeepSeek API key(用于压缩):登录 https://platform.deepseek.com → API keys → 创建,得到sk-xxxx。key 必须你自己申请;别人无法提供。1.(推荐)定制 Dockerfile:开启本地向量嵌入 中文分词coolify 的 Dockerfile 默认用--omitoptional,会跳过本地向量模型,退化成纯 BM25 关键词检索;且对中文是整段切词。你写中文、要语义召回,就改一行。编辑agentmemory/deploy/coolify/Dockerfile,把那条npm install ...改成:RUN printf {name:agentmemory-deploy,version:1.0.0,private:true,overrides:{iii-sdk:%s}}\n ${III_SDK_VERSION} package.json \ npm install agentmemory/agentmemory${AGENTMEMORY_VERSION} --no-fund --no-audit \ npm install xenova/transformers node-rs/jieba tiny-segmenter --no-fund --no-audit \ ln -s /opt/agentmemory/node_modules/.bin/agentmemory /usr/local/bin/agentmemory去掉了--omitoptional,显式装了本地嵌入模型 中日韩分词器。维护提示:你改过这个文件后不要直接git pull(会被覆盖)。日常升级只改 compose 里的版本号即可(见第 6 节)。2. docker-compose.yml存成docker-compose.yml,和 clone 出来的agentmemory/目录同级。services:# Tailscale 节点:持有网络栈,agentmemory 共享它ts-agentmemory:image:tailscale/tailscale:latesthostname:agentmemory# → MagicDNS:http://agentmemory:3111environment:-TS_AUTHKEY${TS_AUTHKEY}-TS_STATE_DIR/var/lib/tailscale-TS_USERSPACEfalse# 内核模式(需 /dev/net/tun)volumes:-ts-state:/var/lib/tailscaledevices:-/dev/net/tun:/dev/net/tuncap_add:-net_adminports:-3113:3113# viewer 发布到 NAS 局域网(端口须发布在网络栈持有者上)restart:unless-stoppedagentmemory:build:context:./agentmemory/deploy/coolifydockerfile:Dockerfileargs:AGENTMEMORY_VERSION:0.9.26III_VERSION:0.11.2III_SDK_VERSION:0.11.2network_mode:service:ts-agentmemory# 与 Tailscale 容器共享网络depends_on:-ts-agentmemoryenvironment:# ---- 压缩 LLM:DeepSeek(OpenAI 兼容)-----OPENAI_API_KEY${OPENAI_API_KEY}-OPENAI_BASE_URL${OPENAI_BASE_URL}#https://api.deepseek.com-OPENAI_MODEL${OPENAI_MODEL}#deepseek-v4-flash# ---- viewer 局域网访问 -----AGENTMEMORY_VIEWER_HOST0.0.0.0-VIEWER_ALLOWED_HOSTS${NAS_LAN_IP}:3113-VIEWER_ALLOWED_ORIGINShttp://${NAS_LAN_IP}:3113volumes:-agentmemory-data:/datarestart:unless-stoppedvolumes:ts-state:agentmemory-data:.env(同目录,务必加入.gitignore):TS_AUTHKEYtskey-auth-xxxxxxxx OPENAI_BASE_URLsk-xxxxxxxx OPENAI_API_KEYhttps://api.deepseek.com OPENAI_MODELdeepseek-v4-flash NAS_LAN_IP192.168.1.50 # 换成你 NAS 的局域网 IP端口说明:API(3111)、stream(3112)被 entrypoint 绑到0.0.0.0,通过 Tailscale 节点在 tailnet 上可达,不发布到局域网;viewer(3113)默认绑 loopback,这里用AGENTMEMORY_VIEWER_HOST0.0.0.0改绑 在ts-agentmemory上ports: 3113:3113发布到局域网。下面是容器网络与服务依赖关系图环境变量docker-compose.yml 服务栈共享网络栈ts-agentmemoryTailscale sidecar网络栈持有者agentmemory主服务network_mode: service:ts-agentmemoryts-state 卷agentmemory-data 卷TS_AUTHKEYDEEPSEEK_API_KEYNAS_LAN_IP3. 启动 取密钥dockercompose up-d--build# 首次启动入口会生成一次性密钥,只打印一次,记下来:dockercompose logs agentmemory|grepAGENTMEMORY_SECRET# 形如 AGENTMEMORY_SECRET64位hex(持久化在 /data/.hmac)验证:# API(任意 tailnet 设备)curlhttp://agentmemory:3111/agentmemory/health# viewer(任意局域网设备浏览器)# http://192.168.1.50:3113下面是首次启动的完整流程DeepSeekTailscaleagentmemoryts-agentmemorydocker compose管理员DeepSeekTailscaleagentmemoryts-agentmemorydocker compose管理员密钥持久化到 /data/.hmacdocker compose up -d --build启动 Tailscale sidecar使用 TS_AUTHKEY 认证加入 tailnet节点: agentmemory构建并启动 agentmemory连接 DeepSeek API验证连接成功生成 AGENTMEMORY_SECRETdocker compose logs agentmemory | grep SECRETAGENTMEMORY_SECRET64位hexcurl http://agentmemory:3111/agentmemory/health{status:ok}4. 客户端 Tailscale Claude Code 接入每台开发机(Mac / Windows / Linux):# 1) 装并登录 Tailscale,加入同一 tailnet# https://tailscale.com/download → tailscale up# 2) 装 Claude Code 插件(注册 hooks skills 自动接 MCP)# 在 Claude Code 里:# /plugin marketplace add rohitg00/agentmemory# /plugin install agentmemory# 3) 设两个环境变量(写进 ~/.zshrc / ~/.bashrc;Windows 用系统环境变量)exportAGENTMEMORY_URLhttp://agentmemory:3111# MagicDNS;或 http://100.x.x.x:3111exportAGENTMEMORY_SECRET第3节日志里的密钥# 4) 重启 Claude Code,验证连通 鉴权curl-HAuthorization: Bearer$AGENTMEMORY_SECREThttp://agentmemory:3111/agentmemory/healthhooks 和 MCP shim 都读这两个变量:AGENTMEMORY_URL决定连哪、AGENTMEMORY_SECRET以Bearer发送。两台机器配好即共享同一份记忆。日常正常写代码,hooks 自动捕获;需要时用/recall、/remember、/handoff等 skill。5. 压缩 LLM(DeepSeek)说明与验证agentmemory 的 provider 检测:只要OPENAI_API_KEY有真实值,就走provider: openai,model取OPENAI_MODEL、baseURL取OPENAI_BASE_URL。这条通道官方注释支持“OpenAI, DeepSeek, SiliconFlow, Azure, vLLM, LM Studio”。所以接 DeepSeek 就是把这三个变量指过去(已在第 2 节配好)。deepseek-v4-flash是 cost-optimized 档,适合做后台高频压缩(源码里专门有针对贵模型的成本告警)。base URL 用https://api.deepseek.com(OpenAI SDK 习惯的https://api.deepseek.com/v1也行)。验证:# 变量是否真进了容器dockercomposeexecagentmemoryprintenv|grep-EOPENAI_|VIEWER_|TS_# provider 是 openai 还是 noopdockercomposeexecagentmemory agentmemory doctor若日志里仍出现 “No LLM provider key found … using no-op provider”,说明 key 没被读到——检查.env的DEEPSEEK_API_KEY和 compose 的environment引用。6. 升级三块各自独立,最常做的是 agentmemory 本身。6.1 升级 agentmemory改版本号 重建cd/volume1/docker# 1) 先备份(数据唯一不可替代)curl-s-HAuthorization: Bearer$AGENTMEMORY_SECRET\http://agentmemory:3111/agentmemory/exportbackup-$(date%F).json# 并对 agentmemory-data 卷做 NAS 快照# 2) 查新版 看 release 是否要求改引擎npmview agentmemory/agentmemory version# 3) 改 docker-compose.yml 的 args.AGENTMEMORY_VERSION# 4) 重建dockercompose build agentmemorydockercompose up-ddockercompose logs--tail50agentmemory# 确认无 EPIPE/报错6.2 铁律:III_VERSION别乱升保持0.11.2。升到 0.11.6 会出现 EPIPE 重连循环、保存后搜不到。只有当 agentmemory 某新版 release notes明确支持新引擎时,才按它给的版本同步改。6.3 回滚把AGENTMEMORY_VERSION改回旧值重建即可,数据卷不动。若新版动过状态库结构,回滚旧二进制可能读不了已迁移数据——这时用第 6.1 步那份 JSON 导出import重建。6.4 Tailscale 边车 / 客户端dockercompose pull ts-agentmemorydockercompose up-d# 边车客户端插件在 Claude Code 里重装/更新;尽量让服务端与客户端小版本相近。你的AGENTMEMORY_SECRET存在/data/.hmac,升级/重建不变,客户端无需重配。7. 把本地已有记忆迁到 NASimport接口要求{ exportData: export内容, strategy: merge|replace|skip }。# (本地)先起本地 server:agentmemory 或 npx agentmemory/agentmemorycurl-shttp://127.0.0.1:3111/agentmemory/exportexport.json# 语料大、超时就分页:?maxSessions10offset0 逐批拉# 包一层jq{exportData: ., strategy: merge}export.jsonimport.json# 推到 NAScurl-XPOST http://agentmemory:3111/agentmemory/import\-HAuthorization: Bearer$AGENTMEMORY_SECRET\-HContent-Type: application/json--dataimport.jsonmerge合并 /replace覆盖 /skip只补新。首次迁移用merge。裸拷贝~/.agentmemory的 SQLite 为备选,要求两端版本一致且停服时操作,优先用 export/import。8. 备份 / 维护 / 排错备份:记忆在agentmemory-data卷(/data/state_store.db),纳入 NAS 快照;或定期export出 JSON。密钥轮换:删/data/.hmac后重启会重新生成并打印。只看到 7 个 MCP 工具:shim 没连上 server——查AGENTMEMORY_URL可达、health 通。存了搜不到 / EPIPE:多半 iii 引擎版本不符,保持III_VERSION0.11.2。viewer 打不开:确认AGENTMEMORY_VIEWER_HOST0.0.0.0且VIEWER_ALLOWED_HOSTS里的host:port与你浏览器地址栏完全一致(含端口);改了要docker compose up -d重建容器生效。provider 显示 noop:DeepSeek key 没传进容器,见第 5 节。附录 AOption — 不用 sidecar,改 NAS 原生 Tailscale若 NAS 容器拿不到/dev/net/tun:套件中心装 Tailscale(NAS 得到100.x.x.x),compose 去掉 sidecar,agentmemory 直接发布端口:ports: [100.x.x.x:3111:3111, 192.168.1.50:3113:3113](API 走 tailnet IP、viewer 走局域网 IP)。客户端AGENTMEMORY_URLhttp://100.x.x.x:3111。附录 Bviewer 的三档访问方式按安全性从高到低共同前提:viewer 是免密特权界面(代理时自动带AGENTMEMORY_SECRET)。能打开它 全权读写记忆,无需令牌。按你的暴露面选最小的一档。三档可按需共存(白名单逗号分隔),但暴露越广风险越大。B1 — SSH 隧道最安全,viewer 不出现在任何网络把第 2 节ts-agentmemory的ports: [3113:3113]改成[127.0.0.1:3113:3113](只绑 NAS 本机回环),并设:agentmemory:environment:-AGENTMEMORY_VIEWER_HOST0.0.0.0# 端口转发到容器内 loopback 收不到,必须 0.0.0.0-VIEWER_ALLOWED_HOSTSlocalhost:3113,127.0.0.1:3113-VIEWER_ALLOWED_ORIGINShttp://localhost:3113,http://127.0.0.1:3113然后ssh -L 3113:127.0.0.1:3113 用户NAS,浏览器开http://localhost:3113。只有能 SSH 进 NAS 的人能用。B2 — 局域网主文档默认,家庭内网用见第 2 节:ports: [3113:3113]VIEWER_ALLOWED_HOSTS${NAS_LAN_IP}:3113。同一局域网设备开http://NAS局域网IP:3113。B3 — 全域 / tailnet你的任意 Tailscale 设备、任意地点可访问“全域” 你 tailnet 内任意设备、任意网络位置可达;不是公网。viewer 已绑0.0.0.0、与 Tailscale 边车共享网络栈,所以它已在 tailscale 接口监听——只需把 tailnet 主机加进白名单,无需再发布任何端口:agentmemory:environment:-AGENTMEMORY_VIEWER_HOST0.0.0.0# 可与局域网并存,逗号分隔;host:port 必须与地址栏完全一致-VIEWER_ALLOWED_HOSTS${NAS_LAN_IP}:3113,agentmemory:3113,${NAS_TS_IP}:3113-VIEWER_ALLOWED_ORIGINShttp://${NAS_LAN_IP}:3113,http://agentmemory:3113,http://${NAS_TS_IP}:3113.env补一行NAS_TS_IP100.x.x.x(NAS 的 Tailscale IP)。docker compose up -d生效。任意 tailnet 设备开http://agentmemory:3113(MagicDNS)或http://100.x.x.x:3113。单人 tailnet到此即可。若你的 tailnet 有别人,务必在 Tailscale 后台 Access controls 用 ACL把 viewer 端口锁到只有你自己:给 NAS 节点打 tag(如tag:agentmemory),并仅放行你这个用户访问该端口——{ tagOwners: { tag:agentmemory: [autogroup:owner] }, acls: [ // 你自己的设备:全放行 { action: accept, src: [autogroup:owner], dst: [*:*] } // 不要给其他用户/tag 添加指向 tag:agentmemory:3113 的规则,默认即拒绝 ] }打 tag 需让TS_AUTHKEY带--advertise-tagstag:agentmemory,或在后台给该节点手动加 tag。不推荐 — 公网直曝viewer 无登录,真要从公网开必须在前面套一层带认证的反向代理(basic auth / OAuth)。鉴于其特权性质,强烈建议改用 B3 的 tailnet 全域访问,而不是把它挂到公网。附录 CHeadscale连协调层都自托管NAS 的ts-agentmemory与各客户端tailscale up都加--login-serverhttps://你的headscale;auth key 由headscale preauthkeys create签发。数据平面行为不变。