272 lines
6.4 KiB
Markdown
272 lines
6.4 KiB
Markdown
# QAUP 极简离线部署方案
|
||
Spring Boot + Redis + PostgreSQL(一键部署、一键升级)
|
||
|
||
## 1. 设计原则
|
||
|
||
- **极简优先**:最少的文件,最少的步骤
|
||
- **离线部署**:预打包所有依赖,无需联网
|
||
- **一键操作**:部署和升级都是一条命令
|
||
- **配置灵活**:关键配置可外部修改
|
||
|
||
## 2. 打包准备(开发环境执行一次)
|
||
|
||
### 2.1 打包脚本(package.sh)
|
||
```bash
|
||
#!/bin/bash
|
||
echo "=== QAUP 打包脚本 ==="
|
||
|
||
# 1. 构建应用
|
||
mvn clean package -DskipTests
|
||
|
||
# 2. 拉取并导出镜像
|
||
docker pull openjdk:21-jre-alpine
|
||
docker pull redis:8-alpine
|
||
docker pull postgres:17-3.5-alpine
|
||
docker save openjdk:21-jre-alpine redis:8-alpine postgres:17-3.5-alpine | gzip > images.tar.gz
|
||
|
||
# 3. 准备部署包
|
||
mkdir -p qaup-deploy
|
||
cp qaup-admin/target/qaup-admin.jar qaup-deploy/app.jar
|
||
cp deploy/simple/* qaup-deploy/
|
||
cp images.tar.gz qaup-deploy/
|
||
|
||
# 4. 打包
|
||
cd qaup-deploy && zip -r ../qaup-deploy-$(date +%Y%m%d).zip .
|
||
echo "打包完成: qaup-deploy-$(date +%Y%m%d).zip"
|
||
```
|
||
|
||
### 2.2 部署包结构(极简版)
|
||
```
|
||
qaup-deploy.zip
|
||
├── images.tar.gz # Docker镜像包
|
||
├── docker-compose.yml # 服务编排
|
||
├── app.jar # 应用程序
|
||
├── config.yml # 外部配置(可修改)
|
||
├── init.sql # 数据库初始化脚本
|
||
├── deploy.sh # 一键部署
|
||
└── update.sh # 一键升级
|
||
```
|
||
|
||
## 3. docker-compose.yml(极简版)
|
||
```yaml
|
||
services:
|
||
app:
|
||
image: openjdk:21-jre-alpine
|
||
container_name: qaup-app
|
||
restart: always
|
||
ports:
|
||
- "8080:8080"
|
||
volumes:
|
||
- ./app.jar:/app.jar
|
||
- ./config.yml:/config.yml
|
||
command: ["java", "-jar", "/app.jar", "--spring.config.location=/config.yml"]
|
||
depends_on:
|
||
- db
|
||
- redis
|
||
|
||
redis:
|
||
image: redis:8-alpine
|
||
container_name: qaup-redis
|
||
restart: always
|
||
command: ["redis-server", "--maxmemory", "256mb", "--maxmemory-policy", "allkeys-lru"]
|
||
|
||
db:
|
||
image: postgres:17-3.5-alpine
|
||
container_name: qaup-db
|
||
restart: always
|
||
environment:
|
||
POSTGRES_DB: qaup
|
||
POSTGRES_USER: qaup
|
||
POSTGRES_PASSWORD: qaup123
|
||
volumes:
|
||
- ./data:/var/lib/postgresql/data
|
||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||
```
|
||
|
||
## 4. 外部配置文件(config.yml)
|
||
```yaml
|
||
# 服务器配置
|
||
server:
|
||
port: 8080
|
||
|
||
# 数据库配置
|
||
spring:
|
||
datasource:
|
||
url: jdbc:postgresql://qaup-db:5432/qaup
|
||
username: qaup
|
||
password: qaup123
|
||
driver-class-name: org.postgresql.Driver
|
||
|
||
# Redis配置
|
||
data:
|
||
redis:
|
||
host: qaup-redis
|
||
port: 6379
|
||
database: 0
|
||
|
||
# 应用配置
|
||
qaup:
|
||
# 文件上传路径
|
||
profile: /tmp/uploads
|
||
# 外部接口配置(客户可修改)
|
||
external:
|
||
api-host: 192.168.1.100
|
||
api-port: 8090
|
||
|
||
# 日志配置(简化)
|
||
logging:
|
||
level:
|
||
com.qaup: info
|
||
pattern:
|
||
console: "%d{HH:mm:ss} %-5level %logger{36} - %msg%n"
|
||
```
|
||
|
||
## 5. 数据库初始化(init.sql)
|
||
```sql
|
||
-- 创建基础表结构
|
||
CREATE TABLE IF NOT EXISTS sys_user (
|
||
user_id SERIAL PRIMARY KEY,
|
||
user_name VARCHAR(30) NOT NULL,
|
||
nick_name VARCHAR(30) NOT NULL,
|
||
password VARCHAR(100) DEFAULT '',
|
||
status CHAR(1) DEFAULT '0',
|
||
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
-- 插入默认管理员
|
||
INSERT INTO sys_user (user_name, nick_name, password)
|
||
VALUES ('admin', '管理员', '$2a$10$7JB720yubVSOfvam/RtmyO4wV/hOoLsKpHpJI.VqSb/VXaVzqQqhu')
|
||
ON CONFLICT DO NOTHING;
|
||
|
||
-- 其他标准数据...
|
||
```
|
||
|
||
## 6. 一键部署(deploy.sh)
|
||
```bash
|
||
#!/bin/bash
|
||
echo "=== QAUP 一键部署 ==="
|
||
|
||
# 载入镜像
|
||
echo "载入Docker镜像..."
|
||
docker load -i images.tar.gz
|
||
|
||
# 创建数据目录
|
||
mkdir -p data
|
||
|
||
# 启动服务
|
||
echo "启动服务..."
|
||
docker compose up -d
|
||
|
||
# 等待启动
|
||
echo "等待服务启动(30秒)..."
|
||
sleep 30
|
||
|
||
echo "✅ 部署完成!访问: http://localhost:8080"
|
||
echo "默认账号: admin / admin123"
|
||
```
|
||
|
||
## 7. 客户部署(1条命令)
|
||
```bash
|
||
unzip qaup-deploy.zip && cd qaup-deploy && ./deploy.sh
|
||
```
|
||
|
||
## 8. 一键升级(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"
|
||
fi
|
||
|
||
# 备份当前版本
|
||
cp app.jar app.jar.backup
|
||
echo "已备份当前版本"
|
||
|
||
# 停止应用
|
||
echo "停止应用服务..."
|
||
docker compose stop app
|
||
|
||
# 替换应用
|
||
cp new-app.jar app.jar
|
||
echo "已更新应用文件"
|
||
|
||
# 启动应用
|
||
echo "启动应用服务..."
|
||
docker compose start app
|
||
|
||
# 等待启动
|
||
echo "等待服务启动(30秒)..."
|
||
sleep 30
|
||
|
||
echo "✅ 升级完成!"
|
||
echo "如有问题,可执行回滚: cp app.jar.backup app.jar && docker compose restart app"
|
||
```
|
||
|
||
## 9. Java版本兼容性注意事项
|
||
|
||
### 9.1 编译与运行环境匹配
|
||
- **编译环境**: 确保项目在Java 21环境下编译
|
||
- **运行环境**: Docker镜像必须与编译版本匹配(`openjdk:21-jre-alpine` 或 `eclipse-temurin:21-jre`)
|
||
|
||
### 9.2 常见版本错误
|
||
如果遇到 `UnsupportedClassVersionError`,确认以下配置:
|
||
```yaml
|
||
# docker-compose.yml 中必须使用Java 21镜像
|
||
services:
|
||
app:
|
||
# 错误示例(可能导致版本不匹配)
|
||
# image: openjdk:17-jre-alpine
|
||
|
||
# 正确示例
|
||
image: openjdk:21-jre-alpine
|
||
```
|
||
|
||
### 9.3 版本验证命令
|
||
```bash
|
||
# 检查容器中Java版本
|
||
docker exec <container-name> java -version
|
||
|
||
# 检查jar文件编译版本
|
||
javap -cp <jar-file> -version <main-class>
|
||
```
|
||
## 9. 操作总结
|
||
|
||
### 开发环境(一次性)
|
||
```bash
|
||
./package.sh # 打包部署文件
|
||
```
|
||
|
||
### 客户环境
|
||
```bash
|
||
# 首次部署
|
||
unzip qaup-deploy.zip && cd qaup-deploy && ./deploy.sh
|
||
|
||
# 日常升级
|
||
./update.sh
|
||
|
||
# 查看状态
|
||
docker compose ps
|
||
|
||
# 查看日志
|
||
docker compose logs -f app
|
||
```
|
||
|
||
## 10. 优势总结
|
||
|
||
✅ **极简部署**:解压 → 运行脚本,2步完成
|
||
✅ **极简升级**:替换jar → 运行脚本,自动完成
|
||
✅ **离线友好**:所有依赖预打包,无需联网
|
||
✅ **配置灵活**:关键配置外部文件,可随时修改
|
||
✅ **自动初始化**:数据库结构和标准数据自动创建
|
||
✅ **一键回滚**:升级失败可快速回滚到上一版本
|