# Cyrene 部署指南

三种方式启动开发环境：**ethend 一键**（推荐）、**手动逐服务**、**Docker Compose**。

---

## 环境要求

| 依赖 | 版本 | 用途 |
|------|------|------|
| Go | 1.21+ | 编译后端服务 |
| Node.js | 20+ (LTS) | 前端 / ethend |
| Docker & Docker Compose | — | 数据库 & 基础设施 |
| Git Bash (Windows) | — | 运行 ethend.sh |

### Windows 额外要求

- **Git for Windows**（提供 Git Bash 终端），安装时选择 "Git Bash Here"
- Go 和 Node.js 需加入系统 **PATH**（安装时勾选 "Add to PATH"）
- Docker Desktop 需启用 **WSL 2** 后端

Windows 提供两个启动脚本：

| 脚本 | 终端 | 适用场景 |
|------|------|----------|
| `ethend.bat` | CMD / PowerShell | 双击运行，无需 Git Bash |
| `ethend.sh` | Git Bash | 完整 CLI 体验（推荐） |

两者支持相同的命令集，日常开发推荐使用 Git Bash 运行 `./ethend.sh`；快速启动可直接双击 `ethend.bat`。

---

## 方式一：ethend 一键启动（推荐）

### 1. 配置环境变量

```bash
cp .env.example .env
# 编辑 .env，至少配置:
#   LLM_API_URL  /  LLM_API_KEY / LLM_MODEL
#   ADMIN_USERNAME / ADMIN_PASSWORD
```

### 2. 启动数据库

```bash
./ethend.sh db:start
```

### 3. 编译并启动全部服务

```bash
./ethend.sh start --build
```

首次运行会编译全部后端 Go 服务（约 1-2 分钟），之后按依赖顺序启动全部服务，每步等待健康检查通过。

### 4. 打开控制台

| 地址 | 说明 |
|------|------|
| `http://localhost:9090` | ethend 管理面板 |
| `http://localhost:5173` | 前端聊天界面 |

详细 CLI 用法见 [docs/api/ethend.md](docs/api/ethend.md)。

---

## 方式二：手动逐服务启动

适用于需要精细控制或调试单个服务的场景。

### 1. 配置 + 数据库

```bash
cp .env.example .env   # 编辑配置
docker compose -f docker-compose.dev.db.yml up -d
```

### 2. 按依赖顺序编译并启动

```bash
# 1) 记忆服务 (端口 8091)
cd backend/memory-service && go build -o main.exe ./cmd/main.go && ./main.exe

# 2) IoT 调试服务 (端口 8083)
cd backend/iot-debug-service && go build -o main.exe ./cmd/main.go && ./main.exe

# 3) 语音服务 (端口 8093)
cd backend/voice-service && go build -o main.exe ./cmd/main.go && ./main.exe

# 4) AI-Core (端口 8081)
cd backend/ai-core && go build -o main.exe ./cmd/main.go && ./main.exe

# 5) Gateway (端口 8080)
cd backend/gateway && go build -o main.exe ./cmd/main.go && ./main.exe

# 6) 前端 (端口 5173)
cd frontend/web && npm install && npx vite --host 0.0.0.0
```

> **注意**: Linux/macOS 下去掉 `.exe` 后缀。编译时必须设置 `GOWORK=off`。

---

## 方式三：Docker Compose

### 开发环境（基础设施 + 后端服务）

```bash
docker compose -f docker-compose.dev.yml up -d
```

启动服务：postgres, redis, qdrant, minio, searxng, memory-service, voice-service, iot-debug-service, ai-core, gateway, ethend。前端需本地启动。

### 生产环境

```bash
# 1. 配置环境变量
cp .env.example .env
# 编辑 .env，填入真实的 API Key 和密码

# 2. 启动所有服务
docker compose up -d
```

包含 Caddy 反向代理（自动 TLS）。详细说明见 [docs/deploy/docker-compose.md](docs/deploy/docker-compose.md)。

---

## 项目架构

