部署文档

拉代码 → 配 .env → docker compose up,三步把平台跑起来。数据库不用单独安装,Compose 自带 PostgreSQL 和 Redis。每个配置字段的完整说明见 环境变量清单,本页不重复。

1. 准备要求

  • Docker 20+ 与 Docker Compose v2。
  • 2 核 4G 内存起步;磁盘预留 10G+(镜像 + 数据卷)。
  • 端口:3006(Web 入口,可自行改映射)、8003(节点控制服务,只对节点和内网开放,不是网页)、8004(Tunnel Runtime,仅容器内网,不对外)。
  • PostgreSQL 16 与 Redis 7 由 Compose 自动创建,无需预装。

2. 拉取代码与子模块

克隆时带 --recurse-submodules,一条命令连主仓和五个子仓一起拉下来。不要只看主仓页面上的“关联仓库”——Git 实际拉取的是主仓 .gitmodules 记录的五个子仓。

# 1. 主仓 + 全部子模块(国内直连 GitHub 慢,用 gh-proxy 加速)
git clone --recurse-submodules https://gh-proxy.org/https://github.com/wuxin-gh/ai-lubricant.git
cd ai-lubricant

# 2. 确认五项前面没有 “-”
git submodule status

主仓使用相对 submodule URL,从 Gitee 克隆时会按当前组织解析为以下仓库:

目录Gitee 仓库构建用途
node_serverxiongrun/ai-lubricant-node-server节点控制服务
nodesxiongrun/ai-lubricant-nodes节点二进制与 Agent 运行时
user-frontendxiongrun/ai-lubricant-user-frontendWeb 管理端与用户门户
mobilexiongrun/ai-lubricant-mobile手机客户端(服务端部署本身可不构建)
device-controlxiongrun/ai-lubricant-device-controlAndroid/iOS 控制组件
“关联仓库”不等于 Git 自动拉取这五个子仓必须在 Gitee 上真实存在,且当前账号有读取权限;否则 git submodule update 仍会失败。失败时先看命令输出的是哪个仓库 404/无权限,不要直接继续构建。

3. 配置 .env

cp .env.example .env

最小必改项(其余字段保持默认即可启动):

变量说明
POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DATABASE同时是 Compose 建库参数和应用连接参数,一处改两边生效。密码必须换成强密码。
AI_LUBRICANT_COMPAT_ENABLED要用 Web 管理端(/manager)和用户门户(/console)必须设 true。
AI_LUBRICANT_BOOTSTRAP_ADMIN_EMAIL / _PASSWORD首次启动幂等创建平台管理员;创建完成后从 .env 移除明文密码。
NODE_CONTROL_TOKEN数据服务→控制服务的内部 Bearer,两进程必须同值。见下方「生成三个共享密钥」。
NODE_CREDENTIAL_ENCRYPTION_KEY节点 TOTP 凭据 AES-256 密钥,生成后不可轮换,否则已加密的节点凭据全部失效。见下方生成方式。
AGENT_ATTACHMENT_SIGNING_KEYAgent 附件签名临时 URL 的 HMAC 密钥,多实例必须同值。见下方生成方式。

生成三个共享密钥(插入 .env,容器创建前必须有值)

容器创建时才会解析 .env,所以这三个值必须在 docker compose up 之前就写进 .env。任选一种生成方式(不需要 Python):

# a) 有 openssl(Linux/macOS 自带):
openssl rand -base64 32   →  填入 NODE_CONTROL_TOKEN=
openssl rand -hex 32      →  填入 NODE_CREDENTIAL_ENCRYPTION_KEY=
openssl rand -base64 48   →  填入 AGENT_ATTACHMENT_SIGNING_KEY=

# b) 有 Python:
python script/init_compose_env.py    # 自动写入 .env,幂等

