# EternalAI 部署指南

## 架构概览

```
用户浏览器 → Nginx (80/443) → Node.js Express (3001) → PostgreSQL (5432)
                                    ↓
                              PM2 进程管理
```

## 文件清单

| 文件 | 用途 |
|------|------|
| `ecosystem.config.js` | PM2 进程配置 |
| `.env.example` | 环境变量模板 |
| `deploy/setup-server.sh` | 首次服务器初始化脚本 |
| `deploy/deploy.sh` | 每次部署脚本 |
| `deploy/nginx.conf` | Nginx 反向代理配置模板 |
| `.gitea/workflows/deploy.yml` | Gitea Actions CI/CD 工作流 |

---

## 一、首次部署（全量部署）

### 1.1 准备服务器

在目标服务器上执行以下操作。

```bash
# 克隆代码仓库
cd /opt  # 或你选择的部署目录
git clone http://gitea.fischerai.cn/chigulong/eternalai.git
cd eternalai
```

### 1.2 运行服务器初始化脚本

```bash
bash deploy/setup-server.sh
```

此脚本会自动完成：
- 检测并安装 Node.js 20 LTS（如缺失）
- 检测并安装 PostgreSQL 15（如缺失）
- 检测并安装 PM2（如缺失）
- 检测并安装 Nginx（如缺失）
- 创建数据库 `eternalai` 和用户
- 自动生成 `.env` 文件（含随机 JWT 密钥和数据库密码）
- 安装 npm 依赖
- 生成 Prisma Client
- 推送数据库 Schema
- 启动 PM2 进程并配置开机自启

**自定义数据库配置**（可选）：
```bash
DB_NAME=mydb DB_USER=myuser DB_PASS=mypassword bash deploy/setup-server.sh
```

脚本完成后会输出数据库密码，请妥善保存。

### 1.3 配置 Nginx 反向代理

```bash
# 复制 Nginx 配置
sudo cp deploy/nginx.conf /etc/nginx/sites-available/eternalai
sudo ln -s /etc/nginx/sites-available/eternalai /etc/nginx/sites-enabled/

# 编辑配置，替换 YOUR_DOMAIN 为实际域名
sudo nano /etc/nginx/sites-enabled/eternalai
# 将所有 YOUR_DOMAIN 替换为你的域名，如 eternalai.example.com

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo nginx -s reload
```

### 1.4 配置 HTTPS（推荐）

```bash
# 安装 Certbot
sudo apt-get install -y certbot python3-certbot-nginx  # Ubuntu/Debian
# 或
sudo yum install -y certbot python3-certbot-nginx      # CentOS/RHEL

# 自动获取并配置 SSL 证书
sudo certbot --nginx -d YOUR_DOMAIN

# 证书自动续期（Certbot 会自动配置 cron）
sudo certbot renew --dry-run
```

### 1.5 验证部署

```bash
# 检查 PM2 进程状态
pm2 status

# 查看应用日志
pm2 logs eternalai

# 测试本地访问
curl http://localhost:3001

# 测试 Nginx 代理访问
curl http://YOUR_DOMAIN
```

---

## 二、CI/CD 自动部署（推送即部署）

### 2.1 配置 Gitea Secrets

在 Gitea 仓库设置中添加 Secret：

1. 进入仓库 → Settings → Actions → Secrets
2. 添加 `DATABASE_URL`，值为 `.env` 文件中的 `DATABASE_URL`

### 2.2 配置 Gitea Runner

确保已注册 self-hosted runner：

```bash
# 在服务器上注册 runner（如尚未注册）
# 参考 Gitea 官方文档: https://docs.gitea.com/usage/actions/quickstart
```

### 2.3 自动部署流程

每次推送代码到 `master` 分支时，Gitea Actions 会自动：

1. 拉取最新代码
2. 安装 npm 依赖
3. 生成 Prisma Client
4. 推送数据库 Schema（`prisma db push`）
5. 重启 PM2 进程（`pm2 reload`）
6. 健康检查（等待 HTTP 200）
7. 重载 Nginx

