基础镜像创建
This commit is contained in:
589
build.sh
589
build.sh
@@ -6,8 +6,35 @@
|
||||
# 1. 从git拉取最新代码
|
||||
# 2. 编译后端jar包
|
||||
# 3. 构建前端dist
|
||||
# 4. 制作Docker镜像
|
||||
# 4. 制作Docker镜像(支持基础镜像和应用镜像)
|
||||
# 5. 保存镜像到文件(用于离线部署)
|
||||
#
|
||||
# 使用方法:
|
||||
# ./build.sh [target] [options] [version]
|
||||
#
|
||||
# 目标(target):
|
||||
# base-serv - 构建后端基础镜像(包含Python依赖)
|
||||
# base-web - 构建前端基础镜像(Nginx)
|
||||
# base-all - 构建所有基础镜像
|
||||
# serv - 构建后端服务镜像
|
||||
# web - 构建前端服务镜像
|
||||
# mysql - 构建MySQL镜像
|
||||
# all - 构建所有应用镜像(默认)
|
||||
#
|
||||
# 选项(options):
|
||||
# build - 编译代码(serv和web需要)
|
||||
# save - 保存镜像到tar文件(需要指定version)
|
||||
#
|
||||
# 版本(version):
|
||||
# save=YYYYMMDD_HHMMSS - 指定要保存的镜像版本
|
||||
# 不指定则使用当前构建的版本
|
||||
#
|
||||
# 示例:
|
||||
# ./build.sh base-all # 构建所有基础镜像
|
||||
# ./build.sh serv build save # 编译后端+构建镜像+保存当前版本
|
||||
# ./build.sh all build save # 完整构建流程
|
||||
# ./build.sh serv save=20251124_143025 # 保存指定版本的镜像
|
||||
# ./build.sh all build save=20251124_150000 # 构建并保存为指定版本
|
||||
##############################################
|
||||
|
||||
set -e # 遇到错误立即退出
|
||||
@@ -44,10 +71,48 @@ DOCKER_PATH="${PROJECT_ROOT}/docker"
|
||||
BUILD_OUTPUT="${PROJECT_ROOT}/build-output"
|
||||
IMAGE_VERSION=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# 解析命令行参数
|
||||
BUILD_TARGET="${1:-all}" # 默认构建所有应用镜像
|
||||
shift || true
|
||||
DO_BUILD=false
|
||||
DO_SAVE=false
|
||||
SAVE_VERSION="" # 要保存的版本号
|
||||
|
||||
# 解析选项
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
build)
|
||||
DO_BUILD=true
|
||||
;;
|
||||
save)
|
||||
DO_SAVE=true
|
||||
# 如果不指定版本,使用当前构建的版本
|
||||
;;
|
||||
save=*)
|
||||
DO_SAVE=true
|
||||
SAVE_VERSION="${arg#save=}"
|
||||
;;
|
||||
*)
|
||||
log_warn "未知选项: $arg"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 如果save时没有指定版本,使用当前时间戳
|
||||
if [ "${DO_SAVE}" = true ] && [ -z "${SAVE_VERSION}" ]; then
|
||||
SAVE_VERSION="${IMAGE_VERSION}"
|
||||
fi
|
||||
|
||||
echo "=========================================="
|
||||
echo "校园新闻管理系统 - 构建脚本"
|
||||
echo "=========================================="
|
||||
log_info "构建目标: ${BUILD_TARGET}"
|
||||
log_info "构建版本: ${IMAGE_VERSION}"
|
||||
log_info "编译代码: ${DO_BUILD}"
|
||||
log_info "保存镜像: ${DO_SAVE}"
|
||||
if [ "${DO_SAVE}" = true ]; then
|
||||
log_info "保存版本: ${SAVE_VERSION}"
|
||||
fi
|
||||
log_info "项目路径: ${PROJECT_ROOT}"
|
||||
echo "=========================================="
|
||||
echo ""
|
||||
@@ -56,109 +121,54 @@ echo ""
|
||||
mkdir -p "${BUILD_OUTPUT}"
|
||||
|
||||
# ================================================
|
||||
# 步骤1: Git Pull
|
||||
# 构建函数
|
||||
# ================================================
|
||||
log_step "步骤1: 拉取最新代码"
|
||||
|
||||
# 构建后端基础镜像
|
||||
build_base_serv() {
|
||||
log_step "构建后端基础镜像(Base Serv)"
|
||||
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 "代码拉取完成"
|
||||
log_info "执行: docker build -t school-news-base-serv:${IMAGE_VERSION} -f docker/Dockerfile.base-serv ."
|
||||
if docker build -t school-news-base-serv:${IMAGE_VERSION} -f docker/Dockerfile.base-serv .; then
|
||||
docker tag school-news-base-serv:${IMAGE_VERSION} school-news-base-serv:latest
|
||||
log_info "✅ 后端基础镜像构建成功"
|
||||
log_info " 镜像标签: school-news-base-serv:${IMAGE_VERSION}"
|
||||
log_info " 镜像标签: school-news-base-serv:latest"
|
||||
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包未找到"
|
||||
log_error "❌ 后端基础镜像构建失败"
|
||||
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镜像"
|
||||
# 构建前端基础镜像
|
||||
build_base_web() {
|
||||
log_step "构建前端基础镜像(Base Web)"
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
log_info "执行: docker build -t school-news-base-web:${IMAGE_VERSION} -f docker/Dockerfile.base-web ."
|
||||
if docker build -t school-news-base-web:${IMAGE_VERSION} -f docker/Dockerfile.base-web .; then
|
||||
docker tag school-news-base-web:${IMAGE_VERSION} school-news-base-web:latest
|
||||
log_info "✅ 前端基础镜像构建成功"
|
||||
log_info " 镜像标签: school-news-base-web:${IMAGE_VERSION}"
|
||||
log_info " 镜像标签: school-news-base-web:latest"
|
||||
else
|
||||
log_error "❌ 前端基础镜像构建失败"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 构建MySQL镜像
|
||||
log_info "构建MySQL镜像(包含数据库初始化)..."
|
||||
build_mysql() {
|
||||
log_step "构建MySQL镜像"
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
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 "✅ MySQL镜像构建成功"
|
||||
log_info " 镜像标签: school-news-mysql:${IMAGE_VERSION}"
|
||||
log_info " 镜像标签: school-news-mysql:latest"
|
||||
else
|
||||
@@ -166,202 +176,265 @@ else
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 构建后端服务镜像
|
||||
build_serv() {
|
||||
log_step "构建后端服务镜像(Serv)"
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
# 检查基础镜像
|
||||
if ! docker images | grep -q "school-news-base-serv.*latest"; then
|
||||
log_error "基础镜像不存在: school-news-base-serv:latest"
|
||||
log_error "请先构建基础镜像:./build.sh base-serv"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查jar包
|
||||
if [ ! -f "${SERV_PATH}/admin/target/admin-1.0.0.jar" ]; then
|
||||
log_error "jar包不存在: ${SERV_PATH}/admin/target/admin-1.0.0.jar"
|
||||
log_error "请先编译后端项目:./build.sh serv build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 构建后端镜像
|
||||
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 "✅ 后端服务镜像构建成功"
|
||||
log_info " 镜像标签: school-news-serv:${IMAGE_VERSION}"
|
||||
log_info " 镜像标签: school-news-serv:latest"
|
||||
else
|
||||
log_error "❌ 后端镜像构建失败"
|
||||
log_error "❌ 后端服务镜像构建失败"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 构建前端服务镜像
|
||||
build_web() {
|
||||
log_step "构建前端服务镜像(Web)"
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
# 检查基础镜像
|
||||
if ! docker images | grep -q "school-news-base-web.*latest"; then
|
||||
log_error "基础镜像不存在: school-news-base-web:latest"
|
||||
log_error "请先构建基础镜像:./build.sh base-web"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 检查dist目录
|
||||
if [ ! -d "${WEB_PATH}/dist" ]; then
|
||||
log_error "dist目录不存在: ${WEB_PATH}/dist"
|
||||
log_error "请先构建前端项目:./build.sh web build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 构建前端镜像
|
||||
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 "✅ 前端服务镜像构建成功"
|
||||
log_info " 镜像标签: school-news-web:${IMAGE_VERSION}"
|
||||
log_info " 镜像标签: school-news-web:latest"
|
||||
else
|
||||
log_error "❌ 前端镜像构建失败"
|
||||
log_error "❌ 前端服务镜像构建失败"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 编译后端
|
||||
compile_serv() {
|
||||
log_step "编译后端jar包"
|
||||
cd "${SERV_PATH}"
|
||||
|
||||
log_info "清理旧的构建..."
|
||||
mvn clean -q
|
||||
|
||||
log_info "开始编译后端项目..."
|
||||
if mvn package -DskipTests -pl admin -am; then
|
||||
JAR_FILE="${SERV_PATH}/admin/target/admin-1.0.0.jar"
|
||||
JAR_SIZE=$(du -h "${JAR_FILE}" | cut -f1)
|
||||
log_info "✅ 后端编译成功: ${JAR_SIZE}"
|
||||
else
|
||||
log_error "❌ 后端编译失败"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 构建前端
|
||||
compile_web() {
|
||||
log_step "构建前端dist"
|
||||
cd "${WEB_PATH}"
|
||||
|
||||
log_info "清理旧的构建..."
|
||||
rm -rf dist
|
||||
|
||||
log_info "开始构建前端项目..."
|
||||
if npm run build; then
|
||||
FILE_COUNT=$(find dist -type f | wc -l)
|
||||
DIST_SIZE=$(du -sh dist | cut -f1)
|
||||
log_info "✅ 前端构建成功: ${FILE_COUNT}个文件, ${DIST_SIZE}"
|
||||
else
|
||||
log_error "❌ 前端构建失败"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 保存镜像
|
||||
save_images() {
|
||||
log_step "保存Docker镜像"
|
||||
cd "${BUILD_OUTPUT}"
|
||||
|
||||
case ${BUILD_TARGET} in
|
||||
base-serv)
|
||||
save_image "school-news-base-serv"
|
||||
;;
|
||||
base-web)
|
||||
save_image "school-news-base-web"
|
||||
;;
|
||||
base-all)
|
||||
save_image "school-news-base-serv"
|
||||
save_image "school-news-base-web"
|
||||
;;
|
||||
mysql)
|
||||
save_image "school-news-mysql"
|
||||
;;
|
||||
serv)
|
||||
save_image "school-news-serv"
|
||||
;;
|
||||
web)
|
||||
save_image "school-news-web"
|
||||
;;
|
||||
all)
|
||||
save_image "school-news-mysql"
|
||||
save_image "school-news-serv"
|
||||
save_image "school-news-web"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 保存单个镜像(使用指定版本或当前构建版本)
|
||||
save_image() {
|
||||
local IMAGE_NAME=$1
|
||||
local VERSION="${SAVE_VERSION}"
|
||||
local IMAGE_FILE="${IMAGE_NAME}_${VERSION}.tar"
|
||||
|
||||
# 检查镜像是否存在
|
||||
if ! docker images | grep -q "${IMAGE_NAME}.*${VERSION}"; then
|
||||
log_error "❌ 镜像不存在: ${IMAGE_NAME}:${VERSION}"
|
||||
log_error " 请先构建该版本的镜像,或使用 docker images 查看可用版本"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "保存${IMAGE_NAME}:${VERSION}镜像..."
|
||||
if docker save -o "${IMAGE_FILE}" ${IMAGE_NAME}:${VERSION}; then
|
||||
IMAGE_SIZE=$(du -h "${IMAGE_FILE}" | cut -f1)
|
||||
log_info "✅ 镜像已保存: ${IMAGE_SIZE}"
|
||||
log_info " 版本: ${IMAGE_NAME}:${VERSION}"
|
||||
log_info " 文件: ${BUILD_OUTPUT}/${IMAGE_FILE}"
|
||||
else
|
||||
log_error "❌ 镜像保存失败: ${IMAGE_NAME}:${VERSION}"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ================================================
|
||||
# 主流程控制
|
||||
# ================================================
|
||||
|
||||
# Git更新(可选)
|
||||
if [ "${DO_BUILD}" = true ]; then
|
||||
log_step "Git Pull"
|
||||
cd "${PROJECT_ROOT}"
|
||||
|
||||
if [[ $(git status --porcelain) ]]; then
|
||||
log_warn "检测到未提交的更改"
|
||||
read -p "是否继续拉取代码?(y/n): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_warn "跳过git pull"
|
||||
else
|
||||
git pull origin main 2>/dev/null || git pull origin master 2>/dev/null || true
|
||||
fi
|
||||
else
|
||||
git pull origin main 2>/dev/null || git pull origin master 2>/dev/null || true
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# 执行编译
|
||||
if [ "${DO_BUILD}" = true ]; then
|
||||
case ${BUILD_TARGET} in
|
||||
serv|all)
|
||||
compile_serv
|
||||
;& # fallthrough
|
||||
web|all)
|
||||
compile_web
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# 执行镜像构建
|
||||
case ${BUILD_TARGET} in
|
||||
base-serv)
|
||||
build_base_serv
|
||||
;;
|
||||
base-web)
|
||||
build_base_web
|
||||
;;
|
||||
base-all)
|
||||
build_base_serv
|
||||
build_base_web
|
||||
;;
|
||||
mysql)
|
||||
build_mysql
|
||||
;;
|
||||
serv)
|
||||
build_serv
|
||||
;;
|
||||
web)
|
||||
build_web
|
||||
;;
|
||||
all)
|
||||
build_mysql
|
||||
build_serv
|
||||
build_web
|
||||
;;
|
||||
*)
|
||||
log_error "未知的构建目标: ${BUILD_TARGET}"
|
||||
echo ""
|
||||
echo "可用的构建目标:"
|
||||
echo " base-serv - 构建后端基础镜像"
|
||||
echo " base-web - 构建前端基础镜像"
|
||||
echo " base-all - 构建所有基础镜像"
|
||||
echo " mysql - 构建MySQL镜像"
|
||||
echo " serv - 构建后端服务镜像"
|
||||
echo " web - 构建前端服务镜像"
|
||||
echo " all - 构建所有应用镜像(默认)"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# 查看镜像信息
|
||||
log_info "Docker镜像列表:"
|
||||
docker images | grep -E "school-news-(mysql|serv|web)" | head -10
|
||||
docker images | grep -E "school-news-" | head -15
|
||||
echo ""
|
||||
|
||||
# 保存镜像
|
||||
if [ "${DO_SAVE}" = true ]; then
|
||||
save_images
|
||||
fi
|
||||
|
||||
# ================================================
|
||||
# 步骤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 "构建完成!"
|
||||
log_info "✅ 构建完成!"
|
||||
echo "=========================================="
|
||||
log_info "构建目标: ${BUILD_TARGET}"
|
||||
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"
|
||||
log_info "输出目录: ${BUILD_OUTPUT}"
|
||||
echo "=========================================="
|
||||
59
docker/Dockerfile.base-serv
Normal file
59
docker/Dockerfile.base-serv
Normal file
@@ -0,0 +1,59 @@
|
||||
# ====================================
|
||||
# 后端基础镜像 - Base Serv
|
||||
# 包含:JRE + Python + 系统工具 + 爬虫依赖
|
||||
# 用途:作为后端服务镜像的基础,避免每次都安装依赖
|
||||
# ====================================
|
||||
FROM eclipse-temurin:21-jre
|
||||
|
||||
# 设置环境变量
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 安装系统依赖和工具
|
||||
RUN apt-get update && \
|
||||
apt-get install -y \
|
||||
# Python环境
|
||||
python3 \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
# 网络和诊断工具
|
||||
netcat-traditional \
|
||||
curl \
|
||||
wget \
|
||||
# MySQL客户端
|
||||
default-mysql-client \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 临时复制requirements.txt用于安装依赖
|
||||
COPY schoolNewsCrawler/requirements.txt /tmp/requirements.txt
|
||||
|
||||
# 安装Python爬虫依赖(一次性安装到基础镜像)
|
||||
RUN echo "========================================" && \
|
||||
echo "安装Python爬虫依赖到基础镜像" && \
|
||||
echo "========================================" && \
|
||||
python3 -m pip --version && \
|
||||
echo "" && \
|
||||
# Python 3.12 引入了 PEP 668 规范,需要添加 --break-system-packages
|
||||
python3 -m pip install --no-cache-dir --break-system-packages -r /tmp/requirements.txt && \
|
||||
echo "" && \
|
||||
echo "✅ 爬虫依赖安装完成" && \
|
||||
python3 -m pip list | grep -E "(beautifulsoup4|crawl4ai|selenium|pydantic|requests|loguru)" && \
|
||||
# 清理临时文件
|
||||
rm -f /tmp/requirements.txt
|
||||
|
||||
# 创建应用目录结构
|
||||
WORKDIR /app
|
||||
RUN mkdir -p /app/config /app/logs /app/uploads /app/crawler
|
||||
|
||||
# 镜像元数据
|
||||
LABEL maintainer="School News Team" \
|
||||
description="Base image for school-news backend service with Python dependencies" \
|
||||
version="1.0"
|
||||
|
||||
# 暴露端口(文档用途)
|
||||
EXPOSE 8081
|
||||
|
||||
# 默认命令(会被子镜像覆盖)
|
||||
CMD ["echo", "This is base image, please use school-news-serv image"]
|
||||
41
docker/Dockerfile.base-web
Normal file
41
docker/Dockerfile.base-web
Normal file
@@ -0,0 +1,41 @@
|
||||
# ====================================
|
||||
# 前端基础镜像 - Base Web
|
||||
# 包含:Nginx + 基础配置
|
||||
# 用途:作为前端服务镜像的基础
|
||||
# ====================================
|
||||
FROM nginx:alpine
|
||||
|
||||
# 设置环境变量
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
# 安装必要工具
|
||||
RUN apk add --no-cache \
|
||||
# 时区数据
|
||||
tzdata \
|
||||
# 基础工具
|
||||
bash \
|
||||
curl \
|
||||
# 日志处理
|
||||
&& mkdir -p /app/logs
|
||||
|
||||
# 设置时区
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 创建应用目录
|
||||
WORKDIR /app
|
||||
RUN mkdir -p /app/config /app/logs
|
||||
|
||||
# Nginx基础配置(可被覆盖)
|
||||
RUN rm -f /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 镜像元数据
|
||||
LABEL maintainer="School News Team" \
|
||||
description="Base image for school-news frontend service with Nginx" \
|
||||
version="1.0"
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
|
||||
# 默认命令(会被子镜像覆盖)
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
@@ -1,40 +1,16 @@
|
||||
# 后端服务运行镜像
|
||||
# ====================================
|
||||
# 后端服务镜像 - School News Serv
|
||||
# 基于:school-news-base-serv(已包含Python依赖)
|
||||
# 注意:jar包需要在主机中先编译好
|
||||
FROM eclipse-temurin:21-jre
|
||||
|
||||
# 设置环境变量
|
||||
ENV LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 安装Python3和pip(用于爬虫)以及MySQL客户端(用于配置更新)
|
||||
RUN apt-get update && \
|
||||
apt-get install -y python3 python3-pip python3-venv netcat-traditional curl default-mysql-client && \
|
||||
apt-get clean && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# 创建应用目录
|
||||
WORKDIR /app
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /app/config /app/logs /app/uploads /app/crawler
|
||||
# ====================================
|
||||
FROM school-news-base-serv:latest
|
||||
|
||||
# 从主机复制已编译的jar包
|
||||
COPY schoolNewsServ/admin/target/admin-1.0.0.jar /app/app.jar
|
||||
|
||||
# 复制爬虫脚本
|
||||
# 复制爬虫脚本(基础镜像已安装依赖,这里只需复制脚本)
|
||||
COPY schoolNewsCrawler/ /app/crawler/
|
||||
|
||||
# 安装爬虫依赖(根据requirements.txt)
|
||||
RUN cd /app/crawler && \
|
||||
if [ -f requirements.txt ]; then \
|
||||
echo "安装爬虫依赖..."; \
|
||||
# Python 3.12 引入了 PEP 668 规范,默认禁止在系统环境直接使用 pip 安装包,防止破坏系统 Python 环境。
|
||||
python3 -m pip install --no-cache-dir --break-system-packages -r requirements.txt; \
|
||||
else \
|
||||
echo "警告: 未找到requirements.txt文件"; \
|
||||
fi
|
||||
|
||||
# 复制默认配置文件(作为备份)
|
||||
COPY schoolNewsServ/admin/src/main/resources/application.yml /app/config/application.yml.template
|
||||
COPY schoolNewsServ/admin/src/main/resources/log4j2-spring.xml /app/config/log4j2-spring.xml.template
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
# 前端服务运行镜像
|
||||
# ====================================
|
||||
# 前端服务镜像 - School News Web
|
||||
# 基于:school-news-base-web(Nginx Alpine)
|
||||
# 注意:dist目录需要在主机中先构建好
|
||||
FROM nginx:alpine
|
||||
# ====================================
|
||||
FROM school-news-base-web:latest
|
||||
|
||||
# 设置环境变量
|
||||
ENV TZ=Asia/Shanghai
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache tzdata
|
||||
|
||||
# 创建配置目录
|
||||
RUN mkdir -p /app/config /app/logs /usr/share/nginx/html/schoolNewsWeb
|
||||
# 创建前端目录
|
||||
RUN mkdir -p /usr/share/nginx/html/schoolNewsWeb
|
||||
|
||||
# 从主机复制已构建的dist目录
|
||||
COPY schoolNewsWeb/dist/ /usr/share/nginx/html/schoolNewsWeb/
|
||||
|
||||
Reference in New Issue
Block a user