46441335c0
- 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>
236 lines
8.4 KiB
Markdown
236 lines
8.4 KiB
Markdown
# Docker Compose 生产部署
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 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](../../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` — 缺失会导致 **panic**
|
||
- `ADMIN_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 零依赖,立即启动
|
||
|
||
---
|
||
|
||
## 运行时状态
|
||
|
||
```bash
|
||
$ 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](../../.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`:
|
||
|
||
```bash
|
||
# 无域名(仅 HTTP)
|
||
DOMAIN=
|
||
|
||
# 有域名(自动 HTTPS)
|
||
DOMAIN=your-domain.com
|
||
ACME_EMAIL=admin@your-domain.com
|
||
```
|
||
|
||
Caddy 在 `DOMAIN` 有值时自动从 Let's Encrypt 申请 TLS 证书,无需额外配置。
|
||
|
||
## 常用命令
|
||
|
||
```bash
|
||
# 重新构建并启动单个服务
|
||
docker compose up -d --build gateway
|
||
|
||
# 查看特定服务日志
|
||
docker compose logs -f ai-core
|
||
|
||
# 停止所有服务
|
||
docker compose down
|
||
|
||
# 停止并删除数据卷(危险)
|
||
docker compose down -v
|
||
```
|