```bash
# 推送代码触发自动部署
git push origin master
```

### 2.4 手动触发部署

在 Gitea 仓库 → Actions 页面，可手动触发 `Deploy EternalAI` 工作流。

---

## 三、手动部署（不使用 CI/CD）

```bash
# SSH 登录服务器
ssh user@your-server

# 进入应用目录
cd /opt/eternalai

# 运行部署脚本
bash deploy/deploy.sh
```

部署脚本会自动完成：拉取代码 → 安装依赖 → 数据库迁移 → 重启 PM2 → 健康检查。

---

## 四、常用运维命令

### PM2 进程管理

```bash
pm2 status                    # 查看进程状态
pm2 logs eternalai            # 实时查看日志
pm2 logs eternalai --lines 100  # 查看最近 100 行日志
pm2 restart eternalai         # 重启进程
pm2 reload eternalai          # 零停机重载
pm2 stop eternalai            # 停止进程
pm2 delete eternalai          # 删除进程
pm2 monit                     # 监控面板
```

### 数据库操作

```bash
# 推送 Schema 变更
npx prisma db push

# 打开 Prisma Studio（数据库可视化管理）
npx prisma studio

# 连接 PostgreSQL
psql -U eternalai -d eternalai -h localhost
```

### Nginx 操作

```bash
sudo nginx -t                 # 测试配置
sudo nginx -s reload          # 重载配置
sudo systemctl status nginx   # 查看状态
sudo tail -f /var/log/nginx/eternalai_error.log  # 查看错误日志
```

### 日志查看

```bash
# 应用日志
tail -f logs/out.log          # 标准输出
tail -f logs/err.log          # 错误输出

# Nginx 日志
sudo tail -f /var/log/nginx/eternalai_access.log
sudo tail -f /var/log/nginx/eternalai_error.log

# PostgreSQL 日志
sudo tail -f /var/log/postgresql/postgresql-15-main.log
```

---

## 五、更新部署

### 5.1 日常更新（代码变更）

```bash
# 方法一：推送代码触发 CI/CD（推荐）
git push origin master

# 方法二：手动部署
bash deploy/deploy.sh
```

### 5.2 数据库 Schema 变更

修改 `prisma/schema.prisma` 后：

```bash
# 推送到 master，CI/CD 会自动执行 prisma db push
git add prisma/schema.prisma
git commit -m "feat: update schema"
git push origin master

# 或手动执行
npx prisma db push
pm2 reload eternalai
```

### 5.3 环境变量变更

```bash
# 编辑 .env 文件
nano .env

# 重启应用使配置生效
pm2 reload eternalai --update-env
```

---

## 六、回滚

```bash
# 查看部署历史
git log --oneline -10

# 回滚到指定版本
git checkout <commit-hash>
npm install
npx prisma db push
pm2 reload eternalai

# 或回滚到上一个版本
git checkout HEAD~1
npm install
npx prisma db push
pm2 reload eternalai
```

---

## 七、故障排查

### 应用无法启动

```bash
# 查看错误日志
pm2 logs eternalai --err --lines 50

# 常见原因:
# 1. .env 文件缺失 → 运行 deploy/setup-server.sh
# 2. 数据库连接失败 → 检查 DATABASE_URL 和 PostgreSQL 服务
# 3. 端口被占用 → 检查 PORT 环境变量
```

### 数据库连接失败

```bash
# 检查 PostgreSQL 服务
sudo systemctl status postgresql

# 测试连接
psql -U eternalai -d eternalai -h localhost -W

# 检查 pg_hba.conf 认证配置
sudo cat /etc/postgresql/15/main/pg_hba.conf | grep -v '^#'
```

### Nginx 502 Bad Gateway

```bash
# 检查 Node.js 进程是否运行
pm2 status

# 检查端口
curl http://localhost:3001

# 检查 Nginx 错误日志
sudo tail -f /var/log/nginx/eternalai_error.log
```

### PM2 进程未开机自启

```bash
# 重新配置开机自启
pm2 startup systemd
# 执行输出的 sudo 命令
pm2 save
```