# c) 都没有:浏览器搜 “random hex generator”,生成 32 字节随机串填入即可
#    三个值互相独立、各不相同;系统不校验格式,任意随机串均可。
留空会拒启这三个键若留空,node-server 首启会尝试「生成后写回 .env」;而在 Docker 单文件挂载(./.env:/app/.env)上文件重命名会报 [Errno 16] Device or resource busy,导致控制服务直接拒启(容器 unhealthy)。先在宿主 .env 填好非空值,node-server 读到值就跳过写回,不会触发该错误。
改完 .env 必须 up 重建,restart 无效docker compose restart 只重启进程,不重新解析 env_file——容器环境变量是创建那一刻的快照,之后改 .env 一个字节都不会进容器。改密钥后请用 docker compose up -d --force-recreate(或带 --build)。
不要提交 .env里面有数据库密码、内部 token 和管理员密码。生产环境敏感值走 Secret 注入,全量字段见 环境变量清单。
Compose 暴露的调试端口PostgreSQL 映射到宿主 15432、Redis 到 6479,仅本机调试用;生产环境把它们从对外映射里去掉,只留内网。

4. 启动

docker compose up -d --build

# 五个服务应为 running / healthy
docker compose ps

# 看数据服务日志
docker compose logs -f ai-lubricant

首次启动要构建应用镜像,需要几分钟。应用自动通过 postgres、redis 服务名连依赖,不需要手工填容器 IP。

服务角色端口
postgres业务数据库(渠道、账号、Key、任务、日志元数据)宿主 15432 → 容器 5432,仅调试
redis运行态真相源(限流、配额、冷却、会话)宿主 6479 → 容器 6379,仅调试
ai-lubricant数据服务:对外 API、管理端、用户门户、Agent 运行时、MCP宿主 3006 → 容器 8001
node-server节点控制面,接收节点 h2c 主动连接宿主 8003 → 容器 8003
tunnel-serverTunnel Runtime:管理 frpc / cloudflared / npc 子进程容器 8004,不对外发布

三个应用服务共享同一个镜像(build 一次,靠 command 区分入口),并读同一份 .env。启动顺序由 depends_on + 健康检查串起来:postgres/redis → node-server → ai-lubricant / tunnel-server。

不用内网穿透可以不起 tunnel-serverdocker compose up -d postgres redis node-server ai-lubricant 即可,隧道方案管理页与任务预览端口对外暴露会不可用,其余功能不受影响。也可以用 TUNNEL_RUNTIME_ENABLED=false 让它空转。

5. 初始化数据库

docker compose exec ai-lubricant python server/init_db.py

脚本幂等,重复运行安全。它只建表结构;如果启动日志提示「缺少必填主配置」,先完成管理员引导和基础配置,不要用反复重启解决。路径带 server/,脚本不在仓库根。

6. 访问

  • Web 入口:http://127.0.0.1:3006;管理端 /manager,用户门户 /console。
  • 8003 是节点控制服务,只接受节点连接和内部调用,不要当网页访问。
  • 生产部署用 HTTPS 反向代理指向 3006,并按 生产安全清单收敛其余端口。

7. 日常运维

# 升级到最新版
git pull
git submodule sync --recursive
git submodule update --init --recursive
docker compose up -d --build

# 备份数据库(逻辑备份)
docker compose exec -T postgres \
  pg_dump -U ai_lubricant -d ai-lubricant -Fc > ai-lubricant.dump

# 停止(保留数据卷)
docker compose down
升级必须一起更新子模块只 git pull 主仓,node_server/ 等子模块的工作树仍停在旧代码,docker compose up --build 用的还是旧源码。已部署升级后若节点页报「未配置控制面」,先 git submodule update --init --recursive 再重建镜像。
down -v 会删除数据卷除非已确认备份完成,否则不要执行 docker compose down -v。

8. 可选:ClickHouse

export CLICKHOUSE_REQUEST_PAYLOAD_ENABLED=true
docker compose --profile clickhouse up -d

不开也不影响模型代理主链路;开了才有请求大字段双写和对话存储。捕获请求正文前先完成隐私评估。

