镜像制作

This commit is contained in:
2025-11-24 11:50:15 +08:00
parent 12592c5a24
commit 07bd166257
53 changed files with 3822 additions and 2140 deletions

367
build.sh Normal file
View File

@@ -0,0 +1,367 @@
#!/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 "=========================================="