# 君鸿卡管系统 - 部署指南

本文档提供从零开始部署君鸿卡管系统到测试环境的完整步骤。

---

## 架构概览

```
┌─────────────────────────────────────────────────────────────────┐
│                         部署架构图                               │
└───────────────────────────┬─────────────────────────────────────┘
                            │
        ┌───────────────────▼───────────────────┐
        │      开发者 Push 代码到 Gitea        │
        │    (main/dev/test 分支)              │
        └───────────────────┬───────────────────┘
                            │
        ┌───────────────────▼───────────────────┐
        │  部署服务器 (47.111.166.169)          │
        │                                       │
        │  ┌─────────────────────────────────┐ │
        │  │  Act Runner (docker-runner-01)  │ │
        │  │  自动触发工作流                  │ │
        │  └───────────┬─────────────────────┘ │
        │              │                        │
        │  ┌───────────▼─────────────────────┐ │
        │  │  构建 Docker 镜像                │ │
        │  │  - API 镜像                      │ │
        │  │  - Worker 镜像                   │ │
        │  └───────────┬─────────────────────┘ │
        │              │                        │
        │  ┌───────────▼─────────────────────┐ │
        │  │  Push 到私有 Docker Registry     │ │
        │  │  registry.boss160.cn             │ │
        │  └───────────┬─────────────────────┘ │
        │              │                        │
        │  ┌───────────▼─────────────────────┐ │
        │  │  本地部署（无 SSH）              │ │
        │  │  - Pull 镜像                     │ │
        │  │  - 滚动更新容器                  │ │
        │  │  - 清理旧镜像（保留 3 个）       │ │
        │  └───────────┬─────────────────────┘ │
        │              │                        │
        │  ┌───────────▼─────────────────────┐ │
        │  │  服务运行中                      │ │
        │  │  - API: 0.0.0.0:3000             │ │
        │  │  - Worker: 后台任务处理          │ │
        │  └──────────────────────────────────┘ │
        └───────────────────────────────────────┘
```

**关键优势**：Act Runner 在部署服务器本地运行，无需 SSH，配置简单！

---

## 前置准备

### 1. 服务器环境要求

- **操作系统**：Ubuntu 20.04+ / CentOS 7+
- **Docker**：20.10+
- **Docker Compose**：1.29+
- **内存**：至少 2GB
- **磁盘**：至少 20GB
- **Act Runner**：已部署并注册到 Gitea（✅ 你已经有了 docker-runner-01）

### 2. 外部依赖服务

系统依赖以下外部服务（需提前部署）：

- **PostgreSQL 14+**：数据库
- **Redis 6.0+**：缓存和队列

---

## 第一步：服务器初始化

### 1.1 确认 Docker 环境

```bash
# SSH 到服务器
ssh qycard001@47.111.166.169 -p 52022

# 验证 Docker 和 Docker Compose
docker --version
docker-compose --version

# 验证 Act Runner 正在运行
docker ps | grep runner
# 应该能看到 docker-runner-01
```

### 1.2 创建部署目录

```bash
# 创建部署目录
mkdir -p /home/qycard001/app/junhong_cmp
cd /home/qycard001/app/junhong_cmp

# 创建日志目录（配置已嵌入二进制文件，无需 configs 目录）
mkdir -p logs
```

### 1.3 配置说明

系统使用**嵌入式配置 + 环境变量覆盖**机制：

- 默认配置已编译在二进制文件中
- 通过 `docker-compose.prod.yml` 中的环境变量覆盖配置
- 环境变量前缀：`JUNHONG_`
- 格式：`JUNHONG_{配置路径}`，路径分隔符用下划线替代点号

**无需手动创建配置文件**，所有配置在 `docker-compose.prod.yml` 的 `environment` 中管理。

### 1.4 部署文件

`docker-compose.prod.yml` 由 CI/CD 自动从代码仓库复制到部署目录，无需手动操作。

如需手动部署，可从代码仓库复制：

```bash
# 方式1: 使用 Git
git clone <你的仓库地址> temp
cp temp/docker-compose.prod.yml ./docker-compose.prod.yml
rm -rf temp

# 方式2: 从本地上传
# scp -P 52022 docker-compose.prod.yml qycard001@47.111.166.169:/home/qycard001/app/junhong_cmp/
```

---

