diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..1315e77 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,68 @@ +# Git +.git +.gitignore +.gitattributes + +# IDE +.idea +.vscode +*.iml +*.swp +*.swo +*~ + +# Docker +docker/ +Dockerfile* +docker-compose*.yml +.dockerignore + +# 文档 +*.md +README* +doc/ +docs/ + +# 日志 +logs/ +*.log + +# 临时文件 +tmp/ +temp/ +.tmp/ + +# 后端相关 +schoolNewsServ/target/ +schoolNewsServ/.mvn/ +schoolNewsServ/mvnw* +schoolNewsServ/**/*.class +schoolNewsServ/**/*.jar +!schoolNewsServ/admin/target/admin-1.0.0.jar +!schoolNewsServ/docker/start.sh + +# 前端相关 +schoolNewsWeb/node_modules/ +schoolNewsWeb/dist/ +schoolNewsWeb/.env.local +schoolNewsWeb/.env.*.local +schoolNewsWeb/npm-debug.log* +schoolNewsWeb/yarn-debug.log* +schoolNewsWeb/yarn-error.log* +!schoolNewsWeb/docker/start.sh + +# 爬虫相关 +schoolNewsCrawler/__pycache__/ +schoolNewsCrawler/**/*.pyc +schoolNewsCrawler/.pytest_cache/ +schoolNewsCrawler/.venv/ +schoolNewsCrawler/venv/ + +# 操作系统 +.DS_Store +Thumbs.db + +# 数据和上传文件 +uploads/ +*.sql +*.dump diff --git a/Optional[NewsItem] b/Optional[NewsItem] deleted file mode 100644 index e69de29..0000000 diff --git a/ResultDomain b/ResultDomain deleted file mode 100644 index e69de29..0000000 diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..66b8bb5 --- /dev/null +++ b/build.bat @@ -0,0 +1,317 @@ +@echo off +chcp 65001 >nul +REM ======================================== +REM 校园新闻管理系统 - 构建和打包脚本 (Windows) +REM 功能: +REM 1. 从git拉取最新代码 +REM 2. 编译后端jar包 +REM 3. 构建前端dist +REM 4. 制作Docker镜像 +REM 5. 保存镜像到文件(用于离线部署) +REM ======================================== + +setlocal enabledelayedexpansion + +REM 颜色定义 +set "INFO=[92m[INFO][0m" +set "WARN=[93m[WARN][0m" +set "ERROR=[91m[ERROR][0m" +set "STEP=[94m[STEP][0m" + +REM 项目路径 +set "PROJECT_ROOT=%~dp0" +set "SERV_PATH=%PROJECT_ROOT%schoolNewsServ" +set "WEB_PATH=%PROJECT_ROOT%schoolNewsWeb" +set "DOCKER_PATH=%PROJECT_ROOT%docker" +set "BUILD_OUTPUT=%PROJECT_ROOT%build-output" + +REM 生成版本号 +for /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c%%a%%b) +for /f "tokens=1-2 delims=/: " %%a in ('time /t') do (set mytime=%%a%%b) +set "IMAGE_VERSION=%mydate%_%mytime%" + +echo ========================================== +echo 校园新闻管理系统 - 构建脚本 +echo ========================================== +echo %INFO% 构建版本: %IMAGE_VERSION% +echo %INFO% 项目路径: %PROJECT_ROOT% +echo ========================================== +echo. + +REM 创建输出目录 +if not exist "%BUILD_OUTPUT%" mkdir "%BUILD_OUTPUT%" + +REM ================================================ +REM 步骤1: Git Pull +REM ================================================ +echo %STEP% 步骤1: 拉取最新代码 +cd "%PROJECT_ROOT%" + +REM 检查git状态 +git status --short >nul 2>&1 +if %errorlevel% neq 0 ( + echo %WARN% 未检测到git仓库,跳过代码拉取 + goto build_backend +) + +echo %INFO% 从远程仓库拉取代码... +git pull origin main 2>nul +if errorlevel 1 ( + git pull origin master 2>nul + if errorlevel 1 ( + echo %WARN% 代码拉取失败或已是最新版本,继续构建... + ) else ( + echo %INFO% 代码拉取完成 + ) +) else ( + echo %INFO% 代码拉取完成 +) +echo. + +REM ================================================ +REM 步骤2: 构建后端jar包 +REM ================================================ +:build_backend +echo %STEP% 步骤2: 构建后端jar包 +cd "%SERV_PATH%" + +echo %INFO% 清理旧的构建... +call mvn clean -q + +echo %INFO% 开始编译后端项目... +echo %INFO% 执行: mvn package -DskipTests -pl admin -am +call mvn package -DskipTests -pl admin -am +if errorlevel 1 ( + echo %ERROR% 后端编译失败 + pause + exit /b 1 +) +echo %INFO% 后端编译成功 + +REM 验证jar包 +set "JAR_FILE=%SERV_PATH%\admin\target\admin-1.0.0.jar" +if exist "%JAR_FILE%" ( + for %%F in ("%JAR_FILE%") do set "JAR_SIZE=%%~zF" + set /a "JAR_SIZE_MB=!JAR_SIZE! / 1048576" + echo %INFO% ✅ jar包已生成: !JAR_SIZE_MB!MB + echo %INFO% 路径: %JAR_FILE% +) else ( + echo %ERROR% ❌ jar包未找到 + pause + exit /b 1 +) +echo. + +REM ================================================ +REM 步骤3: 构建前端dist +REM ================================================ +echo %STEP% 步骤3: 构建前端项目 +cd "%WEB_PATH%" + +REM 检查node_modules +if not exist "node_modules" ( + echo %INFO% 安装前端依赖... + call npm install + if errorlevel 1 ( + echo %ERROR% 依赖安装失败 + pause + exit /b 1 + ) +) + +echo %INFO% 清理旧的构建... +if exist "dist" rd /s /q "dist" + +echo %INFO% 开始构建前端项目... +echo %INFO% 执行: npm run build +call npm run build +if errorlevel 1 ( + echo %ERROR% 前端构建失败 + pause + exit /b 1 +) +echo %INFO% 前端构建成功 + +REM 验证dist目录 +set "DIST_DIR=%WEB_PATH%\dist" +if exist "%DIST_DIR%" ( + for /f %%A in ('dir /s /b "%DIST_DIR%\*" ^| find /c /v ""') do set "FILE_COUNT=%%A" + echo %INFO% ✅ dist目录已生成 (!FILE_COUNT!个文件) + echo %INFO% 路径: %DIST_DIR% +) else ( + echo %ERROR% ❌ dist目录未找到 + pause + exit /b 1 +) +echo. + +REM ================================================ +REM 步骤4: 制作Docker镜像 +REM ================================================ +echo %STEP% 步骤4: 制作Docker镜像 +cd "%PROJECT_ROOT%" + +REM 构建后端镜像 +echo %INFO% 构建后端镜像... +echo %INFO% 执行: docker build -t school-news-serv:%IMAGE_VERSION% -f docker\Dockerfile.serv . +docker build -t school-news-serv:%IMAGE_VERSION% -f docker\Dockerfile.serv . +if errorlevel 1 ( + echo %ERROR% ❌ 后端镜像构建失败 + pause + exit /b 1 +) +echo %INFO% ✅ 后端镜像构建成功 + +REM 打latest标签 +docker tag school-news-serv:%IMAGE_VERSION% school-news-serv:latest +echo %INFO% 镜像标签: school-news-serv:%IMAGE_VERSION% +echo %INFO% 镜像标签: school-news-serv:latest +echo. + +REM 构建前端镜像 +echo %INFO% 构建前端镜像... +echo %INFO% 执行: docker build -t school-news-web:%IMAGE_VERSION% -f docker\Dockerfile.web . +docker build -t school-news-web:%IMAGE_VERSION% -f docker\Dockerfile.web . +if errorlevel 1 ( + echo %ERROR% ❌ 前端镜像构建失败 + pause + exit /b 1 +) +echo %INFO% ✅ 前端镜像构建成功 + +REM 打latest标签 +docker tag school-news-web:%IMAGE_VERSION% school-news-web:latest +echo %INFO% 镜像标签: school-news-web:%IMAGE_VERSION% +echo %INFO% 镜像标签: school-news-web:latest +echo. + +REM 查看镜像信息 +echo %INFO% Docker镜像列表: +docker images | findstr "school-news" +echo. + +REM ================================================ +REM 步骤5: 保存镜像到文件 +REM ================================================ +echo %STEP% 步骤5: 保存Docker镜像 +cd "%BUILD_OUTPUT%" + +REM 保存后端镜像 +set "SERV_IMAGE_FILE=school-news-serv_%IMAGE_VERSION%.tar" +echo %INFO% 保存后端镜像到文件... +echo %INFO% 执行: docker save -o %SERV_IMAGE_FILE% school-news-serv:%IMAGE_VERSION% +docker save -o "%SERV_IMAGE_FILE%" school-news-serv:%IMAGE_VERSION% +if errorlevel 1 ( + echo %ERROR% ❌ 后端镜像保存失败 + pause + exit /b 1 +) + +for %%F in ("%SERV_IMAGE_FILE%") do set "SERV_SIZE=%%~zF" +set /a "SERV_SIZE_MB=!SERV_SIZE! / 1048576" +echo %INFO% ✅ 后端镜像已保存: !SERV_SIZE_MB!MB +echo %INFO% 文件: %BUILD_OUTPUT%\%SERV_IMAGE_FILE% +echo. + +REM 保存前端镜像 +set "WEB_IMAGE_FILE=school-news-web_%IMAGE_VERSION%.tar" +echo %INFO% 保存前端镜像到文件... +echo %INFO% 执行: docker save -o %WEB_IMAGE_FILE% school-news-web:%IMAGE_VERSION% +docker save -o "%WEB_IMAGE_FILE%" school-news-web:%IMAGE_VERSION% +if errorlevel 1 ( + echo %ERROR% ❌ 前端镜像保存失败 + pause + exit /b 1 +) + +for %%F in ("%WEB_IMAGE_FILE%") do set "WEB_SIZE=%%~zF" +set /a "WEB_SIZE_MB=!WEB_SIZE! / 1048576" +echo %INFO% ✅ 前端镜像已保存: !WEB_SIZE_MB!MB +echo %INFO% 文件: %BUILD_OUTPUT%\%WEB_IMAGE_FILE% +echo. + +REM ================================================ +REM 生成部署说明文件 +REM ================================================ +echo %INFO% 生成部署说明文件... +set "DEPLOY_INFO_FILE=%BUILD_OUTPUT%\部署说明_%IMAGE_VERSION%.txt" + +( +echo ======================================== +echo 校园新闻管理系统 - Docker镜像部署说明 +echo ======================================== +echo. +echo 构建信息: +echo 构建时间: %date% %time% +echo 版本号: %IMAGE_VERSION% +echo 构建主机: %COMPUTERNAME% +echo. +echo 镜像文件: +echo 后端镜像: %SERV_IMAGE_FILE% ^(!SERV_SIZE_MB!MB^) +echo 前端镜像: %WEB_IMAGE_FILE% ^(!WEB_SIZE_MB!MB^) +echo. +echo ======================================== +echo 部署步骤: +echo ======================================== +echo. +echo 1. 将镜像文件传输到目标服务器 +echo. +echo 2. 加载Docker镜像: +echo docker load -i %SERV_IMAGE_FILE% +echo docker load -i %WEB_IMAGE_FILE% +echo. +echo 3. 验证镜像: +echo docker images ^| findstr school-news +echo. +echo 4. 启动服务: +echo cd docker +echo docker-compose up -d +echo. +echo 5. 查看服务状态: +echo docker-compose ps +echo docker-compose logs -f +echo. +echo ======================================== +echo 访问地址: +echo ======================================== +echo 前端: http://localhost:8080/schoolNewsWeb/ +echo 后端: http://localhost:8081/schoolNewsServ +echo. +echo ======================================== +echo 注意事项: +echo ======================================== +echo 1. 确保目标服务器已安装Docker和Docker Compose +echo 2. 确保端口8080、8081、3306、6379未被占用 +echo 3. 首次部署需要准备数据库初始化脚本 +echo 4. 生产环境请修改默认密码(.env文件) +echo. +echo ======================================== +) > "%DEPLOY_INFO_FILE%" + +echo %INFO% ✅ 部署说明已生成: %DEPLOY_INFO_FILE% +echo. + +REM ================================================ +REM 构建摘要 +REM ================================================ +echo ========================================== +echo 构建完成! +echo ========================================== +echo %INFO% 构建版本: %IMAGE_VERSION% +echo. +echo %INFO% Docker镜像: +echo - school-news-serv:%IMAGE_VERSION% +echo - school-news-web:%IMAGE_VERSION% +echo. +echo %INFO% 镜像文件保存在: %BUILD_OUTPUT%\ +dir /b "%BUILD_OUTPUT%\*.tar" "%BUILD_OUTPUT%\*.txt" 2>nul +echo. +echo %INFO% 下一步操作: +echo 1. 查看部署说明: %DEPLOY_INFO_FILE% +echo 2. 传输镜像文件到目标服务器 +echo 3. 在目标服务器加载镜像: docker load -i ^<镜像文件^> +echo 4. 启动服务: cd docker ^&^& docker-compose up -d +echo ========================================== +echo. + +pause diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..442c733 --- /dev/null +++ b/build.sh @@ -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 "==========================================" \ No newline at end of file diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..674c597 --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,14 @@ +# 数据库配置 +MYSQL_ROOT_PASSWORD=123456 +MYSQL_DATABASE=school_news +MYSQL_USER=schoolnews +MYSQL_PASSWORD=123456 +MYSQL_PORT=3306 + +# Redis配置 +REDIS_PASSWORD=123456 +REDIS_PORT=6379 + +# 服务端口配置 +SERV_PORT=8081 +WEB_PORT=8080 diff --git a/docker/Dockerfile.mysql b/docker/Dockerfile.mysql new file mode 100644 index 0000000..dd1389b --- /dev/null +++ b/docker/Dockerfile.mysql @@ -0,0 +1,101 @@ +# 校园新闻管理系统 - MySQL数据库镜像 +# 基于reInit.sh的数据库初始化方案 +FROM mysql:8.0 + +# 设置环境变量 +ENV LANG=C.UTF-8 \ + TZ=Asia/Shanghai + +# 复制MySQL配置文件 +COPY docker/mysql/my.cnf /etc/mysql/conf.d/my.cnf + +# 创建SQL目录 +RUN mkdir -p /docker-entrypoint-initdb.d /opt/sql + +# 复制所有SQL文件(保持目录结构) +COPY schoolNewsServ/.bin/mysql/sql/ /opt/sql/ + +# 复制并调整reInit.sh为Docker环境 +COPY schoolNewsServ/.bin/mysql/sql/reInit.sh /opt/sql/ +RUN sed -i 's/DB_HOST="localhost"/DB_HOST="localhost"/' /opt/sql/reInit.sh && \ + sed -i 's/DB_PORT="3306"/DB_PORT="3306"/' /opt/sql/reInit.sh && \ + sed -i 's/DB_USER="root"/DB_USER="root"/' /opt/sql/reInit.sh && \ + sed -i 's/DB_PASSWORD="123456"/DB_PASSWORD="${MYSQL_ROOT_PASSWORD}"/' /opt/sql/reInit.sh && \ + sed -i 's/DB_NAME="school_news"/DB_NAME="${MYSQL_DATABASE}"/' /opt/sql/reInit.sh && \ + chmod +x /opt/sql/reInit.sh + +# 创建Docker初始化适配脚本 +RUN cat > /docker-entrypoint-initdb.d/01-init-database.sh <<'EOF' +#!/bin/bash +set -e + +echo "==========================================" +echo "校园新闻管理系统 - 数据库初始化" +echo "使用 reInit.sh + Docker配置更新" +echo "==========================================" + +# 等待MySQL完全启动 +echo "等待MySQL启动..." +until mysql -uroot -p"${MYSQL_ROOT_PASSWORD}" -e "SELECT 1" >/dev/null 2>&1; do + sleep 1 +done +echo "MySQL已就绪" + +# 切换到SQL目录 +cd /opt/sql + +# 设置环境变量供reInit.sh使用 +export DB_HOST="localhost" +export DB_PORT="3306" +export DB_USER="root" +export DB_PASSWORD="${MYSQL_ROOT_PASSWORD}" +export DB_NAME="${MYSQL_DATABASE}" +export MYSQL_PWD="${MYSQL_ROOT_PASSWORD}" + +# 直接调用reInit.sh的初始化函数 +echo "执行数据库初始化..." + +# Source reInit.sh并调用其初始化函数 +source reInit.sh + +# 调用reInit.sh的核心函数(跳过备份和删除) +execute_init_script # 执行initAll.sql +import_sensitive_words # 导入敏感词 + +# Docker环境特定配置:更新爬虫路径 +echo "更新Docker环境配置..." +mysql -uroot "${MYSQL_DATABASE}" < /etc/nginx/conf.d/default.conf + +# 复制启动脚本 +COPY schoolNewsWeb/docker/start.sh /app/start.sh +RUN chmod +x /app/start.sh + +# 暴露端口 +EXPOSE 80 + +# 健康检查 +HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ + CMD wget --quiet --tries=1 --spider http://localhost/schoolNewsWeb/ || exit 1 + +# 启动应用 +CMD ["/app/start.sh"] diff --git a/docker/Docker构建流程检查报告.md b/docker/Docker构建流程检查报告.md new file mode 100644 index 0000000..c5066d0 --- /dev/null +++ b/docker/Docker构建流程检查报告.md @@ -0,0 +1,516 @@ +# Docker构建流程检查报告 + +## 📋 检查项目清单 + +### ✅ 1. build.sh 构建流程 + +#### 1.1 Git更新代码 +```bash +# 第59-81行 +log_step "步骤1: 拉取最新代码" +git pull origin main || git pull origin master +``` +**状态**: ✅ 已实现 +- 检查未提交更改 +- 支持main/master分支 +- 错误处理 + +#### 1.2 编译后端 +```bash +# 第84-111行 +cd "${SERV_PATH}" +mvn clean +mvn package -DskipTests -pl admin -am +``` +**状态**: ✅ 已实现 +- 清理旧构建 +- 编译admin模块 +- 验证jar包存在 +- 显示文件大小 + +**产物**: `schoolNewsServ/admin/target/admin-1.0.0.jar` + +#### 1.3 构建前端 +```bash +# 第113-148行 +cd "${WEB_PATH}" +npm install # 如果需要 +rm -rf dist +npm run build +``` +**状态**: ✅ 已实现 +- 检查依赖 +- 清理旧构建 +- 构建dist目录 +- 验证文件数量 + +**产物**: `schoolNewsWeb/dist/` + +--- + +## 🐳 2. Docker镜像构建 + +### 2.1 镜像版本命名 + +```bash +# 第45行 +IMAGE_VERSION=$(date +%Y%m%d_%H%M%S) +``` + +**格式**: `yyyymmdd_HHMMSS` +**示例**: `20251124_143025` +**状态**: ✅ 符合要求 + +### 2.2 后端镜像(school-news-serv) + +**Dockerfile.serv 检查**: + +```dockerfile +FROM eclipse-temurin:21-jre + +# ✅ 包含jar包 +COPY schoolNewsServ/admin/target/admin-1.0.0.jar /app/app.jar + +# ✅ 包含爬虫 +COPY schoolNewsCrawler/ /app/crawler/ + +# ✅ 安装爬虫依赖 +RUN pip install -r /app/crawler/requirements.txt + +# ✅ 配置文件模板(可挂载) +COPY application.yml /app/config/application.yml.template +COPY log4j2-spring.xml /app/config/log4j2-spring.xml.template + +# ✅ 安装MySQL客户端(用于配置更新) +RUN apt-get install -y default-mysql-client +``` + +**挂载点**: +- ✅ `/app/config/application.yml` - 配置文件 +- ✅ `/app/config/log4j2-spring.xml` - 日志配置 +- ✅ `/app/logs` - 日志目录 +- ✅ `/app/uploads` - 上传文件 +- ✅ `/app/crawler` - 爬虫脚本 + +**结论**: ✅ **完全符合要求** + +--- + +### 2.3 前端镜像(school-news-web) + +**Dockerfile.web 检查**: + +```dockerfile +FROM nginx:alpine + +# ✅ 包含构建结果 +COPY schoolNewsWeb/dist/ /usr/share/nginx/html/schoolNewsWeb/ + +# ✅ 配置文件(可外挂) +COPY schoolNewsWeb/public/app-config.js /app/config/app-config.js.template + +# ✅ 启动时处理配置替换 +COPY schoolNewsWeb/docker/start.sh /app/start.sh +``` + +**配置外挂机制**: +```bash +# start.sh +if [ -f /app/config/app-config.js ]; then + cp /app/config/app-config.js /usr/share/nginx/html/schoolNewsWeb/app-config.js +fi +``` + +**挂载点**: +- ✅ `/app/config/app-config.js` - 运行时配置(可整个替换) +- ✅ `/app/logs` - 日志目录 + +**配置加载流程**: +``` +1. HTML引用