Mem0 自托管服务器实战指南:FastAPI + pgvector + Dashboard 的本地部署、安全加固与 Postgres 镜像迁移
2026/9/7 4:48:40 网站建设 项目流程

Mem0 自托管服务器实战指南:FastAPI + pgvector + Dashboard 的本地部署、安全加固与 Postgres 镜像迁移

【免费下载链接】embedchainThe Memory Layer for AI Agents - Drop-in memory infrastructure for AI agents and apps. Context that persists. Built for production.项目地址: https://gitcode.com/GitHub_Trending/em/embedchain

Mem0(原 embedchain 项目演进而来)除了 Python SDK 之外,还内置了一个可自托管的 FastAPI REST 服务端与本地 Web 仪表盘。本文基于仓库中的 server/README.md,结合服务端源码、Docker 编排与运维脚本,完整讲解:如何用一条命令拉起整套记忆服务、如何理解其"安全默认"设计、如何管理请求日志与遥测,以及如何将 Postgres 镜像从已归档的ankane/pgvector平滑迁移到官方pgvector/pgvector:pg17。读完本文,你可以独立完成 Mem0 记忆服务的本地部署、日常运维与跨大版本升级。

一、服务端架构总览:三个容器组成的最小记忆栈

从 server/docker-compose.yaml 可以看到,自托管栈由三个服务构成,通过mem0_networkbridge 网络互通:

服务镜像/构建端口映射职责
mem0基于 server/dev.Dockerfile 构建8888:8000FastAPI REST API,挂载源码并--reload热更新
postgrespgvector/pgvector:pg178432:5432向量存储(memories)+ 应用库(用户、API Key、请求日志)
mem0-dashboard基于 server/dashboard/ 构建的 Next.js 应用3000:3000Web 仪表盘,走/api/health健康检查

几个值得注意的编排细节:

  • Postgres 凭据强制注入POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}(server/docker-compose.yaml),:?语法意味着.env中未设置该变量时 compose 直接拒绝启动——这正是 README 中"POSTGRES_PASSWORD 现为必填项"的实现来源。
  • 双数据库分工:server/init-db.sh 在 Postgres 首次初始化时额外创建mem0_app库,存放用户、API Key、请求日志等应用数据;默认的postgres库则供 pgvector 存放记忆向量。
  • 启动时序mem0服务depends_onPostgres 的service_healthy,其启动命令先执行alembic upgrade head再拉起uvicorn main:app,即 API 容器启动时会自动跑数据库迁移。

二、快速启动

2.1 前置准备:配置.env

复制示例环境文件并至少填写 Postgres 密码与一个 LLM 提供商的 Key:

cd server cp .env.example .env # Edit .env — at minimum set POSTGRES_PASSWORD and OPENAI_API_KEY

server/.env.example 中各变量的完整含义如下:

变量默认值说明
OPENAI_API_KEY默认 LLM/Embedder 提供商的 Key;也可改用ANTHROPIC_API_KEY/GOOGLE_API_KEY
POSTGRES_HOST/POSTGRES_PORT/POSTGRES_DB/POSTGRES_USERpostgres/5432/postgres/postgres向量库连接参数
POSTGRES_PASSWORD必填未设置时 docker compose 拒绝启动
POSTGRES_COLLECTION_NAMEmemoriespgvector 集合(表)名
ADMIN_API_KEY遗留的直连管理密钥,建议长度 ≥ 16 位
JWT_SECRET认证启用时的 JWT 签名密钥,可用openssl rand -base64 48生成
AUTH_DISABLEDfalse仅本地开发可设为true,生产环境禁用
DASHBOARD_URLhttp://localhost:3000CORS 白名单来源
APP_DB_NAMEmem0_app应用数据库名
MEM0_DEFAULT_LLM_MODELgpt-5-mini默认 LLM 模型,可覆盖以固定版本
MEM0_DEFAULT_EMBEDDER_MODELtext-embedding-3-small默认 Embedder 模型
MEM0_TELEMETRYtrue匿名遥测开关,设为false退出
REQUEST_LOG_RETENTION_DAYS30请求日志保留天数