## 第二步：配置 Gitea Secrets

详细步骤请参考 [Gitea Secrets 配置说明](./gitea-secrets-setup.md)。

**只需要配置 2 个 Secrets**（非常简单！）：

| Secret 名称 | 值 |
|------------|-----|
| `REGISTRY_USERNAME` | `junhong_admin` |
| `REGISTRY_PASSWORD` | `JunHong@2025!Registry` |

**配置步骤**：
1. 进入 Gitea 仓库 → 设置 → Secrets
2. 添加 `REGISTRY_USERNAME`，值为 `junhong_admin`
3. 添加 `REGISTRY_PASSWORD`，值为 `JunHong@2025!Registry`
4. 完成！

---

## 第三步：首次手动部署

在自动化 CI/CD 生效前，先进行一次手动部署验证环境。

### 3.1 登录 Docker Registry

```bash
# 在服务器上执行
ssh qycard001@47.111.166.169 -p 52022

docker login registry.boss160.cn -u junhong_admin
# 输入密码：JunHong@2025!Registry
```

### 3.2 手动构建镜像（可选）

如果 CI/CD 还未运行，可以手动构建：

```bash
cd <代码仓库目录>

# 构建 API 镜像
docker build -f Dockerfile.api -t registry.boss160.cn/junhong/cmp-fiber-api:latest .

# 构建 Worker 镜像
docker build -f Dockerfile.worker -t registry.boss160.cn/junhong/cmp-fiber-worker:latest .

# 推送镜像
docker push registry.boss160.cn/junhong/cmp-fiber-api:latest
docker push registry.boss160.cn/junhong/cmp-fiber-worker:latest
```

### 3.3 启动服务

```bash
cd /home/qycard001/app/junhong_cmp

# 拉取镜像
docker-compose -f docker-compose.prod.yml pull

# 启动服务
docker-compose -f docker-compose.prod.yml up -d

# 查看服务状态
docker-compose -f docker-compose.prod.yml ps

# 查看日志
docker-compose -f docker-compose.prod.yml logs -f
```

### 3.4 验证部署

```bash
# 测试 API 健康检查
curl http://localhost:3000/health

# 预期输出：
# {"code":0,"msg":"ok","data":{"status":"healthy"},"timestamp":1234567890}

# 查看容器状态
docker ps | grep junhong
```

---

## 第四步：自动化部署

配置完成后，每次 Push 代码到 `main` / `dev` / `test` 分支时，会自动触发构建。

### 工作流触发规则

| 分支 | 镜像标签 | 是否自动部署 |
|------|---------|------------|
| `main` | `latest` | ✅ 是 |
| `dev` | `dev` | ❌ 否（仅构建镜像）|
| `test` | `test` | ❌ 否（仅构建镜像）|

### 触发自动部署

```bash
# 在本地提交代码
git add .
git commit -m "测试自动部署"
git push origin main
```

### 监控部署进度

1. 在 Gitea 仓库页面点击 **Actions** 标签
2. 查看最新的工作流运行状态
3. 点击工作流查看详细日志

**预期日志输出**：
```
✅ 检出代码
✅ 设置镜像标签: latest
✅ 登录 Docker Registry
✅ 构建 API 镜像
✅ 构建 Worker 镜像
✅ 推送镜像到 Registry
✅ 部署到本地
   - 拉取最新镜像...
   - 执行滚动更新...
   - 等待服务健康检查...
   - 清理旧镜像（保留最近 3 个版本）...
   - 部署完成！
✅ 构建结果通知
```

---

## 运维操作

### 查看服务日志

```bash
cd /home/qycard001/app/junhong_cmp

# 查看 API 日志
docker-compose -f docker-compose.prod.yml logs -f api

# 查看 Worker 日志
docker-compose -f docker-compose.prod.yml logs -f worker

# 查看应用日志文件
tail -f logs/app.log | jq .
tail -f logs/access.log | jq .
```

### 重启服务

```bash
cd /home/qycard001/app/junhong_cmp

# 重启所有服务
docker-compose -f docker-compose.prod.yml restart

# 重启单个服务
docker-compose -f docker-compose.prod.yml restart api
docker-compose -f docker-compose.prod.yml restart worker
```

### 手动执行数据库迁移