```
Cyrene/
├── frontend/web/                # React 前端 (Vite + TypeScript)
├── backend/
│   ├── ai-core/                 # AI 推理核心 (LLM 编排、人设注入、工具调用、后台思考)
│   ├── gateway/                 # API 网关 (JWT、路由、限流、WebSocket Hub)
│   ├── memory-service/          # 记忆服务 (CRUD、语义检索、衰减、自动提取)
│   ├── voice-service/           # 语音服务 (DashScope STT + Edge-TTS)
│   ├── iot-debug-service/       # IoT 调试服务 (8 个模拟智能家居设备)
│   └── pkg/                     # 共享包 (logger 等)
├── ethend/                    # ethend 管理面板 (Express + WebSocket)
├── scripts/                     # 辅助脚本 (migrate / tunnel / whisper-setup / pg-backup)
├── searxng/                     # SearXNG 搜索引擎配置
├── backups/                     # 数据库备份文件
├── test/                        # E2E 测试
├── docs/                        # 文档
├── docker-compose.dev.db.yml    # 开发基础设施
├── docker-compose.dev.yml       # 开发环境 (DB + 后端 + ethend + SearXNG)
├── docker-compose.yml           # 生产环境 (+ Caddy)
└── ethend.sh                  # ethend CLI
```

---

## 服务端口

| 端口 | 服务 | 对外 |
|------|------|------|
| 5173 | Frontend (Vite) | 是 |
| 8080 | Gateway API | **是**（唯一客户端入口） |
| 8081 | AI-Core | 否 |
| 8083 | IoT Debug | 否 |
| 8091 | Memory Service | 否 |
| 8088 | SearXNG | 否 |
| 8093 | Voice Service | 否 |
| 9090 | ethend | 是 |
| 5432 | PostgreSQL | 否 |
| 6379 | Redis | 否 |
| 6333 | Qdrant HTTP | 否 |
| 6334 | Qdrant gRPC | 否 |
| 9000 | MinIO S3 | 否 |
| 9001 | MinIO Console | 否 |

> **客户端只需连接 Gateway (8080)**。所有后端服务不直接对外暴露。

---

## 核心环境变量

完整列表见 `.env.example`。

### 必填

| 变量 | 说明 |
|------|------|
| `LLM_API_URL` | LLM API 地址 |
| `LLM_API_KEY` | LLM API 密钥 |
| `LLM_MODEL` | 主模型 |
| `ADMIN_USERNAME` | 管理员用户名 |
| `ADMIN_PASSWORD` | 管理员密码 |
| `JWT_SECRET` | JWT 签名密钥 |

### 推荐配置

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `LLM_FALLBACK_MODEL` | 回退模型 | `gpt-4o-mini` |
| `ENV` | 运行环境 | `development` |
| `REGISTRATION_ENABLED` | 开放注册 | `true` |
| `ADMIN_NICKNAME` | 管理员显示昵称 | `管理员` |
| `JWT_EXPIRY_HOURS` | JWT 有效期 | `720` |
| `ENABLE_BACKGROUND_THINKING` | 后台自主思考 | `true` |
| `THINK_OFFLINE_GAP_SEC` | 离线时思考间隔 | `600` |
| `ALLOWED_ORIGINS` | CORS 跨域白名单 | `http://localhost:5173,...` |
| `INTERNAL_SERVICE_TOKEN` | 服务间通信 Token | — |
| `WEBHOOK_API_KEY` | Webhook API Key | — |

### 语音 (可选)

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `DASHSCOPE_API_KEY` | 阿里云 DashScope API Key | — |
| `DASHSCOPE_STT_MODEL` | STT 模型 | `qwen3-asr-flash-...` |
| `TTS_PROVIDER` | TTS 引擎 | `edge-tts` |
| `ASR_PROVIDER` | 本地 ASR 引擎 | `faster-whisper` |

### 服务地址

| 变量 | 默认值 |
|------|--------|
| `MEMORY_SERVICE_URL` | `http://localhost:8091` |
| `VOICE_SERVICE_URL` | `http://localhost:8093` |
| `IOT_SERVICE_URL` | `http://localhost:8083` |

### 数据库 / 存储

| 变量 | 默认值 |
|------|--------|
| `POSTGRES_HOST` / `POSTGRES_PORT` | `localhost` / `5432` |
| `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB` | `cyrene` / — / `cyrene_ai` |
| `REDIS_HOST` / `REDIS_PORT` | `localhost` / `6379` |
| `MINIO_ENDPOINT` | `localhost:9000` |
| `VECTOR_DB_URL` | `http://localhost:6333` |

