- Go 服务 godotenv.Load("../.env") → godotenv.Load("../../.env")
- ethend.sh/config.js 读取路径改为根目录 .env
- 删除 .docker.env.example 和 backend/.env.example,统一为 .env.example
- Docker compose 默认读取根 .env,无需 --env-file
- 同步更新全部文档
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8.4 KiB
Docker Compose 生产部署
快速开始
# 1. 配置环境变量
cp .env.example .env
# 编辑 .env,填入真实的 API Key 和密码
# 有域名时设置 DOMAIN=your-domain.com
# 2. 启动所有服务
docker compose up -d
# 3. 查看状态
docker compose ps
docker compose logs -f
服务清单
| 服务 | 端口 | 说明 |
|---|---|---|
| caddy | 80 / 443 | 反向代理,自动 HTTPS |
| gateway | 8080 (内部) | API 网关 |
| ai-core | 8081 (内部) | AI 核心 |
| memory-service | 8091 (内部) | 记忆检索 |
| voice-service | 8093 (内部) | 语音识别 |
| iot-debug-service | 8083 (内部) | IoT 调试 |
| ethend | 9090 (外部) | 管理控制台 |
| postgres | 5432 (内部) | 数据库 (pgvector/pg16) |
| redis | 6379 (内部) | 缓存 |
| qdrant | 6333 (内部) | 向量数据库 |
| minio | 9000 (内部) | 对象存储 |
| searxng | 8080 (内部) | 搜索引擎 |
架构分层
Internet
│
▼
┌────────────────────────────────────┐
│ Caddy (:80/:443) │ ← 反向代理层
│ TLS 自动签发 · WebSocket 路由 │
└────────────┬───────────────────────┘
│
┌─────▼──────┐
│ Gateway │ ← API 网关层
│ :8080 │ 唯一后端入口
└──┬───┬───┬─┘
│ │ │
┌────▼┐ ┌▼───▼──┐ ┌────────────┐
│AI │ │Memory │ │Voice/IoT/ │ ← 业务服务层
│Core │ │:8091 │ │ethend │
│:8081│ └───────┘ └────────────┘
└──┬──┘
│
┌────▼───────────────────────────┐
│ Postgres · Redis · Qdrant · MinIO│ ← 基础设施层
└────────────────────────────────┘
12 个容器通过内部 Docker 网络通信(服务名即主机名)。仅 Caddy 和 ethend 向宿主机暴露端口。
各服务详解
反向代理层
Caddy — 唯一对外入口,监听 ${CADDY_HTTP_PORT:-80} 和 ${CADDY_HTTPS_PORT:-443}。
路由规则(由 Caddyfile 定义):
| 路径 | 转发目标 | 说明 |
|---|---|---|
/ws/* |
gateway:8080 | WebSocket 实时推送 |
/api/* |
gateway:8080 | REST API(含 X-Forwarded-For) |
| 其他 | 内置响应 | 前端占位页 |
DOMAIN非空时,Caddy 自动从 Let's Encrypt 签发 TLS 证书DOMAIN为空时仅 HTTP(:80模式)
API 网关层
Gateway (:8080) — 核心枢纽,所有客户端请求经由此处。启动要求 PostgreSQL 和 Redis 均通过健康检查。
功能:JWT 认证、用户注册/登录、WebSocket Hub、限流、CORS、消息排队。
关键 env:
JWT_SECRET+INTERNAL_SERVICE_TOKEN— 缺失会导致 panicADMIN_USERNAME+ADMIN_PASSWORD— 首次启动时自动创建管理员账号ALLOWED_ORIGINS— 跨域白名单,需包含 ethend 端口和前端地址
业务服务层
AI-Core (:8081) — LLM 编排核心:人设注入、多子会话调度、工具调用、后台思考。依赖 PostgreSQL 健康。
Memory Service (:8091) — 记忆 CRUD + 语义检索 + 衰减 + 自动提取。依赖 PostgreSQL 健康。
Voice Service (:8093) — DashScope 云 STT + whisper.cpp 本地 ASR。无启动依赖。
IoT Debug Service (:8083) — 8 个模拟智能家居设备。无启动依赖。
ethend (:9090) — 管理控制台 (Node.js Express):服务启停、日志监控、性能分析。端口直接暴露到宿主机(不经过 Caddy)。无启动依赖。
基础设施层
PostgreSQL (:5432) — pgvector/pgvector:pg16 镜像,存储用户、会话、消息、记忆、IoT 设备状态。健康检查 pg_isready 每 10s 一次,5 次失败才判定不健康。
Redis (:6379) — redis:7-alpine,WebSocket 会话缓存、JWT 黑名单、限流计数器。健康检查 redis-cli ping。
Qdrant (:6333-6334) — 向量数据库,记忆语义检索。无健康检查(非启动依赖)。
MinIO (:9000-9001) — S3 兼容对象存储,存放用户上传的图片和文件。
启动序列
Phase 1 (并行) Phase 2 (并行) Phase 3 (并行)
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ postgres │─健康──▶ │ gateway │ │ voice-svc │
│ redis │─健康──▶ │ ai-core │ │ iot-debug │
│ qdrant │ │ memory-svc │ │ ethend │
│ minio │ │ caddy │ │ │
│ searxng │ └──────────────┘ └──────────────┘
└──────────┘ 等 PG/Redis 健康 无依赖,立即启动
总是启动
- Phase 1 — 基础设施 + 搜索引擎,无依赖,总是最先启动
- Phase 2 — gateway / ai-core / memory-service 等待 PostgreSQL + Redis 健康检查通过;caddy 等待 gateway 容器启动
- Phase 3 — voice-service / iot-debug-service / ethend 零依赖,立即启动
运行时状态
$ docker compose ps
NAME STATUS PORTS
cyrene_caddy Up 0.0.0.0:80->80, 0.0.0.0:443->443
cyrene_gateway Up (healthy) 8080/tcp
cyrene_ai_core Up 8081/tcp
cyrene_memory_service Up 8091/tcp
cyrene_voice_service Up 8093/tcp
cyrene_iot_debug_service Up 8083/tcp
cyrene_ethend Up 0.0.0.0:9090->9090/tcp
cyrene_searxng Up 8080/tcp
cyrene_postgres Up (healthy) 5432/tcp
cyrene_redis Up (healthy) 6379/tcp
cyrene_qdrant Up 6333-6334/tcp
cyrene_minio Up 9000-9001/tcp
对外可达:
| 地址 | 经过 |
|---|---|
http://<IP>/api/v1/chat |
Caddy → Gateway → AI-Core |
ws://<IP>/ws |
Caddy → Gateway WebSocket |
http://<IP>:9090 |
直连 ethend |
数据持久化 — 5 个 Docker 卷(docker compose down 不会删除,需加 -v 才清空):
| 卷 | 内容 |
|---|---|
pg_data |
所有业务数据(用户、会话、消息、记忆) |
redis_data |
会话缓存 |
qdrant_data |
向量索引 |
minio_data |
上传文件 |
caddy_data |
TLS 证书 |
环境变量
所有变量在 .env 中配置,完整模板见 .env.example。
必填(服务启动 panic 若缺失)
| 变量 | 说明 |
|---|---|
LLM_API_URL |
LLM API 地址 |
LLM_API_KEY |
LLM API 密钥 |
ADMIN_PASSWORD |
管理员密码 |
JWT_SECRET |
JWT 签名密钥 |
INTERNAL_SERVICE_TOKEN |
服务间通信认证 Token |
POSTGRES_PASSWORD |
数据库密码 |
MINIO_SECRET_KEY |
MinIO 密钥 |
推荐配置
| 变量 | 默认值 | 说明 |
|---|---|---|
LLM_MODEL |
gpt-4o |
主模型 |
LLM_FALLBACK_MODEL |
gpt-4o-mini |
回退模型 |
ADMIN_USERNAME |
admin |
管理员用户名 |
ADMIN_NICKNAME |
管理员 |
AI 对管理员的称呼 |
REGISTRATION_ENABLED |
false |
开放注册(生产建议关闭) |
ALLOWED_ORIGINS |
http://localhost:5173,... |
CORS 白名单 |
ENABLE_BACKGROUND_THINKING |
true |
后台自主思考 |
ACME_EMAIL |
— | Let's Encrypt 证书邮箱 |
域名与 HTTPS
在 .env 中设置 DOMAIN 和 ACME_EMAIL:
# 无域名(仅 HTTP)
DOMAIN=
# 有域名(自动 HTTPS)
DOMAIN=your-domain.com
ACME_EMAIL=admin@your-domain.com
Caddy 在 DOMAIN 有值时自动从 Let's Encrypt 申请 TLS 证书,无需额外配置。
常用命令
# 重新构建并启动单个服务
docker compose up -d --build gateway
# 查看特定服务日志
docker compose logs -f ai-core
# 停止所有服务
docker compose down
# 停止并删除数据卷(危险)
docker compose down -v