```bash
# 进入 API 容器
docker exec -it junhong-cmp-api bash

# 查看当前迁移版本
migrate -path /app/migrations -database "$(cat /app/.env | grep DB_ | xargs)" version

# 执行迁移（通常容器启动时会自动执行）
migrate -path /app/migrations -database "$(cat /app/.env | grep DB_ | xargs)" up
```

### 回滚到旧版本

```bash
cd /home/qycard001/app/junhong_cmp

# 查看可用镜像
docker images | grep cmp-fiber

# 示例输出：
# registry.boss160.cn/junhong/cmp-fiber-api   latest    abc123    2 hours ago   50MB
# registry.boss160.cn/junhong/cmp-fiber-api   def456    def456    1 day ago     50MB

# 修改 docker-compose.prod.yml 中的镜像标签
# 将 :latest 改为具体的 commit SHA
sed -i 's/:latest/:def456/g' docker-compose.prod.yml

# 重新部署
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml up -d
```

### 清理磁盘空间

```bash
# 清理未使用的镜像
docker image prune -a -f

# 清理未使用的容器
docker container prune -f

# 清理未使用的卷
docker volume prune -f

# 一键清理所有（谨慎使用）
docker system prune -a -f --volumes
```

---

## 常见问题

### Q1: 容器启动失败，显示 "unhealthy"

**排查步骤**：
1. 查看容器日志：`docker-compose -f docker-compose.prod.yml logs api`
2. 检查 `docker-compose.prod.yml` 中的环境变量配置是否正确（数据库连接、Redis 连接）
3. 确认外部依赖（PostgreSQL、Redis）是否可访问
4. 手动测试健康检查：`curl http://localhost:3000/health`

### Q2: 数据库迁移失败

**可能原因**：
- 数据库连接信息错误
- 迁移文件损坏
- 数据库权限不足

**解决方法**：
```bash
# 检查 .env 文件配置
cat /home/qycard001/app/junhong_cmp/.env

# 手动测试数据库连接
docker run --rm postgres:14 psql "postgresql://erp_pgsql:erp_2025@cxd.whcxd.cn:16159/junhong_cmp_test?sslmode=disable" -c "SELECT 1;"

# 查看迁移日志
docker logs junhong-cmp-api | grep migrate
```

### Q3: CI/CD 工作流失败

**常见原因**：
1. **Secrets 未配置或错误**：检查 Gitea Secrets 是否配置了 `REGISTRY_USERNAME` 和 `REGISTRY_PASSWORD`
2. **Registry 认证失败**：验证用户名密码是否正确
3. **磁盘空间不足**：执行 `df -h` 检查磁盘空间

**排查方法**：
- 在 Gitea Actions 页面查看详细日志
- 在服务器上手动测试 Registry 登录：`docker login registry.boss160.cn -u junhong_admin`

### Q4: 镜像拉取慢或超时

**解决方法**：
```bash
# 检查 Registry 连接
curl -I https://registry.boss160.cn

# 检查网络
ping registry.boss160.cn

# 查看 Docker 日志
journalctl -u docker -f
```

### Q5: Act Runner 权限问题

**问题现象**：工作流报错 `permission denied` 或 `cannot connect to Docker daemon`

**解决方法**：
```bash
# 确认 Act Runner 用户在 docker 组中
docker exec -it docker-runner-01 groups

# 如果缺少 docker 组，重启 Act Runner 容器
docker restart docker-runner-01
```

---

## 安全建议

1. **定期更新**：
   - 定期更新 Docker 和 Docker Compose
   - 及时应用系统安全补丁

2. **防火墙配置**：
   ```bash
   # 仅开放必要端口
   sudo ufw allow 52022/tcp   # SSH
   sudo ufw allow 3000/tcp    # API（如果需要外部访问）
   sudo ufw enable
   ```

3. **日志监控**：
   - 配置日志轮转，防止磁盘占满
   - 定期审查访问日志和错误日志

4. **备份策略**：
   - 定期备份数据库
   - 定期备份 `docker-compose.prod.yml`（包含所有配置）

---

## 下一步

部署完成后：
1. ✅ 配置域名和反向代理（Nginx / Caddy）
2. ✅ 启用 HTTPS（Let's Encrypt）
3. ✅ 配置监控和告警（Prometheus + Grafana）
4. ✅ 设置自动备份脚本

---

## 支持

如有问题，请联系运维团队或提交 Issue。
