QDAirPortBackend0122/doc/deploy/deploy-design.md
2026-01-22 13:19:47 +08:00

462 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# QAUP 极简离线部署方案
Spring Boot + Redis + PostgreSQL with PostGIS一键部署、一键升级
## 1. 设计原则
- **极简优先**:最少的文件,最少的步骤
- **离线部署**:预打包所有依赖,无需联网
- **一键操作**:部署和升级都是一条命令
- **配置灵活**:关键配置可外部修改
- **自动化迁移**数据库版本自动管理Flyway
## 2. 打包准备(开发环境执行一次)
### 2.1 打包脚本package-all.sh
```bash
#!/bin/bash
echo "=== QAUP 打包脚本 ==="
# 1. 构建应用在macOS上
mvn clean package -DskipTests
# 2. 拉取并导出镜像(在服务器上)
docker pull m.daocloud.io/docker.io/postgis/postgis:17-3.5-alpine
docker pull m.daocloud.io/docker.io/library/redis:8.0-alpine
docker pull m.daocloud.io/docker.io/library/eclipse-temurin:21-jre
# 导出镜像
docker save m.daocloud.io/docker.io/postgis/postgis:17-3.5-alpine \
m.daocloud.io/docker.io/library/redis:8.0-alpine \
m.daocloud.io/docker.io/library/eclipse-temurin:21-jre | gzip > images.tar.gz
# 3. 准备部署包
mkdir -p qaup-deploy
cp qaup-admin/target/qaup-admin.jar qaup-deploy/app.jar
cp deploy/docker-compose.yml qaup-deploy/
cp deploy/config.yml qaup-deploy/
cp images.tar.gz qaup-deploy/
# 4. 打包
tar -czf qaup-deploy-$(date +%Y%m%d-%H%M%S).tar.gz -C qaup-deploy .
echo "打包完成: qaup-deploy-$(date +%Y%m%d-%H%M%S).tar.gz"
```
### 2.2 部署包结构
```
qaup-deploy.tar.gz
├── images.tar.gz # Docker镜像包PostGIS + Redis + Java21
├── docker-compose.yml # 服务编排(包含健康检查)
├── app.jar # 应用程序
├── config.yml # 外部配置(可修改)
├── deploy-all.sh # 一键部署脚本
├── deploy-update.sh # 一键升级脚本
├── DeployGuide.md # 详细部署指南
└── qaup_database_export.sql # 完整数据库备份(可选)
```
## 3. docker-compose.yml当前实际版本
```yaml
services:
# PostgreSQL + PostGIS 数据库服务
qaup-postgres:
image: m.daocloud.io/docker.io/postgis/postgis:17-3.5-alpine
container_name: qaup-postgres
restart: unless-stopped
environment:
POSTGRES_DB: qaup
POSTGRES_USER: qaup
POSTGRES_PASSWORD: qaup123
volumes:
- ./data/postgres:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U qaup"]
interval: 30s
timeout: 10s
retries: 3
# Redis 缓存服务
qaup-redis:
image: m.daocloud.io/docker.io/library/redis:8.0-alpine
container_name: qaup-redis
restart: unless-stopped
command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
volumes:
- ./data/redis:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 30s
timeout: 10s
retries: 3
# QAUP 应用服务Java 21
qaup-app:
image: m.daocloud.io/docker.io/library/eclipse-temurin:21-jre
container_name: qaup-app
restart: unless-stopped
environment:
SPRING_PROFILES_ACTIVE: prod
LOG_PATH: /app/logs
# 数据库连接配置
DB_HOST: qaup-postgres
DB_PORT: 5432
DB_NAME: qaup
DB_USER: qaup
DB_PASSWORD: qaup123
# Flyway配置自动化数据库迁移
SPRING_FLYWAY_ENABLED: true
SPRING_FLYWAY_BASELINE_ON_MIGRATE: true
SPRING_FLYWAY_VALIDATE_ON_MIGRATE: true
SPRING_FLYWAY_CLEAN_DISABLED: true
volumes:
- ./app.jar:/app/app.jar
- ./config.yml:/app/config.yml
- ./logs:/app/logs
- ./backup:/app/backup
ports:
- "8080:8080"
depends_on:
qaup-postgres:
condition: service_healthy
qaup-redis:
condition: service_healthy
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 120s
command: [
"sh", "-c",
"echo 'Waiting for database to be ready...' &&
sleep 10 &&
echo 'Starting QAUP application with Flyway migration...' &&
java -jar /app/app.jar --spring.config.location=/app/config.yml"
]
networks:
default:
name: qaup-network
```
## 4. 外部配置文件config.yml
```yaml
# 服务器配置
server:
port: 8080
# 应用配置
qaup:
# 文件上传路径
profile: /tmp/uploads
# 外部接口配置(客户可修改)
external:
api-host: 192.168.1.100
api-port: 8090
# 日志配置
logging:
level:
com.qaup: INFO
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"
file:
name: /app/logs/qaup.log
# 注意数据库和Redis配置通过环境变量设置
```
## 5. 自动化数据库迁移Flyway
### 5.1 迁移脚本位置
```
qaup-admin/src/main/resources/db/migration/
├── V1.0.0__Initial_baseline.sql # 数据库基线结构86KB
├── V1.0.1__Initial_data.sql # 初始数据50KB
└── README.md # 迁移脚本编写规范
```
### 5.2 自动迁移机制
- **应用启动时自动执行**无需手动运行SQL脚本
- **版本控制**:所有迁移按版本顺序执行
- **幂等性**:安全重复执行,不会重复创建对象
- **健康检查**:依赖数据库健康状态启动应用
### 5.3 迁移状态查询
```bash
# 查看应用日志中的迁移信息
docker compose logs qaup-app | grep -i flyway
# 直接查询数据库
docker exec -it qaup-postgres psql -U qaup -d qaup -c "SELECT * FROM flyway_schema_history ORDER BY installed_rank;"
```
## 6. 一键部署deploy-all.sh
```bash
#!/bin/bash
echo "=== QAUP 一键部署 ==="
# 检查Docker
if ! command -v docker &> /dev/null; then
echo "❌ Docker 未安装"
exit 1
fi
# 载入镜像
echo "载入Docker镜像..."
docker load -i images.tar.gz
# 创建数据目录
echo "创建数据目录..."
mkdir -p data/postgres data/redis logs
# 启动服务
echo "启动服务..."
docker compose up -d
# 等待服务启动
echo "等待服务启动60秒..."
sleep 60
# 检查服务状态
if curl -f -s http://localhost:8080/actuator/health > /dev/null 2>&1; then
echo "✅ 部署成功!"
echo ""
echo "访问地址: http://localhost:8080"
echo "数据库: localhost:5432 (qaup/qaup123)"
echo "Redis: localhost:6379"
echo ""
echo "管理命令:"
echo " 查看状态: docker compose ps"
echo " 查看日志: docker compose logs -f qaup-app"
echo " 停止服务: docker compose down"
echo " 升级应用: ./deploy-update.sh"
else
echo "❌ 服务启动失败,请检查日志:"
docker compose logs
fi
```
## 7. 客户部署1条命令
```bash
tar -xzf qaup-deploy.tar.gz && cd qaup-deploy && ./deploy-all.sh
```
## 8. 一键升级deploy-update.sh
```bash
#!/bin/bash
echo "=== QAUP 一键升级 ==="
# 检查新版本文件
if [ ! -f "new-app.jar" ]; then
echo "❌ 请先将新版本文件重命名为 new-app.jar"
exit 1
fi
# 验证Java版本兼容性重要确保jar与容器Java版本匹配
echo "验证Java版本兼容性..."
if command -v java &> /dev/null; then
LOCAL_JAVA_VERSION=$(java -version 2>&1 | head -1 | cut -d'"' -f2 | sed 's/[^0-9.]*\([0-9.]*\).*/\1/')
echo "本地Java版本: $LOCAL_JAVA_VERSION"
echo "容器Java版本: eclipse-temurin:21-jre"
fi
# 备份当前版本
echo "备份当前版本..."
cp app.jar app.jar.backup.$(date +%Y%m%d_%H%M%S)
# 数据库备份(重要)
echo "备份数据库..."
docker exec qaup-postgres pg_dump -U qaup qaup > backup/qaup-backup-$(date +%Y%m%d_%H%M%S).sql
# 停止应用(不影响数据库)
echo "停止应用服务..."
docker compose stop qaup-app
# 替换应用
cp new-app.jar app.jar
echo "已更新应用文件"
# 启动应用Flyway自动处理数据库迁移
echo "启动应用服务..."
docker compose start qaup-app
# 等待启动和迁移完成
echo "等待应用启动和数据库迁移120秒..."
sleep 120
# 检查升级结果
if curl -f -s http://localhost:8080/actuator/health > /dev/null 2>&1; then
echo "✅ 升级成功!"
echo ""
echo "Flyway迁移状态:"
docker exec -it qaup-postgres psql -U qaup -d qaup -c "SELECT version, description, installed_rank FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 5;"
else
echo "❌ 升级失败,开始回滚..."
# 恢复jar文件
LATEST_BACKUP=$(ls -t app.jar.backup.* 2>/dev/null | head -1)
if [ -n "$LATEST_BACKUP" ]; then
cp "$LATEST_BACKUP" app.jar
docker compose restart qaup-app
echo "✅ 已回滚到版本: $LATEST_BACKUP"
else
echo "❌ 未找到备份文件,请手动处理"
fi
fi
```
## 9. Java版本兼容性注意事项
### 9.1 编译与运行环境匹配
- **编译环境**: 确保项目在Java 21环境下编译
- **运行环境**: Docker镜像使用 `eclipse-temurin:21-jre`
### 9.2 常见版本错误
如果遇到 `UnsupportedClassVersionError`,确认以下配置:
```yaml
# docker-compose.yml 中必须使用Java 21镜像
services:
qaup-app:
# 正确示例
image: m.daocloud.io/docker.io/library/eclipse-temurin:21-jre
```
### 9.3 版本验证命令
```bash
# 检查容器中Java版本
docker exec qaup-app java -version
# 检查jar文件编译版本
javap -cp app.jar -version
# 快速健康检查
curl http://localhost:8080/actuator/health
```
## 10. 系统维护操作
### 10.1 日常运维命令
```bash
# 查看服务状态
docker compose ps
# 查看应用日志
docker compose logs -f qaup-app
# 查看数据库日志
docker compose logs qaup-postgres
# 查看Redis日志
docker compose logs qaup-redis
# 查看系统资源使用
docker stats
# 数据库连接测试
docker exec -it qaup-postgres psql -U qaup -d qaup -c "SELECT version();"
# Redis连接测试
docker exec -it qaup-redis redis-cli ping
```
### 10.2 监控数据库迁移状态
```bash
# 查看Flyway迁移历史
docker exec -it qaup-postgres psql -U qaup -d qaup -c "SELECT * FROM flyway_schema_history ORDER BY installed_rank;"
# 查看应用日志中的迁移信息
docker compose logs qaup-app | grep -i flyway
# 查看最近的迁移记录
docker exec -it qaup-postgres psql -U qaup -d qaup -c "SELECT version, description, installed_on FROM flyway_schema_history ORDER BY installed_rank DESC LIMIT 3;"
```
### 10.3 数据备份和恢复
```bash
# 手动备份数据库
docker exec qaup-postgres pg_dump -U qaup qaup > backup/manual-backup-$(date +%Y%m%d_%H%M%S).sql
# 恢复数据库(需要停止应用)
docker compose stop qaup-app
docker exec -i qaup-postgres psql -U qaup qaup < backup/qaup-backup-20250120_143000.sql
docker compose start qaup-app
```
### 10.4 完全重置(开发测试用)
```bash
# 停止所有服务
docker compose down
# 删除数据目录(⚠️ 注意:这会删除所有数据)
rm -rf data/
# 重新部署
./deploy-all.sh
```
## 11. 操作总结
### 开发环境(一次性)
```bash
# 在macOS上构建
mvn clean package -DskipTests
./deploy/package-all.sh
# 或在服务器上打包
./deploy/package-all.sh
```
### 客户环境
```bash
# 首次部署
tar -xzf qaup-deploy.tar.gz && cd qaup-deploy && ./deploy-all.sh
# 程序更新
# 1. 复制新jar文件并重命名为 new-app.jar
# 2. 执行更新
./deploy-update.sh
# 查看状态
docker compose ps
# 查看日志
docker compose logs -f qaup-app
```
## 12. 现代化优势总结
**极简部署**:解压 → 运行脚本2步完成
**极简升级**替换jar → 运行脚本,自动完成
**离线友好**:所有依赖预打包,无需联网
**配置灵活**:关键配置外部文件,可随时修改
**自动化迁移**Flyway自动处理数据库版本管理
**健康检查**:服务依赖和健康状态监控
**PostGIS支持**:内置地理空间数据库能力
**一键回滚**:升级失败可快速回滚到上一版本
**零停机升级**:只重启应用服务,数据库保持运行
**版本兼容**Java 21运行时确保版本一致性