默认运行时配置由 server/main.py 中的DEFAULT_CONFIG组装:向量存储固定为pgvector,LLM 与 Embedder 默认走 OpenAI(gpt-5-mini+text-embedding-3-small)。此外 server/main.py 定义了镜像内置的提供商白名单BUNDLED_LLM_PROVIDERS = ("openai", "anthropic", "gemini")BUNDLED_EMBEDDER_PROVIDERS = ("openai", "gemini")——通过POST /configure切换到未打包的提供商会直接返回 400,源码中的错误提示明确给出了扩展方式(安装对应 Python 包、重建容器并扩展白名单)。

2.2 Agent-first:一条命令完成全部初始化

cd server make bootstrap

server/Makefile 中bootstrap: up wait-api wait-dashboard seed,即依次完成四步:

  1. up:先检查 3000/8888 端口未被占用(避免与已有服务冲突),再docker compose up -d --build
  2. wait-api:轮询GET /auth/setup-status直到 API 就绪(每 2 秒一次);
  3. wait-dashboard:轮询GET /api/health直到仪表盘就绪;
  4. seed:执行 server/scripts/seed.sh 完成账号与 Key 初始化。

seed 脚本的完整调用链值得展开(见 server/scripts/seed.sh):

  1. GET /auth/setup-status判断是否已有管理员;
  2. 若无,调POST /auth/register创建首个 admin(密码未指定时用secrets.token_urlsafe(16)随机生成);
  3. POST /auth/login换取 JWT access token;
  4. 携带 Bearer token 调POST /api-keys创建标签为dev-seed-key的 API Key;
  5. === Ready ===块中一次性打印 Email、Password、API Key。

凭据只打印一次:关闭终端前务必保存密码与 API Key——API Key 在数据库里只保存 bcrypt 哈希(见 server/auth.py 的generate_api_key),无法事后找回。

可覆盖生成的凭据:

cd server make bootstrap EMAIL=admin@company.com PASSWORD='strong-password' NAME='Admin'

面向机器解析的场景(如 CI、Agent 自动化)可用 JSON 输出:

cd server OUTPUT=json make seed

此时 server/scripts/seed.sh 只输出一行 JSON,包含dashboard_urlapi_urlemailpasswordapi_key五个字段,方便直接jq解析。

注意make bootstrap跳过设置向导,因此"使用场景 → 自定义指令"步骤不会执行。若之后想补充自定义指令,直接POST /configure提交{"custom_instructions": "..."}即可(/configure端点定义见 server/main.py,读取配置时敏感字段会自动脱敏为[redacted])。

2.3 Browser-first:走浏览器设置向导

cd server make up

然后打开http://localhost:3000,按向导完成管理员注册与使用场景配置。相比 Agent-first 流程,向导会多触发一个遥测事件(见第五节),并且向导最后一步可让 LLM 基于你填写的use_case自动生成custom_instructions与一条测试消息——对应 API 侧的POST /generate-instructions(server/main.py)。

2.4 拆除与清理

# Stop the stack cd server && make down # Wipe all data (including the Postgres volume) cd server && make clean

make clean等价于docker compose down -v,会永久删除postgres_db卷,包含全部记忆与应用数据,执行前确认无需保留。

三、安全默认:认证、API Key 与响应头

