# Novalon 管理系统 - 部署指南

## 1. 环境要求

### 1.1 硬件要求

| 组件 | 最低配置 | 推荐配置 |
|------|----------|----------|
| CPU | 2 核 | 4 核+ |
| 内存 | 4 GB | 8 GB+ |
| 磁盘 | 20 GB | 50 GB+ SSD |
| 网络 | 100 Mbps | 1 Gbps |

### 1.2 软件要求

| 软件 | 版本 | 说明 |
|------|------|------|
| JDK | 21 | OpenJDK 或 Oracle JDK |
| Maven | 3.9+ | 构建工具 |
| Node.js | 21+ | 前端构建 |
| Docker | 24.0+ | 容器化部署 |
| PostgreSQL | 15+ | 数据库 |
| Nginx | 1.24+ | 反向代理 |

### 1.3 端口要求

| 端口 | 协议 | 用途 |
|------|------|------|
| 8080 | HTTP | 后端 API 服务 |
| 3000 | HTTP | 前端开发服务 |
| 5432 | TCP | PostgreSQL 数据库 |
| 9090 | HTTP | Prometheus 监控 |
| 3000 | HTTP | Grafana 可视化 |

## 2. 本地开发环境部署

### 2.1 数据库部署

#### 启动 PostgreSQL

```bash
# 使用 Docker 启动 PostgreSQL
docker run -d \
  --name novalon-postgres \
  -e POSTGRES_DB=manage_system \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=postgres \
  -p 55432:5432 \
  -v postgres-data:/var/lib/postgresql/data \
  postgres:15-alpine
```

#### 初始化数据库

```bash
# 运行 Flyway 迁移
cd novalon-manage-api/manage-sys
mvn flyway:migrate
```

### 2.2 后端部署

#### 配置环境变量

```bash
# 创建 .env 文件
cat > novalon-manage-api/manage-app/.env << EOF
DB_HOST=localhost
DB_PORT=55432
DB_NAME=manage_system
DB_USERNAME=postgres
DB_PASSWORD=postgres
JWT_SECRET=novalon-manage-secret-key-change-in-production
JWT_EXPIRATION=86400000
EOF
```

#### 启动后端服务

```bash
cd novalon-manage-api/manage-app

# 开发模式启动
mvn spring-boot:run

# 或打包后启动
mvn clean package
java -jar target/manage-app-1.0.0.jar
```

#### 验证后端服务

```bash
# 健康检查
curl http://localhost:8084/actuator/health

# 查看 API 文档
open http://localhost:8084/swagger-ui.html
```

### 2.3 前端部署

#### 安装依赖

```bash
cd novalon-manage-web

# 使用 npm
npm install

# 或使用 pnpm (更快)
pnpm install
```

#### 配置 API 地址

```typescript
// 修改 src/utils/request.ts
const baseURL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8080';
```

#### 启动前端服务

```bash
# 开发模式
npm run dev

# 生产构建
npm run build
```

#### 验证前端服务

```bash
# 访问前端
open http://localhost:5173
```

## 3. Docker 容器化部署

### 3.1 构建镜像

#### 网关镜像

```bash
cd novalon-manage-api/manage-gateway

# 构建镜像
docker build -t novalon-manage-gateway:latest .

# 查看镜像
docker images | grep novalon
```

#### 应用镜像

```bash
cd novalon-manage-api/manage-app

# 构建镜像
docker build -t novalon-manage-app:latest .

# 查看镜像
docker images | grep novalon
```

#### 前端镜像

```bash
cd novalon-manage-web

# 构建镜像
docker build -t novalon-manage-web:latest .

# 查看镜像
docker images | grep novalon
```

### 3.2 Docker Compose 部署

#### 创建 docker-compose.yml

```yaml
version: '3.8'

services:
  postgres:
    image: postgres:15-alpine
    container_name: novalon-postgres
    environment:
      POSTGRES_DB: manage_system
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
    ports:
      - "55432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - novalon-network

  gateway:
    image: novalon-manage-gateway:latest
    container_name: novalon-gateway
    environment:
      SPRING_PROFILES_ACTIVE: prod
      JWT_SECRET: ${JWT_SECRET:-novalon-manage-secret-key}
    ports:
      - "8080:8080"
    depends_on:
      - app
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - novalon-network

  app:
    image: novalon-manage-app:latest
    container_name: novalon-app
    environment:
      SPRING_PROFILES_ACTIVE: prod
      DB_HOST: postgres
      DB_PORT: 5432
      DB_NAME: manage_system
      DB_USERNAME: postgres
      DB_PASSWORD: ${DB_PASSWORD:-postgres}
      JWT_SECRET: ${JWT_SECRET:-novalon-manage-secret-key}
    ports:
      - "8084:8084"
    depends_on:
      postgres:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:8084/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - novalon-network

  frontend:
    image: novalon-manage-web:latest
    container_name: novalon-web
    ports:
      - "80:80"
    depends_on:
      - gateway
    networks:
      - novalon-network

  prometheus:
    image: prom/prometheus:latest
    container_name: novalon-prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
    networks:
      - novalon-network

  grafana:
    image: grafana/grafana:latest
    container_name: novalon-grafana
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD:-admin}
    volumes:
      - grafana-data:/var/lib/grafana
    networks:
      - novalon-network

networks:
  novalon-network:
    driver: bridge

volumes:
  postgres-data:
  grafana-data:
```

