Files
schoolNews/build.sh
2025-11-24 11:50:15 +08:00

367 lines
11 KiB
Bash
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
##############################################
# 校园新闻管理系统 - 构建和打包脚本
# 功能:
# 1. 从git拉取最新代码
# 2. 编译后端jar包
# 3. 构建前端dist
# 4. 制作Docker镜像
# 5. 保存镜像到文件(用于离线部署)
##############################################
set -e # 遇到错误立即退出
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
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_ROOT=$(cd "$(dirname "$0")" && pwd)
SERV_PATH="${PROJECT_ROOT}/schoolNewsServ"
WEB_PATH="${PROJECT_ROOT}/schoolNewsWeb"
DOCKER_PATH="${PROJECT_ROOT}/docker"
BUILD_OUTPUT="${PROJECT_ROOT}/build-output"
IMAGE_VERSION=$(date +%Y%m%d_%H%M%S)
echo "=========================================="
echo "校园新闻管理系统 - 构建脚本"
echo "=========================================="
log_info "构建版本: ${IMAGE_VERSION}"
log_info "项目路径: ${PROJECT_ROOT}"
echo "=========================================="
echo ""
# 创建输出目录
mkdir -p "${BUILD_OUTPUT}"
# ================================================
# 步骤1: Git Pull
# ================================================
log_step "步骤1: 拉取最新代码"
cd "${PROJECT_ROOT}"
# 检查是否有未提交的更改
if [[ $(git status --porcelain) ]]; then
log_warn "检测到未提交的更改"
read -p "是否继续拉取代码?(y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
log_error "已取消构建"
exit 1
fi
fi
log_info "从远程仓库拉取代码..."
if git pull origin main 2>/dev/null || git pull origin master 2>/dev/null; then
log_info "代码拉取完成"
else
log_warn "代码拉取失败或已是最新版本,继续构建..."
fi
echo ""
# ================================================
# 步骤2: 构建后端jar包
# ================================================
log_step "步骤2: 构建后端jar包"
cd "${SERV_PATH}"
log_info "清理旧的构建..."
mvn clean -q
log_info "开始编译后端项目..."
log_info "执行: mvn package -DskipTests -pl admin -am"
if mvn package -DskipTests -pl admin -am; then
log_info "后端编译成功"
else
log_error "后端编译失败"
exit 1
fi
# 验证jar包
JAR_FILE="${SERV_PATH}/admin/target/admin-1.0.0.jar"
if [ -f "${JAR_FILE}" ]; then
JAR_SIZE=$(du -h "${JAR_FILE}" | cut -f1)
log_info "✅ jar包已生成: ${JAR_SIZE}"
log_info " 路径: ${JAR_FILE}"
else
log_error "❌ jar包未找到"
exit 1
fi
echo ""
# ================================================
# 步骤3: 构建前端dist
# ================================================
log_step "步骤3: 构建前端项目"
cd "${WEB_PATH}"
# 检查node_modules
if [ ! -d "node_modules" ]; then
log_info "安装前端依赖..."
npm install
fi
log_info "清理旧的构建..."
rm -rf dist
log_info "开始构建前端项目..."
log_info "执行: npm run build"
if npm run build; then
log_info "前端构建成功"
else
log_error "前端构建失败"
exit 1
fi
# 验证dist目录
DIST_DIR="${WEB_PATH}/dist"
if [ -d "${DIST_DIR}" ]; then
DIST_SIZE=$(du -sh "${DIST_DIR}" | cut -f1)
FILE_COUNT=$(find "${DIST_DIR}" -type f | wc -l)
log_info "✅ dist目录已生成: ${DIST_SIZE} (${FILE_COUNT}个文件)"
log_info " 路径: ${DIST_DIR}"
else
log_error "❌ dist目录未找到"
exit 1
fi
echo ""
# ================================================
# 步骤4: 制作Docker镜像
# ================================================
log_step "步骤4: 制作Docker镜像"
cd "${PROJECT_ROOT}"
# 构建MySQL镜像
log_info "构建MySQL镜像包含数据库初始化..."
log_info "执行: docker build -t school-news-mysql:${IMAGE_VERSION} -f docker/Dockerfile.mysql ."
if docker build -t school-news-mysql:${IMAGE_VERSION} -f docker/Dockerfile.mysql .; then
log_info "✅ MySQL镜像构建成功"
docker tag school-news-mysql:${IMAGE_VERSION} school-news-mysql:latest
log_info " 镜像标签: school-news-mysql:${IMAGE_VERSION}"
log_info " 镜像标签: school-news-mysql:latest"
else
log_error "❌ MySQL镜像构建失败"
exit 1
fi
echo ""
# 构建后端镜像
log_info "构建后端镜像..."
log_info "执行: docker build -t school-news-serv:${IMAGE_VERSION} -f docker/Dockerfile.serv ."
if docker build -t school-news-serv:${IMAGE_VERSION} -f docker/Dockerfile.serv .; then
log_info "✅ 后端镜像构建成功"
# 同时打上latest标签
docker tag school-news-serv:${IMAGE_VERSION} school-news-serv:latest
log_info " 镜像标签: school-news-serv:${IMAGE_VERSION}"
log_info " 镜像标签: school-news-serv:latest"
else
log_error "❌ 后端镜像构建失败"
exit 1
fi
echo ""
# 构建前端镜像
log_info "构建前端镜像..."
log_info "执行: docker build -t school-news-web:${IMAGE_VERSION} -f docker/Dockerfile.web ."
if docker build -t school-news-web:${IMAGE_VERSION} -f docker/Dockerfile.web .; then
log_info "✅ 前端镜像构建成功"
# 同时打上latest标签
docker tag school-news-web:${IMAGE_VERSION} school-news-web:latest
log_info " 镜像标签: school-news-web:${IMAGE_VERSION}"
log_info " 镜像标签: school-news-web:latest"
else
log_error "❌ 前端镜像构建失败"
exit 1
fi
echo ""
# 查看镜像信息
log_info "Docker镜像列表:"
docker images | grep -E "school-news-(mysql|serv|web)" | head -10
echo ""
# ================================================
# 步骤5: 保存镜像到文件
# ================================================
log_step "步骤5: 保存Docker镜像"
cd "${BUILD_OUTPUT}"
# 保存MySQL镜像
MYSQL_IMAGE_FILE="school-news-mysql_${IMAGE_VERSION}.tar"
log_info "保存MySQL镜像到文件..."
log_info "执行: docker save -o ${MYSQL_IMAGE_FILE} school-news-mysql:${IMAGE_VERSION}"
if docker save -o "${MYSQL_IMAGE_FILE}" school-news-mysql:${IMAGE_VERSION}; then
MYSQL_SIZE=$(du -h "${MYSQL_IMAGE_FILE}" | cut -f1)
log_info "✅ MySQL镜像已保存: ${MYSQL_SIZE}"
log_info " 文件: ${BUILD_OUTPUT}/${MYSQL_IMAGE_FILE}"
else
log_error "❌ MySQL镜像保存失败"
exit 1
fi
echo ""
# 保存后端镜像
SERV_IMAGE_FILE="school-news-serv_${IMAGE_VERSION}.tar"
log_info "保存后端镜像到文件..."
log_info "执行: docker save -o ${SERV_IMAGE_FILE} school-news-serv:${IMAGE_VERSION}"
if docker save -o "${SERV_IMAGE_FILE}" school-news-serv:${IMAGE_VERSION}; then
SERV_SIZE=$(du -h "${SERV_IMAGE_FILE}" | cut -f1)
log_info "✅ 后端镜像已保存: ${SERV_SIZE}"
log_info " 文件: ${BUILD_OUTPUT}/${SERV_IMAGE_FILE}"
else
log_error "❌ 后端镜像保存失败"
exit 1
fi
echo ""
# 保存前端镜像
WEB_IMAGE_FILE="school-news-web_${IMAGE_VERSION}.tar"
log_info "保存前端镜像到文件..."
log_info "执行: docker save -o ${WEB_IMAGE_FILE} school-news-web:${IMAGE_VERSION}"
if docker save -o "${WEB_IMAGE_FILE}" school-news-web:${IMAGE_VERSION}; then
WEB_SIZE=$(du -h "${WEB_IMAGE_FILE}" | cut -f1)
log_info "✅ 前端镜像已保存: ${WEB_SIZE}"
log_info " 文件: ${BUILD_OUTPUT}/${WEB_IMAGE_FILE}"
else
log_error "❌ 前端镜像保存失败"
exit 1
fi
echo ""
# 压缩镜像文件(可选)
log_info "是否压缩镜像文件?(y/n): "
read -p "" -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
log_info "压缩镜像文件..."
if command -v gzip &> /dev/null; then
log_info "使用gzip压缩..."
gzip -f "${SERV_IMAGE_FILE}"
gzip -f "${WEB_IMAGE_FILE}"
SERV_GZ_SIZE=$(du -h "${SERV_IMAGE_FILE}.gz" | cut -f1)
WEB_GZ_SIZE=$(du -h "${WEB_IMAGE_FILE}.gz" | cut -f1)
log_info "✅ 压缩完成"
log_info " 后端: ${SERV_GZ_SIZE} (${SERV_IMAGE_FILE}.gz)"
log_info " 前端: ${WEB_GZ_SIZE} (${WEB_IMAGE_FILE}.gz)"
else
log_warn "gzip未安装跳过压缩"
fi
fi
echo ""
# ================================================
# 生成部署说明文件
# ================================================
log_info "生成部署说明文件..."
DEPLOY_INFO_FILE="${BUILD_OUTPUT}/部署说明_${IMAGE_VERSION}.txt"
cat > "${DEPLOY_INFO_FILE}" << EOF
========================================
校园新闻管理系统 - Docker镜像部署说明
========================================
构建信息:
构建时间: $(date '+%Y-%m-%d %H:%M:%S')
版本号: ${IMAGE_VERSION}
构建主机: $(hostname)
Git分支: $(git branch --show-current 2>/dev/null || echo "未知")
Git提交: $(git rev-parse --short HEAD 2>/dev/null || echo "未知")
镜像文件:
MySQL镜像: ${MYSQL_IMAGE_FILE}$([ -f "${MYSQL_IMAGE_FILE}.gz" ] && echo ".gz")
后端镜像: ${SERV_IMAGE_FILE}$([ -f "${SERV_IMAGE_FILE}.gz" ] && echo ".gz")
前端镜像: ${WEB_IMAGE_FILE}$([ -f "${WEB_IMAGE_FILE}.gz" ] && echo ".gz")
========================================
部署步骤:
========================================
1. 将镜像文件传输到目标服务器
2. 解压镜像文件(如果已压缩):
gunzip ${SERV_IMAGE_FILE}.gz
gunzip ${WEB_IMAGE_FILE}.gz
3. 加载Docker镜像:
docker load -i ${MYSQL_IMAGE_FILE}
docker load -i ${SERV_IMAGE_FILE}
docker load -i ${WEB_IMAGE_FILE}
4. 验证镜像:
docker images | grep school-news
5. 启动服务:
cd docker
docker-compose up -d
6. 查看服务状态:
docker-compose ps
docker-compose logs -f
========================================
访问地址:
========================================
前端: http://localhost:8080/schoolNewsWeb/
后端: http://localhost:8081/schoolNewsServ
========================================
注意事项:
========================================
1. 确保目标服务器已安装Docker和Docker Compose
2. 确保端口8080、8081、3306、6379未被占用
3. 首次部署需要准备数据库初始化脚本
4. 生产环境请修改默认密码(.env文件
========================================
EOF
log_info "✅ 部署说明已生成: ${DEPLOY_INFO_FILE}"
echo ""
# ================================================
# 构建摘要
# ================================================
echo "=========================================="
echo "构建完成!"
echo "=========================================="
log_info "构建版本: ${IMAGE_VERSION}"
echo ""
log_info "Docker镜像:"
echo " - school-news-mysql:${IMAGE_VERSION}"
echo " - school-news-serv:${IMAGE_VERSION}"
echo " - school-news-web:${IMAGE_VERSION}"
echo ""
log_info "镜像文件保存在: ${BUILD_OUTPUT}/"
ls -lh "${BUILD_OUTPUT}/" | grep -E "(tar|gz|txt)" | awk '{print " - "$9" ("$5")"}'
echo ""
log_info "下一步操作:"
echo " 1. 查看部署说明: cat ${DEPLOY_INFO_FILE}"
echo " 2. 传输镜像文件到目标服务器"
echo " 3. 在目标服务器加载镜像: docker load -i <镜像文件>"
echo " 4. 启动服务: cd docker && docker-compose up -d"
echo "=========================================="