From 3c102aaa7e7c9079097a93355e14b368cde1c6eb Mon Sep 17 00:00:00 2001 From: huazhongmin Date: Sun, 21 Dec 2025 17:57:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=83=A8=E7=BD=B2=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/emotion-museum.conf | 33 ++++++++++++- course-web/deploy.sh | 100 ++++++++++++++++++++++++++++++++++++++ course-web/vite.config.js | 1 + 3 files changed, 133 insertions(+), 1 deletion(-) create mode 100755 course-web/deploy.sh diff --git a/conf/emotion-museum.conf b/conf/emotion-museum.conf index 1274ecf..2430b38 100644 --- a/conf/emotion-museum.conf +++ b/conf/emotion-museum.conf @@ -3,7 +3,7 @@ server { listen 80; - server_name 101.200.208.45 localhost 127.0.0.1; + server_name 101.200.208.45; # 前端应用路径 location /emotion-museum/ { @@ -67,6 +67,37 @@ server { rewrite ^(.*)$ $1/ permanent; } + # 体验前端应用路径 (course-web) + location /course-of-life/ { + alias /data/www/course-of-life/; + + # 启用目录索引(可选) + autoindex off; + + # 处理 SPA 的 history 模式 (React Router) + # 所有非文件请求都重定向到 index.html + try_files $uri $uri/ /course-of-life/index.html; + + # 设置缓存策略 + # HTML 文件不缓存 + location ~ \.html?$ { + add_header Cache-Control "no-cache, no-store, must-revalidate"; + add_header Pragma "no-cache"; + add_header Expires "0"; + } + + # 静态资源缓存 1 年 + location ~ \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + add_header Cache-Control "public, max-age=31536000, immutable"; + expires 1y; + } + } + + # 处理不带末尾斜杠的 /course-of-life 请求 + location = /course-of-life { + rewrite ^(.*)$ $1/ permanent; + } + # 后端 API 代理 location /api { proxy_pass http://127.0.0.1:19089; diff --git a/course-web/deploy.sh b/course-web/deploy.sh new file mode 100755 index 0000000..24ba62d --- /dev/null +++ b/course-web/deploy.sh @@ -0,0 +1,100 @@ +#!/bin/bash +# 部署脚本 - 将构建好的 course-web 前端项目上传到服务器 +# 支持版本管理和回滚 +# 使用方法: ./deploy.sh [deploy|rollback] + +SERVER_IP="101.200.208.45" +USERNAME="root" +REMOTE_ROOT="/data/www" +APP_NAME="course-of-life" +DEPLOY_ROOT="${REMOTE_ROOT}/${APP_NAME}-releases" +SYMLINK_PATH="${REMOTE_ROOT}/${APP_NAME}" + +TIMESTAMP=$(date +%Y%m%d%H%M%S) +RELEASE_PATH="${DEPLOY_ROOT}/${TIMESTAMP}" + +function deploy() { + echo "🚀 开始部署 ${APP_NAME} 到服务器..." + + # 1. 环境检查 + if ! command -v npm &> /dev/null; then + echo "❌ 错误: 未找到npm命令" + exit 1 + fi + + # 2. 项目构建 + echo "🧹 清理旧构建..." + rm -rf dist + + echo "📦 开始构建..." + if ! npm run build; then + echo "❌ 构建失败" + exit 1 + fi + + if [ ! -d "dist" ]; then + echo "❌ 错误: dist目录不存在" + exit 1 + fi + + # 3. 准备远程目录 + echo "📁 准备远程目录: ${RELEASE_PATH}" + ssh "${USERNAME}@${SERVER_IP}" "mkdir -p ${RELEASE_PATH}" || { + echo "❌ 无法创建远程目录" + exit 1 + } + + # 4. 上传文件 + echo "📤 上传文件..." + if scp -r dist/* "${USERNAME}@${SERVER_IP}:${RELEASE_PATH}/"; then + echo "✅ 文件上传成功" + else + echo "❌ 文件上传失败" + # 清理失败的发布目录 + ssh "${USERNAME}@${SERVER_IP}" "rm -rf ${RELEASE_PATH}" + exit 1 + fi + + # 5. 切换版本 (原子操作) + echo "🔄 切换当前版本..." + # ln -sfn: force update symlink + ssh "${USERNAME}@${SERVER_IP}" "ln -sfn ${RELEASE_PATH} ${SYMLINK_PATH}" || { + echo "❌ 版本切换失败" + exit 1 + } + + # 6. 权限修正 + ssh "${USERNAME}@${SERVER_IP}" "chmod -R 755 ${RELEASE_PATH}" + + # 7. 清理旧版本 (保留最近5个) + echo "🧹 清理旧版本..." + ssh "${USERNAME}@${SERVER_IP}" "cd ${DEPLOY_ROOT} && ls -t | tail -n +6 | xargs -I {} rm -rf {}" + + echo "✅ 部署完成!" + echo "🌍 访问地址: http://${SERVER_IP}/${APP_NAME}/" +} + +function rollback() { + echo "Reverting to previous version..." + # 获取倒数第二个版本目录 + PREV_VERSION=$(ssh "${USERNAME}@${SERVER_IP}" "cd ${DEPLOY_ROOT} && ls -t | head -n 2 | tail -n 1") + + if [ -z "$PREV_VERSION" ]; then + echo "❌ 没有可回滚的版本" + exit 1 + fi + + echo "🔄 回滚到版本: ${PREV_VERSION}" + ssh "${USERNAME}@${SERVER_IP}" "ln -sfn ${DEPLOY_ROOT}/${PREV_VERSION} ${SYMLINK_PATH}" && \ + echo "✅ 回滚成功" || echo "❌ 回滚失败" +} + +# 主逻辑 +case "$1" in + rollback) + rollback + ;; + *) + deploy + ;; +esac diff --git a/course-web/vite.config.js b/course-web/vite.config.js index f51d184..92ff5ca 100644 --- a/course-web/vite.config.js +++ b/course-web/vite.config.js @@ -5,6 +5,7 @@ import tailwindcss from '@tailwindcss/vite' // https://vite.dev/config/ export default defineConfig({ plugins: [react(), tailwindcss()], + base: '/course-of-life/', server: { proxy: { '/api': {