#### 启动服务

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

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

# 停止并删除数据卷
docker-compose down -v
```

## 4. 生产环境部署

### 4.1 服务器准备

#### 系统配置

```bash
# 更新系统
sudo apt update && sudo apt upgrade -y

# 安装 Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# 安装 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# 安装 Nginx
sudo apt install nginx -y
```

#### 防火墙配置

```bash
# 开放必要端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp
sudo ufw enable
```

### 4.2 数据库部署

#### 生产数据库配置

```bash
# 使用生产级配置
docker run -d \
  --name novalon-postgres \
  -e POSTGRES_DB=manage_system \
  -e POSTGRES_USER=${DB_USER} \
  -e POSTGRES_PASSWORD=${DB_PASSWORD} \
  -p 5432:5432 \
  -v /data/postgres:/var/lib/postgresql/data \
  -v /etc/postgresql/postgresql.conf:/etc/postgresql/postgresql.conf:ro \
  postgres:15-alpine \
  -c max_connections=200 \
  -c shared_buffers=256MB \
  -c effective_cache_size=1GB
```

#### 数据库备份

```bash
# 创建备份脚本
cat > /scripts/backup-db.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/backup/postgres"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/manage_system_$DATE.sql"

mkdir -p $BACKUP_DIR

docker exec novalon-postgres pg_dump -U postgres manage_system > $BACKUP_FILE

# 压缩备份
gzip $BACKUP_FILE

# 删除 7 天前的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete

echo "Backup completed: $BACKUP_FILE.gz"
EOF

chmod +x /scripts/backup-db.sh

# 添加定时任务 (每天凌晨 2 点备份)
crontab -e
# 0 2 * * * /scripts/backup-db.sh
```

### 4.3 后端部署

#### 构建生产镜像

```bash
cd novalon-manage-api/manage-sys

# 构建生产镜像
docker build \
  --build-arg SPRING_PROFILES_ACTIVE=prod \
  -t registry.novalon.cn/novalon-manage-api:${VERSION} \
  -t registry.novalon.cn/novalon-manage-api:latest \
  .

# 推送到镜像仓库
docker push registry.novalon.cn/novalon-manage-api:${VERSION}
docker push registry.novalon.cn/novalon-manage-api:latest
```

#### 部署后端服务

```bash
# 拉取最新镜像
docker pull registry.novalon.cn/novalon-manage-api:latest

# 停止旧容器
docker stop novalon-api
docker rm novalon-api

# 启动新容器
docker run -d \
  --name novalon-api \
  --restart unless-stopped \
  -p 8080:8080 \
  -e SPRING_DATASOURCE_URL=${DB_URL} \
  -e SPRING_DATASOURCE_USERNAME=${DB_USER} \
  -e SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD} \
  -e JWT_SECRET=${JWT_SECRET} \
  -e SPRING_PROFILES_ACTIVE=prod \
  -v /var/log/novalon:/app/logs \
  registry.novalon.cn/novalon-manage-api:latest
```

#### 健康检查

```bash
# 检查服务状态
curl http://localhost:8080/actuator/health

# 预期输出
{
  "status": "UP"
}
```

### 4.4 前端部署

#### 构建生产镜像

```bash
cd novalon-manage-web

# 构建生产镜像
docker build \
  -t registry.novalon.cn/novalon-manage-web:${VERSION} \
  -t registry.novalon.cn/novalon-manage-web:latest \
  .

# 推送到镜像仓库
docker push registry.novalon.cn/novalon-manage-web:${VERSION}
docker push registry.novalon.cn/novalon-manage-web:latest
```

#### Nginx 配置

```nginx
# /etc/nginx/sites-available/novalon-manage
upstream backend {
    server 127.0.0.1:8080;
}