---

## 数据库管理

```bash
# 通过 ethend CLI
./ethend.sh db:start          # 启动
./ethend.sh db:stop           # 停止
./ethend.sh db:status         # 状态检查

# 直接 Docker Compose
docker compose -f docker-compose.dev.db.yml up -d
docker compose -f docker-compose.dev.db.yml down

# 开发数据库容器名
docker exec -it cyrene_postgres psql -U cyrene -d cyrene_ai
```

---

## 数据库备份

```bash
# 备份数据库
./scripts/pg-backup.sh backup

# 从最新备份恢复
./scripts/pg-backup.sh restore
```

备份文件保存在 `backups/` 目录，自动保留最近 7 个。详见 [docs/pg-backup-migration.md](docs/pg-backup-migration.md)。

---

## 平台迁移

从 Linux 迁移到 Windows 的详细指南见 [Migration.md](Migration.md)。

---

## 附：Windows 部署说明

### 启动脚本

| 脚本 | 终端 | 说明 |
|------|------|------|
| `ethend.bat` | CMD / PowerShell | 双击即可运行，无需 Git Bash |
| `ethend.sh` | Git Bash | 完整 CLI（推荐） |

```cmd
:: CMD 中直接运行
ethend.bat start --build
ethend.bat status
ethend.bat logs gateway

:: Git Bash 中运行
./ethend.sh start --build
./ethend.sh status
```

### 编译差异

Windows 下 Go 编译产物为 `main.exe` 而非 `main`。ethend 已自动处理此差异，手动编译时需要注意：

```bash
# Windows (Git Bash / PowerShell)
go build -o main.exe ./cmd/main.go
./main.exe

# Linux / macOS
go build -o main ./cmd/main.go
./main
```

所有 Go 服务编译时必须设置 `GOWORK=off`：

```bash
GOWORK=off go build -o main.exe ./cmd/main.go
```

### 端口与进程管理

Windows 没有 `fuser` / `ss` 命令，等价操作为：

```bash
# 查看端口占用
netstat -ano | findstr ":8080"

# 杀进程 (PowerShell)
powershell -Command "Stop-Process -Id <PID> -Force"

# 或者直接用 ethend CLI（跨平台兼容）
./ethend.sh status      # 查看各服务端口状态
./ethend.sh stop        # 停止 ethend
```

### Docker Desktop

安装 Docker Desktop 后确保：
1. **Settings → General** → 勾选 "Use WSL 2 based engine"
2. **Settings → Resources → WSL Integration** → 启用对应发行版
3. 启动 Docker Desktop 后等待引擎就绪，再执行 `docker compose` 命令

若遇到`docker: error during connect`，说明 Docker Desktop 未运行，启动后重试。

### Node.js 版本

建议使用 **Node.js 20 LTS**。Node.js 22-24 存在 WebSocket 相关的已知问题（`UV_HANDLE_CLOSING` 崩溃），开发环境建议降级到 v20。

### Git Bash PATH

若 Git Bash 中找不到 `go` 或 `node`：

```bash
# 检查 PATH
echo $PATH

# 手动添加（添加到 ~/.bashrc 或 ~/.bash_profile）
export PATH="$PATH:/c/Program Files/Go/bin"
export PATH="$PATH:/c/Program Files/nodejs"
```

### 快速排错

| 症状 | 可能原因 | 解决 |
|------|----------|------|
| `go: command not found` | Go 未加入 PATH | 重启 Git Bash 或手动 `export PATH` |
| `Only one usage of each socket address` | 端口被占用 | `./ethend.sh stop` 或用 PowerShell 杀进程 |
| `docker: error during connect` | Docker Desktop 未启动 | 启动 Docker Desktop 等待就绪 |
| `GOWORK` 相关编译错误 | 未设置 GOWORK=off | `export GOWORK=off` 或在命令前加 `GOWORK=off` |
| `npm install` 卡住 | Windows 下 npm 网络问题 | 设置镜像 `npm config set registry https://registry.npmmirror.com` |