9. 替代方式:手动构建镜像

已有外部 PostgreSQL / Redis,或需要单独控制两个进程时才用这种方式;一般部署用上面的 Compose 即可。

# 构建镜像(python:3.11-slim + requirements.txt)
docker build -t ai-lubricant-api .

# 数据服务:外部 PG/Redis 地址用 -e 注入
docker run -d --name ai-lubricant \
  -p 8001:8001 --env-file .env \
  -e POSTGRES_HOST=10.x.x.x -e POSTGRES_PORT=5432 \
  -e POSTGRES_USER=... -e POSTGRES_PASSWORD=... -e POSTGRES_DATABASE=ai-lubricant \
  -e REDIS_HOST=10.x.x.x -e REDIS_PORT=6379 \
  ai-lubricant-api

# 节点控制服务:同一镜像换启动命令
docker run -d --name ai-lubricant-node-server \
  -p 8003:8003 --env-file .env \
  -e POSTGRES_HOST=10.x.x.x -e POSTGRES_PORT=5432 \
  -e POSTGRES_USER=... -e POSTGRES_PASSWORD=... -e POSTGRES_DATABASE=ai-lubricant \
  -e REDIS_HOST=10.x.x.x -e REDIS_PORT=6379 \
  -e NODE_CONTROL_HOST=0.0.0.0 -e NODE_CONTROL_PORT=8003 \
  ai-lubricant-api python -m node_server

# Tunnel Runtime:同一镜像再换启动命令
docker run -d --name ai-lubricant-tunnel-server \
  -p 8004:8004 --env-file .env \
  -e POSTGRES_HOST=10.x.x.x -e POSTGRES_PORT=5432 \
  -e POSTGRES_USER=... -e POSTGRES_PASSWORD=... -e POSTGRES_DATABASE=ai-lubricant \
  -e REDIS_HOST=10.x.x.x -e REDIS_PORT=6379 \
  -e AGENT_COMPOSE_BASE_URL=http://ai-lubricant-node-server:8003 \
  -e TUNNEL_RUNTIME_HOST=0.0.0.0 -e TUNNEL_RUNTIME_PORT=8004 \
  -e TUNNEL_RUNTIME_ENABLED=true \
  ai-lubricant-api python -m tunnel_server
两个容器必须读同一份 .envNODE_CONTROL_TOKEN 是数据服务→控制服务的内部 Bearer,两边必须完全一致,且必须在启动前就写进 .env(见第 3 步「生成三个共享密钥」)。不要依赖控制服务自动生成回写:单文件挂载的 .env 上写回会因文件重命名报 EBUSY 而拒启。Tunnel Runtime 经 AGENT_COMPOSE_BASE_URL 调控制服务,URL 错就启停不了隧道。

完整 Web 前端需要先构建产物:cd user-frontend && pnpm install && pnpm build,再把 /api、/admin、/v1、/agent、/mcp 前缀反代到数据服务(支持 WebSocket 与 SSE)。仓库用 pnpm(pnpm-lock.yaml 锁定),不要换成 npm。

10. 生产上线清单

  • 只公开 HTTPS 入口;PG、Redis、ClickHouse 和 8003 放内网或限制来源。
  • 启用 API Key 鉴权,创建最小权限 key,并定期轮换。
  • 为 PostgreSQL、Redis 数据、.env/Secrets、节点主密钥制定备份与恢复演练。
  • 升级前备份数据库;先在预发布环境验证流式 API、管理端、MCP、WebSocket、节点连接。
  • 保留前一版本镜像和前端 dist;回滚时判断数据库变更是否向后兼容,不能只回滚容器。
  • 数据服务日志按日写入 logs/ 并保留 30 天;生产同步到集中日志平台并控制访问权限。
  • 切换控制服务:先停旧控制进程再启新进程,绝不让两个 Registry 同时对同一批节点下发命令。
  • 不要把请求 payload 捕获当默认选项;开启前评估隐私、脱敏、保留期和访问审计。