部署Mem0项目流程详细记录
-
- [1. 规划服务器](#1. 规划服务器)
- [2. 更新 Ubuntu 基础环境](#2. 更新 Ubuntu 基础环境)
- [3. 安装 Docker Engine 与 Docker Compose](#3. 安装 Docker Engine 与 Docker Compose)
- [4. 下载 Mem0 源码](#4. 下载 Mem0 源码)
- [5. 创建并保护配置文件](#5. 创建并保护配置文件)
- [6. 第一次启动:先在服务器本机验证](#6. 第一次启动:先在服务器本机验证)
- [7. 最小功能测试](#7. 最小功能测试)
- [8. 访问方式:选择其一](#8. 访问方式:选择其一)
-
- [方案 A:只在服务器本机或内网使用](#方案 A:只在服务器本机或内网使用)
- [方案 B:正式公网部署,推荐](#方案 B:正式公网部署,推荐)
- [9. 日常运维命令](#9. 日常运维命令)
- [10. 备份与日志清理](#10. 备份与日志清理)
- 11、相关自定义配置
- [Docker 网络注意事项](#Docker 网络注意事项)
项目地址:
python
https://github.com/mem0ai/mem0

可以。下面是一套适合 Ubuntu 22.04/24.04 小白的部署路线:先在服务器上跑通,再按是否公网访问做安全收口。
先说明一个关键点:仓库当前的 server/docker-compose.yaml 是开发型 配置,含热重载、源码挂载,并把 PostgreSQL 映射到宿主机 8432。它适合先跑通和内网测试;若要公开给互联网使用,应在第二阶段改为仅反向代理暴露 HTTPS,绝不公开 PostgreSQL。
官方自托管组件包括:
- Dashboard:
3000 - API:
8888 - PostgreSQL + pgvector:容器内
5432(当前开发配置映射到宿主机8432) - Neo4j 不在当前 Compose 配置中
Mem0 的 API 默认需要认证;不要在公网环境设置 AUTH_DISABLED=true。
1. 规划服务器
建议起步配置:
- Ubuntu 22.04 或 24.04 LTS
- 2 核 CPU、4 GB 内存、40 GB 磁盘起步
- 一个普通 Linux 用户,并具备
sudo权限 - 若要公网访问:域名,例如
mem0.example.com和api.mem0.example.com - 一个 LLM/Embedding 服务的 API Key。默认配置使用 OpenAI 的
gpt-5-mini与text-embedding-3-small
部署目录建议使用:
bash
/opt/mem0/mem0
不要把密钥写进 Git、截图、聊天记录,或提交 .env 文件。
2. 更新 Ubuntu 基础环境
通过 SSH 登录服务器后执行:
bash
sudo apt update
sudo apt upgrade -y
sudo apt install -y ca-certificates curl git make openssl
若系统提示内核已更新,执行:
bash
sudo reboot
重连服务器后继续。
3. 安装 Docker Engine 与 Docker Compose
使用 Docker 官方 APT 仓库:
bash
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
bash
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
bash
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
验证 Docker:
bash
sudo docker run hello-world
docker compose version
可选:让当前用户不用每次输入 sudo:
bash
sudo usermod -aG docker "$USER"
newgrp docker
docker run hello-world
注意:加入 docker 组等同于获得较高系统权限,只应给可信账号。Docker 官方安装与权限说明见 Docker Ubuntu 安装文档 和 Linux post-install 文档。
4. 下载 Mem0 源码
bash
sudo mkdir -p /opt/mem0
sudo chown -R "$USER":"$USER" /opt/mem0
git clone https://github.com/mem0ai/mem0.git /opt/mem0/mem0
cd /opt/mem0/mem0/server
确认当前位置:
bash
pwd
git rev-parse --short HEAD
应位于:
text
/opt/mem0/mem0/server
5. 创建并保护配置文件
创建 .env:
bash
umask 077
cp .env.example .env
chmod 600 .env
nano .env
该项目默认支持的文本生成模型与嵌入模型是OpneAI官方的模型,如下所示:
至少填写以下项目:
dotenv
OPENAI_API_KEY=你的模型服务密钥
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=请填一个强随机密码
POSTGRES_COLLECTION_NAME=memories
JWT_SECRET=请填一个强随机密钥
ADMIN_API_KEY=
AUTH_DISABLED=false
MEM0_DEFAULT_LLM_MODEL=gpt-5-mini
MEM0_DEFAULT_EMBEDDER_MODEL=text-embedding-3-small
MEM0_TELEMETRY=false
REQUEST_LOG_RETENTION_DAYS=30
在另一个终端生成两个随机值,复制到 .env:
bash
openssl rand -hex 32
openssl rand -hex 48
分别用作:
POSTGRES_PASSWORDJWT_SECRET
ADMIN_API_KEY 可以先留空;首次通过 Dashboard 向导创建管理员后,为实际应用生成独立 API Key。不要把 API Key 硬编码到业务代码,使用环境变量或密钥管理服务。
6. 第一次启动:先在服务器本机验证
仍在 /opt/mem0/mem0/server 目录:
bash
docker compose up -d --build
首次构建要下载 Python、Node、PostgreSQL 镜像,可能需要数分钟。查看状态:
bash
docker compose ps
查看日志:
bash
docker compose logs -f mem0
另开一个终端验证 API:
bash
curl http://127.0.0.1:8888/auth/setup-status
健康检查:
bash
curl -I http://127.0.0.1:8888/docs
curl -I http://127.0.0.1:3000/api/health
在服务器有图形界面时,可打开:
text
http://服务器IP:3000
首次访问会进入初始化向导:
- 创建管理员账号;
- 检查当前模型与嵌入模型配置;
- 创建第一把
m0sk_...API Key; - 立刻保存 API Key------完整值只显示一次;
- 完成向导。
API 文档地址:
text
http://服务器IP:8888/docs
自托管 API 没有 /v1 前缀,例如实际写入接口是 POST /memories。
7. 最小功能测试
在 Dashboard 创建 API Key 后,在服务器执行:
bash
curl -X POST http://127.0.0.1:8888/memories \
-H "Content-Type: application/json" \
-H "X-API-Key: m0sk_替换为你的密钥" \
-d '{
"messages": [{"role": "user", "content": "我喜欢喝咖啡。"}],
"user_id": "test-user"
}'
再查询:
bash
curl "http://127.0.0.1:8888/memories?user_id=test-user" \
-H "X-API-Key: m0sk_替换为你的密钥"

如果写入失败且日志出现 502 Upstream provider error,优先检查 .env 中的 OPENAI_API_KEY、模型名称及服务器是否能访问对应模型服务。
8. 访问方式:选择其一
方案 A:只在服务器本机或内网使用
适合测试、家庭/公司内网。
需要把 Compose 文件中的地址改为服务器实际 IP,避免浏览器错误地访问自己电脑的 localhost。
在 server/docker-compose.yaml 中,将:
yaml
- DASHBOARD_URL=http://localhost:3000
改为:
yaml
- DASHBOARD_URL=${DASHBOARD_URL}
将:
yaml
- NEXT_PUBLIC_API_URL=http://localhost:8888
改为:
yaml
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
然后在 .env 增加,例如服务器内网 IP 是 192.168.1.50:
dotenv
DASHBOARD_URL=http://192.168.1.50:3000
NEXT_PUBLIC_API_URL=http://192.168.1.50:8888
重新创建容器:
bash
docker compose up -d --build --force-recreate
此时从内网电脑访问:
text
http://192.168.1.50:3000
方案 B:正式公网部署,推荐
建议使用两个子域名:
text
https://mem0.example.com Dashboard
https://api.mem0.example.com API
架构如下:
text
浏览器 / 业务系统
│ HTTPS :443
▼
Nginx
├── mem0.example.com → 127.0.0.1:3000
└── api.mem0.example.com → 127.0.0.1:8888
│
▼
Docker 内部 PostgreSQL
正式部署必须做到:
- 只开放
22、80、443; - API 与 Dashboard 仅绑定到
127.0.0.1; - PostgreSQL 不映射宿主机端口;
AUTH_DISABLED=false;- 使用 HTTPS;
.env权限保持600;- 通过 Nginx 统一暴露公网服务。
这一步需要将当前开发 Compose 改成生产 Compose:去除源码挂载和 --reload,限制端口绑定,并配置域名环境变量。因为仓库当前提供的是开发 Compose,我建议不要直接把它的默认端口暴露到公网。
公网环境的 .env 应是:
dotenv
DASHBOARD_URL=https://mem0.example.com
NEXT_PUBLIC_API_URL=https://api.mem0.example.com
AUTH_DISABLED=false
Nginx 反向代理配置示例:
nginx
server {
listen 80;
server_name mem0.example.com;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
nginx
server {
listen 80;
server_name api.mem0.example.com;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
配置域名 DNS 解析到服务器公网 IP 后,可用 Certbot 申请证书。注意 Docker 映射端口可能绕开 UFW 普通规则,因此更安全的措施是从 Compose 层面把 API 和 Dashboard绑定到 127.0.0.1,数据库不发布到宿主机;Docker 官方对此有明确提醒。Docker 防火墙限制说明
9. 日常运维命令
进入目录:
bash
cd /opt/mem0/mem0/server
查看容器:
bash
docker compose ps
查看全部日志:
bash
docker compose logs -f
只看 API 日志:
bash
docker compose logs -f mem0
停止服务,但保留数据:
bash
docker compose down
启动服务:
bash
docker compose up -d
更新代码并重建:
bash
git pull
docker compose up -d --build
不要随便执行下面这个命令:
bash
docker compose down -v
它会删除 PostgreSQL 数据卷,即用户、API Key、配置和 memories。
10. 备份与日志清理
备份 PostgreSQL:
bash
cd /opt/mem0/mem0/server
docker compose exec -T postgres pg_dumpall -U postgres > "mem0-backup-$(date +%F).sql"
确认备份不是空文件:
bash
ls -lh mem0-backup-*.sql
恢复时必须先停 API,只启动 PostgreSQL,再导入备份;否则迁移表可能冲突。
请求审计日志会不断增长。项目内置清理命令:
bash
make prune-logs REQUEST_LOG_RETENTION_DAYS=30
可用 cron 每天凌晨执行:
bash
crontab -e
加入:
cron
0 3 * * * cd /opt/mem0/mem0/server && /usr/bin/make prune-logs REQUEST_LOG_RETENTION_DAYS=30 >> /var/log/mem0-prune.log 2>&1
建议同时把数据库备份复制到另一台机器或对象存储;只放在同一台服务器不算真正的容灾。
如果你告诉我部署目标是"仅本机/内网"还是"公网域名访问",以及是否已有域名,我可以下一步直接给你一套可复制的生产版 Compose、Nginx 和 HTTPS 配置。
11、相关自定义配置
该项目默认支持的文本生成模型与嵌入模型是OpneAI官方的模型,如果想配置成本地启动的自定义文本生成模型与嵌入模型,需要进行如下修改:
结论先说:
- 文本模型:
Qwen3.5-27B-FP8,服务地址应为http://<可访问主机>:9026/v1 - 嵌入模型:
bge-m3-local,服务地址应为http://<可访问主机>:9027/v1 - BGE-M3 稠密向量维度:1024
- pgvector collection 的维度也必须是:1024
- 目前代码不能完整满足"文本模型、嵌入模型、向量维度各自独立配置"的需求,需要改造,但改动集中在
server/main.py与.env.example。
BGE-M3 的官方配置确实是 1024 维,和你贴出的 hidden_size: 1024 一致。BGE-M3 模型卡
现有代码的问题
当前 main.py 的默认配置有三个限制:
- LLM 和 Embedder 共用同一个
OPENAI_API_KEY。 - 两者没有分别传入
base_url。 - pgvector 没有显式传
embedding_model_dims,默认会采用 1536。 - Embedder 没有显式传
embedding_dims,默认也会按 1536 处理。
针对该需求,需要修改对应的.env 、docker-compose.yaml等文件(改动的地方不少)
.env 配置文件如下所示:
server.env
python
# Legacy shared OpenAI-compatible credentials. Keep these only when the LLM
# and embedder use the same endpoint and API key. Prefer the independent
# MEM0_LLM_* and MEM0_EMBEDDER_* variables below for new deployments.
OPENAI_API_KEY="XXXXXXXX"
OPENAI_BASE_URL="XXXXXXXX"
# Optional: other bundled LLM/embedder providers (set the key for the one you want to use)
# ANTHROPIC_API_KEY=
# GOOGLE_API_KEY=
# Postgres --- POSTGRES_PASSWORD is required; docker-compose will not start without it.
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DB=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_COLLECTION_NAME=memories
ADMIN_API_KEY=
JWT_SECRET='61fcd701187483c046f4e020314f0ee1ea982aef227fea626e371646de30223defce62448ab0b1ae59405f3ee14b0884'
# Local development only. Leave false in production.
AUTH_DISABLED=false
DASHBOARD_URL=http://192.168.42.244:3000
NEXT_PUBLIC_API_URL=http://192.168.42.244:8888
APP_DB_NAME=mem0_app
# Independent LLM configuration. The provider must be in BUNDLED_LLM_PROVIDERS
# (see server/main.py). MEM0_DEFAULT_LLM_MODEL remains supported as a legacy fallback.
MEM0_LLM_PROVIDER=openai
MEM0_LLM_API_KEY=EMPTY
MEM0_LLM_BASE_URL=http://192.168.8.165:9026/v1
MEM0_LLM_MODEL=Qwen3.5-27B-FP8
MEM0_LLM_TEMPERATURE=0.2
# Independent embedder configuration. The provider must be in
# BUNDLED_EMBEDDER_PROVIDERS. For OpenAI-compatible embedding servers (such as
# vLLM), set the base URL to the server's /v1 endpoint.
#
# The embedder and vector store dimensions MUST match. For BAAI/bge-m3 served
# by vLLM, use bge-m3-local and 1024 for both values.
MEM0_EMBEDDER_PROVIDER=openai
MEM0_EMBEDDER_API_KEY=EMPTY
MEM0_EMBEDDER_BASE_URL=http://192.168.8.165:9027/v1
MEM0_EMBEDDER_MODEL=bge-m3-local
MEM0_EMBEDDER_DIMENSIONS=1024 # 嵌入模型的维度
MEM0_EMBEDDER_SEND_DIMENSIONS=false # 当嵌入模型未非OpenAI官方模型并且使用vllm但设为 false 后不会向 vLLM 发送 dimensions 参数
MEM0_VECTOR_STORE_DIMENSIONS=1024 # 向量库数据维度
# Legacy model names. They are used only when the corresponding MEM0_LLM_MODEL
# or MEM0_EMBEDDER_MODEL variable is empty.
MEM0_DEFAULT_LLM_MODEL=Qwen3.5-27B-FP8
MEM0_DEFAULT_EMBEDDER_MODEL=bge-m3-local
# Anonymous telemetry. Sends a single onboarding event per install
# (install UUID, email domain, server version, source). No PII.
# Set to false to opt out.
MEM0_TELEMETRY=true
# Days of request_logs history to keep when `make prune-logs` runs.
# Wire the prune command into cron/systemd in production.
REQUEST_LOG_RETENTION_DAYS=30
docker-compose.yaml配置文件
server\docker-compose.yaml
python
name: mem0-dev
services:
mem0:
build:
context: ..
dockerfile: server/dev.Dockerfile
args:
PIP_INDEX_URL: ${PIP_INDEX_URL:-https://mirrors.aliyun.com/pypi/simple}
ports:
- "8888:8000"
env_file:
- .env
networks:
- mem0_network
# Lets a container reach model servers running directly on the Linux Docker host.
# Use http://host.docker.internal:<port>/v1 in MEM0_LLM_BASE_URL or
# MEM0_EMBEDDER_BASE_URL. Remove this mapping when all services are on a
# Docker network instead.
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./history:/app/history
- .:/app
depends_on:
postgres:
condition: service_healthy
command: >
sh -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000 --reload"
environment:
- PYTHONDONTWRITEBYTECODE=1
- PYTHONUNBUFFERED=1
- PYTHONPATH=
# Browser origin allowed by the API. Override in .env for remote access.
- DASHBOARD_URL=${DASHBOARD_URL:-http://localhost:3000}
- APP_DB_NAME=mem0_app
# Also applies to the startup `pip install mem0ai` command below.
- PIP_INDEX_URL=${PIP_INDEX_URL:-https://mirrors.aliyun.com/pypi/simple}
- JWT_SECRET=${JWT_SECRET}
- AUTH_DISABLED=${AUTH_DISABLED:-false}
- MEM0_TELEMETRY=${MEM0_TELEMETRY:-true}
postgres:
image: pgvector/pgvector:pg17
restart: on-failure
shm_size: "128mb"
networks:
- mem0_network
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}
healthcheck:
test: ["CMD-SHELL", "pg_isready -q -d postgres -U ${POSTGRES_USER:-postgres}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres_db:/var/lib/postgresql/data
- ./init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
ports:
- "8432:5432"
mem0-dashboard:
build: ./dashboard
ports:
- "3000:3000"
networks:
- mem0_network
environment:
# Used by the Dashboard's server-side refresh-token route to decide
# whether its session cookie must be Secure. It must be the externally
# reachable dashboard URL (not 0.0.0.0).
- DASHBOARD_URL=${DASHBOARD_URL:-http://localhost:3000}
# Browser-facing API address. Do not use localhost when accessing the
# dashboard from another computer.
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL:-http://localhost:8888}
- API_INTERNAL_URL=http://mem0:8000
- NEXT_PUBLIC_INSTANCE_NAME=Mem0
depends_on:
mem0:
condition: service_started
healthcheck:
test: ["CMD", "wget", "-qO-", "http://127.0.0.1:3000/api/health"]
interval: 10s
timeout: 5s
retries: 3
volumes:
postgres_db:
networks:
mem0_network:
driver: bridge
还应加入启动校验和 /configure 校验:
text
MEM0_EMBEDDER_DIMENSIONS 必须等于 MEM0_VECTOR_STORE_DIMENSIONS
不相等时直接拒绝启动或拒绝保存配置,而不是运行到写入数据时才报错。
你的 vLLM 服务还需验证
你的 BGE-M3 服务应支持 OpenAI 兼容的 /v1/embeddings。vLLM 支持该接口,但仅适用于正确以 embedding/pooling 任务运行的模型。vLLM OpenAI 兼容 Embeddings 文档
先在 BGE-M3 所在机器测试:
bash
curl -sS http://127.0.0.1:9027/v1/embeddings \
-H "Content-Type: application/json" \
-d '{
"model": "bge-m3-local",
"input": "Mem0 正在验证 BGE-M3 向量服务。",
"encoding_format": "float"
}'
若安装了 jq,可直接检查维度:
bash
curl -sS http://127.0.0.1:9027/v1/embeddings \
-H "Content-Type: application/json" \
-d '{
"model": "bge-m3-local",
"input": "Mem0 正在验证 BGE-M3 向量服务。",
"encoding_format": "float"
}' | jq '.data[0].embedding | length'
期望输出:
text
1024
如果返回 404、task not supported 或类似错误,说明当前 vLLM 进程没有以 embedding/pooling 模式启动;需要结合该机器实际 vLLM 版本调整为 --runner pooling 或对应的 embedding task 参数后再验证。
Docker 网络注意事项
如果 Mem0 在 Docker 容器中,而两个 vLLM 进程运行在 Docker 宿主机:
text
127.0.0.1:9026
127.0.0.1:9027
对 Mem0 容器来说并不是宿主机,而是容器自身。因此不能将容器内地址填写为 127.0.0.1。
Linux Docker 下推荐在 docker-compose.yaml 的 mem0 服务添加:
yaml
extra_hosts:
- "host.docker.internal:host-gateway"
然后才可使用:
dotenv
MEM0_LLM_BASE_URL=http://host.docker.internal:9026/v1
MEM0_EMBEDDER_BASE_URL=http://host.docker.internal:9027/v1
如果 vLLM 在另一台机器,则改为那台机器的内网 IP,例如:
dotenv
MEM0_LLM_BASE_URL=http://10.0.0.10:9026/v1
MEM0_EMBEDDER_BASE_URL=http://10.0.0.10:9027/v1
最后,向量维度一旦已有数据就不能直接改。例如现有 memories collection 已用 1536 维写入数据,切换 BGE-M3 的 1024 维时,应新建 collection,例如 memories_bge_m3,或确认无重要数据后重建。
下一步实现时,建议修改范围为:
server/main.py:读取独立 LLM、Embedder、向量维度配置,并加入维度一致性校验;server/.env.example:提供完整说明和默认值;server/docker-compose.yaml:仅在 vLLM 与 Mem0 同宿主机时增加host-gateway;- 增加回归测试:默认值、独立地址、维度不一致时失败、1024 配置成功。