server {
    listen 80;
    server_name api.novalon.cn;

    # 后端 API 代理
    location /api/ {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # WebSocket 代理
    location /ws/ {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # 健康检查
    location /actuator/health {
        proxy_pass http://backend;
        access_log off;
    }
}

server {
    listen 80;
    server_name www.novalon.cn novalon.cn;

    # 前端静态文件
    root /var/www/novalon-manage-web;
    index index.html;

    # SPA 路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_comp_level 6;
}
```

#### 启用站点

```bash
# 创建符号链接
sudo ln -s /etc/nginx/sites-available/novalon-manage /etc/nginx/sites-enabled/

# 测试配置
sudo nginx -t

# 重载 Nginx
sudo systemctl reload nginx
```

### 4.5 HTTPS 配置

#### 使用 Let's Encrypt

```bash
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx -y

# 获取证书
sudo certbot --nginx -d api.novalon.cn -d www.novalon.cn -d novalon.cn

# 自动续期
sudo certbot renew --dry-run
```

## 5. 监控部署

### 5.1 Prometheus 配置

```yaml
# /opt/monitoring/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['localhost:9093']

rule_files:
  - '/opt/monitoring/alerts/*.yml'

scrape_configs:
  - job_name: 'novalon-manage-system'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['localhost:8080']
    relabel_configs:
      - source_labels: [__address__]
        target_label: instance
        replacement: 'novalon-manage-api'
```

### 5.2 Grafana 配置

#### 导入仪表板

1. 访问 Grafana: http://localhost:3000
2. 登录 (admin/admin)
3. 添加 Prometheus 数据源
4. 导入预配置的仪表板

#### 关键指标

| 指标 | 说明 | 告警阈值 |
|------|------|----------|
| jvm_memory_used_bytes | JVM 内存使用 | > 80% |
| http_server_requests_seconds | API 响应时间 | P95 > 500ms |
| hikaricp_connections_active | 数据库连接数 | > 80% |
| cache_gets_total | 缓存命中率 | < 90% |
| system_cpu_usage | CPU 使用率 | > 80% |

## 6. CI/CD 部署

### 6.1 Woodpecker 配置

```yaml
# .woodpecker.yml
pipeline:
  name: Novalon Manage System CI/CD

steps:
  - name: Backend Build
    image: maven:3.9-eclipse-temurin-21
    commands:
      - cd novalon-manage-api
      - mvn clean package -DskipTests

  - name: Backend Test
    image: maven:3.9-eclipse-temurin-21
    commands:
      - cd novalon-manage-api
      - mvn test

  - name: Build Docker Image
    image: docker:dind
    commands:
      - cd novalon-manage-api/manage-sys
      - docker build -t ${REGISTRY}/novalon-manage-api:${CI_COMMIT_SHA:0:8} .

  - name: Push Docker Image
    image: docker:dind
    commands:
      - docker push ${REGISTRY}/novalon-manage-api:${CI_COMMIT_SHA:0:8}

  - name: Deploy to Production
    image: alpine:latest
    commands:
      - ssh ${DEPLOY_USER}@${DEPLOY_HOST} "docker pull ${REGISTRY}/novalon-manage-api:${CI_COMMIT_SHA:0:8} && docker stop novalon-api && docker rm novalon-api && docker run -d --name novalon-api -p 8080:8080 ${REGISTRY}/novalon-manage-api:${CI_COMMIT_SHA:0:8}"
    secrets: [ deploy_ssh_key, deploy_host, deploy_user ]
    when:
      branch: [main]
```

## 7. 运维操作

### 7.1 查看日志

```bash
# 查看应用日志
docker logs -f novalon-api

# 查看数据库日志
docker logs -f novalon-postgres

# 查看所有服务日志
docker-compose logs -f
```

### 7.2 数据库备份

```bash
# 手动备份
docker exec novalon-postgres pg_dump -U postgres manage_system > backup.sql

# 恢复备份
docker exec -i novalon-postgres psql -U postgres manage_system < backup.sql
```

### 7.3 服务重启

```bash
# 重启后端
docker restart novalon-api

# 重启数据库
docker restart novalon-postgres

# 重启所有服务
docker-compose restart
```

### 7.4 查看资源使用

```bash
# 查看容器资源使用
docker stats

# 查看磁盘使用
df -h

# 查看内存使用
free -h
```

## 8. 故障排查

### 8.1 常见问题

| 问题 | 可能原因 | 解决方案 |
|------|----------|----------|
| 数据库连接失败 | 数据库未启动或网络不通 | 检查数据库状态和网络连接 |
| API 请求超时 | 数据库查询慢或资源不足 | 检查慢查询日志和资源使用 |
| 前端无法访问 | Nginx 配置错误 | 检查 Nginx 配置和日志 |
| 内存溢出 | JVM 堆内存不足 | 调整 JVM 参数或增加内存 |

### 8.2 日志分析

```bash
# 查看错误日志
docker logs novalon-api 2>&1 | grep ERROR

# 查看慢查询
docker exec novalon-postgres psql -U postgres -d manage_system -c "SELECT query, mean_exec_time FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10"
```

## 9. 安全加固

### 9.1 网络安全

- 启用 HTTPS
- 配置防火墙规则
- 限制 API 访问频率
- 使用 WAF (Web Application Firewall)

### 9.2 应用安全

- 定期更新依赖
- 运行安全扫描
- 审计日志监控
- 敏感数据加密

### 9.3 数据安全

- 定期备份数据
- 加密备份数据
- 异地备份存储
- 备份恢复演练

## 10. 附录

### 10.1 相关文档

- [系统架构设计](../architecture/system-architecture.md)
- [API 文档](http://localhost:8080/swagger-ui.html)
- [数据库设计](../database/database-schema.md)

### 10.2 联系方式

- 技术支持: support@novalon.cn
- 紧急联系: emergency@novalon.cn
- 文档地址: https://docs.novalon.cn