README 的 "Security Defaults" 一节列出四条规则,均可在源码中得到印证:

  1. 仪表盘登录使用 JWT。server/auth.py 中:算法为 HS256,access token 有效期 30 分钟,refresh token 有效期 30 天。refresh token 采用 jti 表 + 条件 UPDATE 原子消费(server/auth.py),关闭了"读取-检查-写入"竞态,同一 token 并发重放最多只有一个成功。
  2. 程序化访问使用X-API-Key。Key 由secrets.token_urlsafe(32)生成并加m0sk_前缀;数据库api_keys表(server/models.py)只存前 12 位前缀与 bcrypt 哈希,泄露数据库也无法还原 Key 原文。
  3. 认证默认启用。若既无管理员也无ADMIN_API_KEY,server/main.py 启动时会打印醒目警告块,列出三种修复途径(设置ADMIN_API_KEY、到http://<host>:3000/setup注册管理员、仅限本地开发时设AUTH_DISABLED=true)。
  4. AUTH_DISABLED=true仅限本地开发。该值通过 compose 的${AUTH_DISABLED:-false}透传,生产环境应保持 false。

此外,所有受保护请求都会经过请求日志中间件,且响应附带X-Request-ID便于排障(server/main.py)。

仪表盘安全响应头

server/dashboard/next.config.mjs 对所有路径统一设置:

  • X-Frame-Options: DENY
  • Content-Security-Policy: frame-ancestors 'none'
  • X-Content-Type-Options: nosniff
  • Referrer-Policy: strict-origin-when-cross-origin

前两者双重阻止 iframe 嵌入(防点击劫持),nosniff防止浏览器嗅探错误标注的 MIME 类型,Referrer-Policy限制跨域 Referer 泄露。如需更强防护(如 HSTS、CSP nonce),README 建议在自己的反向代理层追加。

忘记密码的官方恢复路径

在栈运行期间从宿主机重置管理员密码:

cd server make reset-admin-password EMAIL=admin@example.com PASSWORD='new-strong-password'

该 target 通过docker compose execmem0容器内执行 server/scripts/reset_admin_password.py(见 server/Makefile)。README 的解释是:任何能拿到宿主 shell 的人本就对数据库和密钥拥有完全访问权,因此这条命令并不扩大攻击面——它是支持的恢复路径,而非绕过机制。

四、仪表盘功能

登录后,仪表盘(Next.js 应用,源码位于 server/dashboard/src/)提供六类能力:

  • Requests— API 调用的实时审计日志(method、path、status、latency),数据即request_logs表(server/models.py);
  • Memories— 浏览记忆,按 user ID 过滤;
  • Entities— 列出所有持有记忆的user_idagent_idrun_id及其数量;删除实体即级联删除其记忆;
  • API Keys— 创建、打标签、吊销每个用户的 Key;
  • Configuration— 运行时覆盖 LLM 与 Embedder 配置;变更持久化到应用库(settings表),重启后重新生效,并分层叠加在.env值之上(对应 API 的GET/POST /configureGET /configure/providers);
  • Settings— 账号资料与密码管理。

API 侧能力与之对应:server/main.py 暴露了POST /memoriesGET /memories(不带标识符时全量列出,需 admin 角色,上限 1000 条)、GET /memories/{id}POST /searchPUT /memories/{id}GET /memories/{id}/historyDELETE /memories/{id}DELETE /memoriesPOST /reset等端点,OpenAPI 文档位于http://localhost:8888/docs

五、请求日志保留策略

request_logs表只增不删,会随流量增长(README 给出的量级参考:10 req/s 下约 86.4 万行/天),需要周期性清理:

cd server make prune-logs # defaults to 30 days make prune-logs REQUEST_LOG_RETENTION_DAYS=7 # shorter window

其背后的实现分两部分:

  1. 写入侧:server/main.py 的log_requests中间件记录每个请求的 method、path、status、latency 与 auth_type,并在finally中通过run_in_executor异步落库;OPTIONS预检请求、/api/health/docs/redoc/openapi.json以及/requests前缀路径被排除(server/main.py),避免审计接口本身制造噪声。
  2. 删除侧:server/scripts/prune_request_logs.py 读取REQUEST_LOG_RETENTION_DAYS(默认 30,必须 ≥ 1 的整数),按 UTC 时间截断执行DELETE ... WHERE created_at < cutoff。README 建议生产环境将其接入 cron 或 systemd timer。

为什么大表上这个删除依然便宜?因为created_at列上建了BRIN 索引——迁移文件 server/alembic/versions/006_request_logs_brin.py 将其从 btree 换成了CREATE INDEX ... USING BRIN (created_at)。对按时间天然有序追加的日志表,BRIN 以极小的索引体积让范围删除快速定位块范围,这正是 README 中"range deletes stay cheap even on large tables"的依据。

六、遥测:默认开启、最多两个事件、可一键退出

遥测实现见 server/telemetry.py,与 Mem0 OSS 库一致默认开启,指向同一个匿名 PostHog 项目,每个安装最多发送两个事件:

事件触发时机属性
admin_registered首个管理员被创建(向导或 API 直连均可)邮箱域名、服务端版本、安装 UUID
onboarding_completed设置向导到达最终成功态同上,外加操作者填写的自由文本use_case

几个可验证的实现细节:

  • 纯 API 引导(make bootstrap)永远不会发出onboarding_completed,因为向导成功态不存在;
  • 每个事件通过状态文件(默认/app/history/telemetry.json)保证"至多一次"(_capture_once中的幂等键,见 server/telemetry.py);
  • distinct_id是随机生成的安装 UUID,属性里只有邮箱域名(非完整邮箱),不含 PII;
  • 退出方式:在.env中设MEM0_TELEMETRY=false(compose 中经${MEM0_TELEMETRY:-true}透传,server/telemetry.py 解析)。

七、从ankane/pgvector迁移到pgvector/pgvector

ankane/pgvector镜像已归档停止维护,当前版本换成官方pgvector/pgvector:pg17(PostgreSQL 17、pgvector 0.8.0)。变更对照:

BeforeAfter
Docker 镜像ankane/pgvector:v0.5.1pgvector/pgvector:pg17
PostgreSQL 版本1517
pgvector 版本0.5.10.8.0
凭据硬编码postgres/postgresPOSTGRES_USER/POSTGRES_PASSWORD环境变量驱动

7.1 全新安装(无存量数据)

无需迁移:复制.env.example.env,设置POSTGRES_PASSWORD,然后make up

7.2 存量安装(保留数据)

PostgreSQL 17 无法直接读取 15 写下的数据文件,必须"先导出、再导入"。

第 1 步:在旧栈运行时导出数据

cd server # Dump all databases (mem0 memories + mem0_app auth/config data) docker compose exec -T postgres pg_dumpall -U postgres > mem0_backup.sql ls -lh mem0_backup.sql # 确认 dump 文件非空

第 2 步:停旧栈并删除旧卷

docker compose down docker compose down -v # 删除 postgres_db 卷——务必先确认备份可用!

第 3 步:更新.env

凭据不再硬编码于docker-compose.yaml,需显式写入:

POSTGRES_HOST=postgres POSTGRES_PORT=5432 POSTGRES_DB=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=<your-password> # required — compose will refuse to start without it POSTGRES_COLLECTION_NAME=memories

若此前依赖硬编码的postgres/postgres,设POSTGRES_PASSWORD=postgres保持凭据一致。

第 4 步:只启动 Postgres

docker compose up -d postgres docker compose exec -T postgres pg_isready -q && echo "ready" || echo "not ready"

必须只先起 Postgres、不起 mem0 API:API 启动即执行alembic upgrade head,会创建空表而与恢复冲突。

第 5 步:恢复数据

docker compose exec -T postgres psql -U postgres < mem0_backup.sql

role "postgres" already exists之类的提示无害。

关键点:恢复必须先于启动 mem0 API 容器。API 启动时的迁移会建空表——之后再恢复会因重复键失败,并丢失 API Key 与设置。

第 6 步:启动 API

docker compose up -d mem0

Alembic 检测到既有表后只增量应用新迁移。

第 7 步:验证

make health curl -s "http://localhost:8888/memories?user_id=<your-user-id>" -H "X-API-Key: <your-api-key>"

make health会分别检查 API/docs的 HTTP 状态、仪表盘/api/healthpg_isready(见 server/Makefile)。

7.3 回滚

如需回退,将 server/docker-compose.yaml 中的镜像改回ankane/pgvector:v0.5.1,执行docker compose down -vdocker compose up -d --build,再把mem0_backup.sql以同样方式灌入旧容器即可。

八、本地端口速查与继续深入

入口地址
仪表盘http://localhost:3000
APIhttp://localhost:8888
OpenAPI 文档http://localhost:8888/docs

常用命令回顾:make up(启动并等待就绪)、make down/make clean(停止 / 停止并删卷)、make logsdocker compose logs -f)、make health(三件套体检)、make bootstrap(Agent-first 一键初始化)、make reset-admin-passwordmake prune-logs

如需进一步阅读实现:REST 端点与默认配置在 server/main.py,认证与 Key 生成在 server/auth.py,路由层在 server/routers/,数据库模型在 server/models.py,应用库迁移在 server/alembic/versions/,仪表盘前端在 server/dashboard/src/,服务端行为有对应测试覆盖(如 tests/test_server_auth.py、tests/test_api_keys_router.py、tests/test_server_params.py)。

【免费下载链接】embedchainThe Memory Layer for AI Agents - Drop-in memory infrastructure for AI agents and apps. Context that persists. Built for production.项目地址: https://gitcode.com/GitHub_Trending/em/embedchain

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询