Files
happy-life-star/package.sh
T

773 lines
20 KiB
Bash
Executable File
Raw 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.
#!/bin/bash
# 情绪博物馆项目打包脚本
# 作者: EmotionMuseum Team
# 版本: 2.0.0
# 更新: 适配新的部署脚本和文件结构
set -e
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $1"
}
# 项目信息
PROJECT_NAME="emotion-museum"
VERSION="1.0.0"
BUILD_TIME=$(date +"%Y%m%d_%H%M%S")
PACKAGE_NAME="${PROJECT_NAME}-${VERSION}-${BUILD_TIME}"
# 创建打包目录
PACKAGE_DIR="packages/${PACKAGE_NAME}"
TEMP_DIR="temp_build"
# 清理函数
cleanup() {
log_info "清理临时文件..."
rm -rf "$TEMP_DIR"
}
# 设置清理陷阱
trap cleanup EXIT
# 检查环境
check_environment() {
log_step "检查构建环境..."
# 检查Node.js
if ! command -v node &> /dev/null; then
log_error "Node.js未安装,请先安装Node.js"
exit 1
fi
log_info "Node.js版本: $(node --version)"
# 检查npm
if ! command -v npm &> /dev/null; then
log_error "npm未安装,请先安装npm"
exit 1
fi
log_info "npm版本: $(npm --version)"
# 检查Java
if ! command -v java &> /dev/null; then
log_error "Java未安装,请先安装Java 17+"
exit 1
fi
log_info "Java版本: $(java --version | head -n 1)"
# 检查Maven
if ! command -v mvn &> /dev/null; then
log_error "Maven未安装,请先安装Maven"
exit 1
fi
log_info "Maven版本: $(mvn --version | head -n 1)"
}
# 构建前端
build_frontend() {
log_step "构建前端项目..."
# 检查前端目录
if [ ! -d "web" ]; then
log_warn "web目录不存在,跳过前端构建"
log_info "注意:将使用预构建的前端文件"
return
fi
cd web
# 检查package.json
if [ ! -f "package.json" ]; then
log_warn "package.json不存在,跳过前端构建"
cd ..
return
fi
# 安装依赖
log_info "安装前端依赖..."
npm ci
# 构建生产版本
log_info "构建前端生产版本..."
npm run build:prod || npm run build
# 检查构建结果
if [ ! -d "dist" ]; then
log_error "前端构建失败,dist目录不存在"
exit 1
fi
log_info "前端构建完成"
cd ..
}
# 构建后端
build_backend() {
log_step "构建后端项目..."
# 检查后端目录
if [ ! -d "backend" ]; then
log_warn "backend目录不存在,跳过后端构建"
log_info "注意:将使用预构建的JAR文件"
return
fi
# 检查是否有源码目录结构
if [ ! -f "backend/pom.xml" ]; then
log_warn "backend/pom.xml不存在,跳过后端构建"
log_info "注意:将使用预构建的JAR文件"
return
fi
cd backend
# 清理之前的构建
log_info "清理之前的构建..."
mvn clean
# 编译和打包
log_info "编译和打包后端服务..."
mvn package -DskipTests
# 检查构建结果
local services=("emotion-gateway" "emotion-ai" "emotion-user")
for service in "${services[@]}"; do
if [ ! -f "${service}/target/${service}-${VERSION}.jar" ]; then
log_error "后端服务 ${service} 构建失败"
exit 1
fi
done
log_info "后端构建完成"
cd ..
}
# 创建部署包
create_package() {
log_step "创建部署包..."
# 创建打包目录
mkdir -p "$PACKAGE_DIR"
mkdir -p "$TEMP_DIR"
# 复制前端文件
log_info "打包前端文件..."
mkdir -p "$TEMP_DIR/frontend"
# 如果有构建产物,复制dist目录
if [ -d "web/dist" ]; then
cp -r web/dist/* "$TEMP_DIR/frontend/"
fi
# 复制前端相关文件
if [ -f "web/Dockerfile" ]; then
cp web/Dockerfile "$TEMP_DIR/frontend/"
fi
if [ -f "web/nginx.conf" ]; then
cp web/nginx.conf "$TEMP_DIR/frontend/"
fi
# 复制前端配置文件
mkdir -p "$TEMP_DIR/frontend/config"
cp web/config/* "$TEMP_DIR/frontend/config/" 2>/dev/null || true
cp web/.env* "$TEMP_DIR/frontend/" 2>/dev/null || true
# 如果没有web目录,从packages目录复制预构建的前端文件
if [ ! -d "web" ] && [ -d "packages/emotion-museum-*/frontend" ]; then
log_info "使用预构建的前端文件..."
cp -r packages/emotion-museum-*/frontend/* "$TEMP_DIR/frontend/"
fi
# 复制后端文件
log_info "打包后端文件..."
mkdir -p "$TEMP_DIR/backend"
# 如果有构建产物,复制jar文件
if [ -d "backend" ] && [ -f "backend/pom.xml" ]; then
# 从构建目录复制
cp backend/emotion-gateway/target/emotion-gateway-*.jar "$TEMP_DIR/backend/" 2>/dev/null || true
cp backend/emotion-ai/target/emotion-ai-*.jar "$TEMP_DIR/backend/" 2>/dev/null || true
cp backend/emotion-user/target/emotion-user-*.jar "$TEMP_DIR/backend/" 2>/dev/null || true
# 复制Dockerfile
cp backend/emotion-gateway/Dockerfile "$TEMP_DIR/backend/gateway-Dockerfile" 2>/dev/null || true
cp backend/emotion-ai/Dockerfile "$TEMP_DIR/backend/ai-Dockerfile" 2>/dev/null || true
cp backend/emotion-user/Dockerfile "$TEMP_DIR/backend/user-Dockerfile" 2>/dev/null || true
else
# 从packages目录复制预构建的文件
if [ -d "packages/emotion-museum-*/backend" ]; then
log_info "使用预构建的后端文件..."
cp packages/emotion-museum-*/backend/*.jar "$TEMP_DIR/backend/" 2>/dev/null || true
cp packages/emotion-museum-*/backend/*-Dockerfile "$TEMP_DIR/backend/" 2>/dev/null || true
fi
fi
# 复制配置文件
mkdir -p "$TEMP_DIR/backend/config"
if [ -d "backend" ] && [ -f "backend/pom.xml" ]; then
# 从源码目录复制
cp backend/emotion-gateway/src/main/resources/application*.yml "$TEMP_DIR/backend/config/" 2>/dev/null || true
cp backend/emotion-ai/src/main/resources/application*.yml "$TEMP_DIR/backend/config/" 2>/dev/null || true
cp backend/emotion-user/src/main/resources/application*.yml "$TEMP_DIR/backend/config/" 2>/dev/null || true
else
# 从packages目录复制
if [ -d "packages/emotion-museum-*/backend/config" ]; then
cp packages/emotion-museum-*/backend/config/* "$TEMP_DIR/backend/config/" 2>/dev/null || true
fi
fi
# 复制数据库脚本
log_info "打包数据库脚本..."
mkdir -p "$TEMP_DIR/database"
# 优先从backend目录复制,然后从packages目录复制
if [ -f "backend/mysql_emotion_museum_final.sql" ]; then
cp backend/mysql_emotion_museum_final.sql "$TEMP_DIR/database/"
elif [ -f "packages/emotion-museum-*/database/mysql_emotion_museum_final.sql" ]; then
cp packages/emotion-museum-*/database/mysql_emotion_museum_final.sql "$TEMP_DIR/database/"
fi
if [ -f "backend/verify-database-script.sql" ]; then
cp backend/verify-database-script.sql "$TEMP_DIR/database/"
elif [ -f "packages/emotion-museum-*/database/verify-database-script.sql" ]; then
cp packages/emotion-museum-*/database/verify-database-script.sql "$TEMP_DIR/database/"
fi
# 复制部署配置和脚本
log_info "打包部署配置..."
# 复制部署配置目录
if [ -d "deploy" ]; then
cp -r deploy "$TEMP_DIR/"
elif [ -d "packages/emotion-museum-*/deploy" ]; then
cp -r packages/emotion-museum-*/deploy "$TEMP_DIR/"
fi
# 复制Docker Compose文件
cp docker-compose*.yml "$TEMP_DIR/" 2>/dev/null || true
if [ -d "packages/emotion-museum-*" ]; then
cp packages/emotion-museum-*/docker-compose*.yml "$TEMP_DIR/" 2>/dev/null || true
fi
# 复制部署脚本
local scripts=("deploy.sh" "install-environment.sh" "init-database.sh" "manage.sh")
for script in "${scripts[@]}"; do
if [ -f "$script" ]; then
cp "$script" "$TEMP_DIR/"
elif [ -f "packages/emotion-museum-*/$script" ]; then
cp packages/emotion-museum-*/"$script" "$TEMP_DIR/"
fi
done
# 复制文档文件
local docs=("README.md" "DEPLOY.md" "QUICK_START.md")
for doc in "${docs[@]}"; do
if [ -f "$doc" ]; then
cp "$doc" "$TEMP_DIR/"
elif [ -f "packages/emotion-museum-*/$doc" ]; then
cp packages/emotion-museum-*/"$doc" "$TEMP_DIR/"
fi
done
# 复制环境配置文件
cp .env* "$TEMP_DIR/" 2>/dev/null || true
if [ -d "packages/emotion-museum-*" ]; then
cp packages/emotion-museum-*/.env* "$TEMP_DIR/" 2>/dev/null || true
fi
# 如果没有.env文件,创建一个模板
if [ ! -f "$TEMP_DIR/.env.test" ]; then
echo "# 请配置环境变量" > "$TEMP_DIR/.env.test"
fi
# 创建版本信息文件
create_version_info
# 创建部署说明
create_deploy_instructions
# 移动到最终目录
mv "$TEMP_DIR"/* "$PACKAGE_DIR/"
log_info "部署包创建完成: $PACKAGE_DIR"
}
# 创建版本信息
create_version_info() {
log_info "生成版本信息..."
cat > "$TEMP_DIR/VERSION.txt" << EOF
情绪博物馆 - 版本信息
========================
项目名称: $PROJECT_NAME
版本号: $VERSION
构建时间: $BUILD_TIME
构建环境: $(uname -s) $(uname -m)
前端信息:
- Node.js: $(node --version)
- npm: $(npm --version)
后端信息:
- Java: $(java --version | head -n 1)
- Maven: $(mvn --version | head -n 1)
Git信息:
$(if [ -d ".git" ]; then
echo "- 分支: $(git branch --show-current 2>/dev/null || echo 'unknown')"
echo "- 提交: $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')"
echo "- 时间: $(git log -1 --format=%cd 2>/dev/null || echo 'unknown')"
else
echo "- Git信息不可用"
fi)
文件清单:
- 前端构建产物: frontend/
- 后端JAR文件: backend/
- 数据库脚本: database/
- 部署配置: deploy/
- Docker配置: docker-compose*.yml
- 部署脚本: *.sh
- 说明文档: *.md
EOF
}
# 创建部署说明
create_deploy_instructions() {
log_info "生成部署说明..."
cat > "$TEMP_DIR/QUICK_START.md" << 'EOF'
# 情绪博物馆测试环境快速部署指南
## 📦 包内容说明
```
emotion-museum-1.0.0-YYYYMMDD_HHMMSS/
├── frontend/ # 前端构建产物
│ ├── assets/ # 静态资源
│ ├── index.html # 主页面
│ ├── Dockerfile # 前端容器配置
│ ├── nginx.conf # Nginx配置
│ └── config/ # 前端配置
├── backend/ # 后端JAR文件
│ ├── emotion-gateway-*.jar # 网关服务
│ ├── emotion-ai-*.jar # AI服务
│ ├── emotion-user-*.jar # 用户服务
│ ├── config/ # 配置文件
│ │ ├── application-test.yml
│ │ ├── gateway-test.yml
│ │ └── ai-test.yml
│ ├── gateway-Dockerfile # 网关容器配置
│ ├── ai-Dockerfile # AI服务容器配置
│ └── user-Dockerfile # 用户服务容器配置
├── database/ # 数据库脚本
│ ├── mysql_emotion_museum_final.sql
│ └── verify-database-script.sql
├── deploy/ # 部署配置
│ ├── nginx/conf.d/ # Nginx配置
│ ├── mysql/conf.d/ # MySQL配置
│ └── redis/ # Redis配置
├── docker-compose.yml # 默认配置
├── docker-compose.test.yml # 测试环境配置
├── deploy.sh # 主部署脚本
├── install-environment.sh # 环境安装脚本
├── init-database.sh # 数据库初始化脚本
├── manage.sh # 管理脚本(兼容)
├── .env.test # 测试环境变量
├── README.md # 快速开始指南
├── VERSION.txt # 版本信息
├── DEPLOY.md # 详细部署文档
└── QUICK_START.md # 本文件
```
## 🚀 快速部署步骤
### 1. 系统要求
- **操作系统**: Linux/macOS (推荐 Ubuntu 20.04+)
- **内存**: 最少4GB,推荐8GB+
- **磁盘**: 最少20GB可用空间
- **网络**: 能够访问互联网
### 2. 部署步骤
#### 方式一:一键部署(推荐)
```bash
# 1. 解压部署包
tar -xzf emotion-museum-*.tar.gz
cd emotion-museum-*
# 2. 配置环境变量(重要)
vim .env.test
# 修改 SERVER_IP 为实际IP
# 配置 COZE_API_TOKEN
# 3. 一键部署(包含环境安装、数据库初始化、服务部署)
chmod +x deploy.sh
./deploy.sh
```
#### 方式二:分步部署
```bash
# 1. 解压部署包
tar -xzf emotion-museum-*.tar.gz
cd emotion-museum-*
# 2. 配置环境变量
vim .env.test
# 3. 分步部署
chmod +x deploy.sh
./deploy.sh install-env # 安装环境
./deploy.sh init-db # 初始化数据库
./deploy.sh build # 构建镜像
./deploy.sh start # 启动服务
```
#### 方式三:跳过某些步骤
```bash
# 如果已安装环境,跳过环境安装
./deploy.sh --skip-env
# 如果已初始化数据库,跳过数据库初始化
./deploy.sh --skip-db
# 启用调试模式
./deploy.sh --debug
```
### 3. 验证部署
```bash
# 查看服务状态
./deploy.sh status
# 健康检查
./deploy.sh health
# 查看日志
./deploy.sh logs
```
### 4. 访问应用
- **前端应用**: http://localhost (或 http://your-server-ip)
- **API网关**: http://localhost:9000
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
## ⚙️ 配置说明
### 必须配置项
编辑 `.env.test` 文件中的以下配置:
```bash
# 服务器IP(重要:修改为实际IP)
SERVER_IP=your-server-ip
# Coze API配置(必须)
COZE_API_TOKEN=your-actual-coze-api-token
# 数据库密码(建议修改)
MYSQL_ROOT_PASSWORD=your-secure-password
MYSQL_PASSWORD=your-secure-password
# JWT密钥(建议修改)
JWT_SECRET=your-production-jwt-secret-key
```
### 可选配置项
```bash
# 时区设置
TZ=Asia/Shanghai
# 端口配置
GATEWAY_PORT=9000
USER_SERVICE_PORT=9001
AI_SERVICE_PORT=9002
# 日志和存储路径
LOG_PATH=/data/logs/emotion-museum
UPLOAD_PATH=/data/uploads/emotion-museum
```
## 🛠️ 管理命令
```bash
# 主要部署命令
./deploy.sh # 完整部署
./deploy.sh start # 启动服务
./deploy.sh stop # 停止服务
./deploy.sh restart # 重启服务
./deploy.sh status # 查看状态
# 日志管理
./deploy.sh logs # 查看所有日志
./deploy.sh logs -f # 跟踪日志
./deploy.sh logs gateway # 查看网关日志
./deploy.sh logs ai-service # 查看AI服务日志
# 数据管理
./deploy.sh backup # 备份数据
./deploy.sh health # 健康检查
./deploy.sh clean # 清理资源
# 独立脚本
./install-environment.sh # 安装环境
./init-database.sh # 初始化数据库
# 兼容命令(旧版本)
./manage.sh start # 启动服务
./manage.sh status # 查看状态
```
## 🔧 生产环境配置
### 1. 使用生产配置
```bash
# 使用生产环境配置
docker-compose -f docker-compose.prod.yml up -d
```
### 2. 配置HTTPS
```bash
# 1. 放置SSL证书
cp your-domain.crt deploy/nginx/ssl/emotion-museum.crt
cp your-domain.key deploy/nginx/ssl/emotion-museum.key
# 2. 修改Nginx配置
vim deploy/nginx/conf.d/emotion-museum.conf
# 取消HTTPS相关配置的注释
# 3. 重启Nginx
docker-compose restart nginx
```
### 3. 配置域名
```bash
# 修改Nginx配置中的域名
vim deploy/nginx/conf.d/emotion-museum.conf
# 将 localhost 替换为您的域名
```
## 🚨 故障排除
### 常见问题
1. **环境安装失败**
```bash
# 检查系统要求
./install-environment.sh verify
# 手动安装特定组件
./install-environment.sh docker
```
2. **端口冲突**
```bash
# 检查端口占用
netstat -tlnp | grep :80
netstat -tlnp | grep :3306
# 修改 .env.test 中的端口配置
```
3. **数据库初始化失败**
```bash
# 查看MySQL容器日志
docker logs emotion-mysql
# 重新初始化
./init-database.sh clean
./init-database.sh
```
4. **服务启动失败**
```bash
# 查看服务日志
./deploy.sh logs service-name
# 查看容器状态
docker ps -a
```
5. **网络连接问题**
```bash
# 检查Docker网络
docker network ls
# 健康检查
./deploy.sh health
```
### 获取帮助
- 查看详细文档: `cat DEPLOY.md`
- 查看快速指南: `cat README.md`
- 查看版本信息: `cat VERSION.txt`
- 查看部署命令: `./deploy.sh --help`
## 📞 技术支持
如遇到问题,请按以下步骤排查:
1. **查看详细日志**`./deploy.sh logs --debug`
2. **检查服务状态**`./deploy.sh status`
3. **验证配置文件**:检查 `.env.test` 配置
4. **查看详细文档**`DEPLOY.md`
5. **重新部署**`./deploy.sh clean && ./deploy.sh`
## 📝 重要提醒
- ⚠️ **首次部署**:请务必修改 `.env.test` 中的 `SERVER_IP` 和 `COZE_API_TOKEN`
- ⚠️ **生产环境**:请修改所有默认密码和密钥
- ⚠️ **防火墙**:确保开放必要的端口 (80, 3306, 6379, 8848, 9000-9002)
---
**部署完成后,请及时修改默认密码和敏感配置!**
EOF
}
# 压缩打包
compress_package() {
log_step "压缩部署包..."
cd packages
tar -czf "${PACKAGE_NAME}.tar.gz" "$PACKAGE_NAME"
# 计算文件大小和校验和
local size=$(du -h "${PACKAGE_NAME}.tar.gz" | cut -f1)
local checksum=$(sha256sum "${PACKAGE_NAME}.tar.gz" | cut -d' ' -f1)
log_info "压缩完成:"
log_info " 文件: packages/${PACKAGE_NAME}.tar.gz"
log_info " 大小: $size"
log_info " 校验: $checksum"
# 创建校验文件
echo "$checksum ${PACKAGE_NAME}.tar.gz" > "${PACKAGE_NAME}.sha256"
cd ..
}
# 生成部署报告
generate_report() {
log_step "生成部署报告..."
local report_file="packages/${PACKAGE_NAME}_REPORT.txt"
cat > "$report_file" << EOF
情绪博物馆部署包报告
==================
构建信息:
- 包名称: ${PACKAGE_NAME}.tar.gz
- 构建时间: $BUILD_TIME
- 构建环境: $(uname -s) $(uname -m)
包内容:
- 前端构建产物 ✓
- 后端JAR文件 ✓
- 数据库脚本 ✓
- 部署配置 ✓
- Docker配置 ✓
- 管理脚本 ✓
- 说明文档 ✓
文件信息:
- 压缩包大小: $(du -h "packages/${PACKAGE_NAME}.tar.gz" | cut -f1)
- SHA256校验: $(cat "packages/${PACKAGE_NAME}.sha256" | cut -d' ' -f1)
部署要求:
- Docker 20.10+
- Docker Compose 1.29+
- 内存: 4GB+
- 磁盘: 10GB+
快速部署:
1. 解压: tar -xzf ${PACKAGE_NAME}.tar.gz
2. 进入: cd ${PACKAGE_NAME}
3. 配置: vim .env
4. 部署: ./quick-deploy.sh
注意事项:
- 请配置正确的Coze API Token
- 生产环境请修改默认密码
- 建议配置HTTPS证书
- 确保防火墙开放必要端口
技术支持:
- 详细文档: DEPLOY.md
- 快速指南: QUICK_START.md
- 管理命令: ./manage.sh --help
EOF
log_info "部署报告已生成: $report_file"
}
# 主函数
main() {
echo "📦 开始打包情绪博物馆项目..."
echo ""
check_environment
build_frontend
build_backend
create_package
compress_package
generate_report
echo ""
log_info "🎉 打包完成!"
echo ""
echo "📁 部署包位置:"
echo " packages/${PACKAGE_NAME}.tar.gz"
echo ""
echo "📋 部署步骤:"
echo " 1. 将压缩包上传到服务器"
echo " 2. 解压: tar -xzf ${PACKAGE_NAME}.tar.gz"
echo " 3. 进入目录: cd ${PACKAGE_NAME}"
echo " 4. 配置环境: vim .env"
echo " 5. 快速部署: ./quick-deploy.sh"
echo ""
echo "📖 详细说明请查看包内的 QUICK_START.md 文件"
echo ""
}
# 处理命令行参数
case "${1:-}" in
"frontend")
check_environment
build_frontend
;;
"backend")
check_environment
build_backend
;;
"clean")
log_info "清理构建文件..."
rm -rf packages temp_build
rm -rf web/dist web/node_modules
cd backend && mvn clean && cd ..
log_info "清理完成"
;;
*)
main
;;
esac