Files
novalon-manage-system/docs/deployment/deployment-guide.md
T

15 KiB

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

# 使用 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

初始化数据库

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

2.2 后端部署

配置环境变量

# 创建 .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

启动后端服务

cd novalon-manage-api/manage-app

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

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

验证后端服务

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

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

2.3 前端部署

安装依赖

cd novalon-manage-web

# 使用 npm
npm install

# 或使用 pnpm (更快)
pnpm install

配置 API 地址

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

启动前端服务

# 开发模式
npm run dev

# 生产构建
npm run build

验证前端服务

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

3. Docker 容器化部署

3.1 构建镜像

网关镜像

cd novalon-manage-api/manage-gateway

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

# 查看镜像
docker images | grep novalon

应用镜像

cd novalon-manage-api/manage-app

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

# 查看镜像
docker images | grep novalon

前端镜像

cd novalon-manage-web

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

# 查看镜像
docker images | grep novalon

3.2 Docker Compose 部署

创建 docker-compose.yml

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:

启动服务

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

# 查看日志
docker-compose logs -f

# 停止服务
docker-compose down

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

4. 生产环境部署

4.1 服务器准备

系统配置

# 更新系统
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

防火墙配置

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

4.2 数据库部署

生产数据库配置

# 使用生产级配置
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

数据库备份

# 创建备份脚本
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 后端部署

构建生产镜像

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

部署后端服务

# 拉取最新镜像
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

健康检查

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

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

4.4 前端部署

构建生产镜像

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 配置

# /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;
}

启用站点

# 创建符号链接
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

# 安装 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 配置

# /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 配置

# .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 查看日志

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

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

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

7.2 数据库备份

# 手动备份
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 服务重启

# 重启后端
docker restart novalon-api

# 重启数据库
docker restart novalon-postgres

# 重启所有服务
docker-compose restart

7.4 查看资源使用

# 查看容器资源使用
docker stats

# 查看磁盘使用
df -h

# 查看内存使用
free -h

8. 故障排查

8.1 常见问题

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

8.2 日志分析

# 查看错误日志
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 相关文档

10.2 联系方式