diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index 9b4038d..cc9fca7 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -1,43 +1,45 @@ +name: Build and Push Docker Image -# name: 构建项目 -# run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +# 当代码推送到 main 分支时触发 +on: + push: + branches: [ main ] -# # 2. 触发条件 (on) -# on: [push] +jobs: + build-and-push: + runs-on: ubuntu-latest -# # 3. 作业定义 (jobs) -# jobs: -# 构建: -# # 4. 运行器选择 (runs-on) -# runs-on: ubuntu-latest - -# # 5. 步骤序列 (steps) -# steps: -# # 步骤 1: 检出代码 -# - name: 检出代码 -# uses: https://gitea.com/actions/checkout@v4 + steps: + # 步骤 1: 检出你的代码仓库 + - name: Checkout code + uses: actions/checkout@v4 -# - name: 显示目录 -# run: ls -la + # 步骤 2: 设置 Docker Buildx (推荐,支持多平台构建等高级功能) + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 -# # 步骤 2: 设置 Node.js 环境 -# - name: 设置 Node.js 环境 -# uses: https://gitea.com/actions/setup-node@v4 -# with: -# node-version: 22 -# cache: 'npm' + # 步骤 3: 登录到你的 Docker 仓库 + # 你需要在 Gitea/GitHub 的 Secrets 中配置好 DOCKERHUB_USERNAME 和 DOCKERHUB_TOKEN + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + registry: registry.bmycode.help + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} -# # 步骤 3: 安装依赖 -# - name: 安装依赖 -# run: npm ci - -# # 步骤 4: 执行打包命令 -# - name: 执行Build构建 -# run: npm run build - -# # 步骤 5: 上传打包产物 -# - name: 上传构建产物 -# uses: https://gitea.com/actions/upload-artifact@v3 -# with: -# name: dist -# path: dist/ \ No newline at end of file + # 步骤 4: 构建并推送 Docker 镜像 (核心步骤) + - name: Build and push + uses: docker/build-push-action@v5 + with: + # context: . 表示 Docker 构建上下文为当前仓库的根目录 + # 这意味着 Dockerfile 中 COPY . . 会复制整个项目代码 + context: . + + # push: true 表示构建成功后将镜像推送到仓库 + push: true + + # tags: 定义镜像的名称和标签 + # 推荐使用 commit sha 作为标签,便于版本追溯 + tags: | + registry.bmycode.help/app-product:latest + registry.bmycode.help/app-product:${{ github.sha }} \ No newline at end of file diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml index 5ff14a3..d422f0d 100644 --- a/.gitea/workflows/test.yml +++ b/.gitea/workflows/test.yml @@ -1,92 +1,91 @@ -# 工作流名称 -name: Gitea Actions Demo +# # 工作流名称 +# name: Gitea Actions Demo -# 运行名称:在Gitea界面中显示的具体运行名称,支持动态变量 -run-name: ${{ gitea.actor }} 正在测试 Gitea Actions 🚀 +# # 运行名称:在Gitea界面中显示的具体运行名称,支持动态变量 +# run-name: ${{ gitea.actor }} 正在测试 Gitea Actions 🚀 -# 触发条件:当发生push事件时触发 -on: [push] +# # 触发条件:当发生push事件时触发 +# on: [push] -# 作业定义 -jobs: - # 作业名称:探索Gitea Actions - Explore-Gitea-Actions: - # 运行环境:在ubuntu-latest标签的runner上运行 - runs-on: ubuntu-latest +# # 作业定义 +# jobs: +# # 作业名称:探索Gitea Actions +# Explore-Gitea-Actions: +# # 运行环境:在ubuntu-latest标签的runner上运行 +# runs-on: ubuntu-latest - # 步骤序列 - steps: - - name: 执行远程 SSH 命令(密码认证) - uses: appleboy/ssh-action@v1 - with: - host: ${{ secrets.HOST }} - username: ${{ secrets.USERNAME }} - password: ${{ secrets.PASSWORD }} - port: ${{ secrets.PORT }} - script: | - pwd - cd /home/bmy/app-product - ls -al +# # 步骤序列 +# steps: +# - name: 执行远程 SSH 命令(密码认证) +# uses: appleboy/ssh-action@v1 +# with: +# host: ${{ secrets.HOST }} +# username: ${{ secrets.USERNAME }} +# password: ${{ secrets.PASSWORD }} +# port: ${{ secrets.PORT }} +# script: | +# pwd +# cd /home/bmy/app-product +# ls -al - # 步骤 2: 在管理机拉取最新代码并部署 - - name: 拉取代码并执行部署 - run: | - # 1. 在 Runner 上安装 sshpass - sudo apt-get update && sudo apt-get install -y sshpass +# # 步骤 2: 在管理机拉取最新代码并部署 +# - name: 拉取代码并执行部署 +# run: | +# # 1. 在 Runner 上安装 sshpass +# sudo apt-get update && sudo apt-get install -y sshpass - # 2. 使用 sshpass 执行远程命令 - # -o StrictHostKeyChecking=no: 自动接受未知的主机密钥,避免 "Host key verification failed" 错误 - # sshpass -p '密码' ssh ...: 通过 sshpass 提供密码 - # -T: 禁用伪终端分配,避免相关警告 - sshpass -p '${{ secrets.PASSWORD }}' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.USERNAME }}@${{ secrets.HOST }} << 'EOF' - # --- 以下为在管理机上执行的脚本 --- +# # 2. 使用 sshpass 执行远程命令 +# # -o StrictHostKeyChecking=no: 自动接受未知的主机密钥,避免 "Host key verification failed" 错误 +# # sshpass -p '密码' ssh ...: 通过 sshpass 提供密码 +# # -T: 禁用伪终端分配,避免相关警告 +# sshpass -p '${{ secrets.PASSWORD }}' ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ${{ secrets.USERNAME }}@${{ secrets.HOST }} << 'EOF' +# # --- 以下为在管理机上执行的脚本 --- - # 定义项目目录(管理机上的代码存放路径) - PROJECT_DIR="/home/bmy/gitea_actions" +# # 定义项目目录(管理机上的代码存放路径) +# PROJECT_DIR="/home/bmy/gitea_actions" - # 进入项目目录,若不存在则克隆仓库 - if [ ! -d "$PROJECT_DIR" ]; then - echo "项目目录不存在,克隆仓库..." - # 假设管理机已配置好 Gitea 的访问权限 (如部署密钥) - # git@git.bmycode.help:bmy/gitea_actions.git - git clone git@git.bmycode.help:${{ gitea.repository }}.git $PROJECT_DIR - cd $PROJECT_DIR - else - echo "拉取最新代码..." - cd $PROJECT_DIR - git checkout main - git pull origin main - fi +# # 进入项目目录,若不存在则克隆仓库 +# if [ ! -d "$PROJECT_DIR" ]; then +# echo "项目目录不存在,克隆仓库..." +# # 假设管理机已配置好 Gitea 的访问权限 (如部署密钥) +# git clone git@git.bmycode.help:${{ gitea.repository }}.git $PROJECT_DIR +# cd $PROJECT_DIR +# else +# echo "拉取最新代码..." +# cd $PROJECT_DIR +# git checkout main +# git pull origin main +# fi - # 执行部署脚本 - pwd - ls +# # 执行部署脚本 +# pwd +# ls - # --- 远程脚本结束 --- - EOF - # 步骤1:输出事件信息 - - run: echo "🎉 该作业由 ${{ gitea.event_name }} 事件自动触发。" +# # --- 远程脚本结束 --- +# EOF +# # 步骤1:输出事件信息 +# - run: echo "🎉 该作业由 ${{ gitea.event_name }} 事件自动触发。" - # 步骤2:输出运行环境信息 - - run: echo "🐧 该作业现在正在Gitea托管的 ${{ runner.os }} 服务器上运行!" +# # 步骤2:输出运行环境信息 +# - run: echo "🐧 该作业现在正在Gitea托管的 ${{ runner.os }} 服务器上运行!" - # 步骤3:输出分支和仓库信息 - - run: echo "🔎 您的分支名称是 ${{ gitea.ref }},您的仓库是 ${{ gitea.repository }}。" +# # 步骤3:输出分支和仓库信息 +# - run: echo "🔎 您的分支名称是 ${{ gitea.ref }},您的仓库是 ${{ gitea.repository }}。" - # 步骤4:检出仓库代码(具有名称的步骤) - - name: 检出仓库代码 - uses: actions/checkout@v4 +# # 步骤4:检出仓库代码(具有名称的步骤) +# - name: 检出仓库代码 +# uses: actions/checkout@v4 - # 步骤5:输出克隆完成信息 - - run: echo "💡 ${{ gitea.repository }} 仓库已克隆到runner。" +# # 步骤5:输出克隆完成信息 +# - run: echo "💡 ${{ gitea.repository }} 仓库已克隆到runner。" - # 步骤6:准备测试提示 - - run: echo "🖥️ 工作流现已准备好在runner上测试您的代码。" +# # 步骤6:准备测试提示 +# - run: echo "🖥️ 工作流现已准备好在runner上测试您的代码。" - # 步骤7:列出仓库文件(多行命令) - - name: 列出仓库中的文件 - run: | - ls ${{ gitea.workspace }} +# # 步骤7:列出仓库文件(多行命令) +# - name: 列出仓库中的文件 +# run: | +# ls ${{ gitea.workspace }} - # 步骤8:输出作业状态 - - run: echo "🍏 此作业的状态是 ${{ job.status }}。" \ No newline at end of file +# # 步骤8:输出作业状态 +# - run: echo "🍏 此作业的状态是 ${{ job.status }}。" \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d38a23c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,21 @@ +FROM node:24-alpine AS builder +WORKDIR /app + +COPY package.json ./ + +# 直接使用 npm install 并解决依赖问题 +RUN npm install --no-audit --no-fund --legacy-peer-deps + +# 拷贝源码并构建 +COPY . . + +# 【前端修改】如果要以子路径 /app-product/ 部署,请用 base 指定前缀,同 .env中VITE_SERVER_NAME +RUN npx vite build + +FROM nginx:alpine +# 构建产物放到 /usr/share/nginx/html/app-product +COPY --from=builder /app/dist /usr/share/nginx/html +# 覆盖 Nginx 配置,支持 SPA 子路径 +COPY nginx.conf /etc/nginx/conf.d/default.conf +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..f9c0b3b --- /dev/null +++ b/nginx.conf @@ -0,0 +1,13 @@ +server { + listen 80; + server_name *.ddd.com; + + location / { + alias /usr/share/nginx/html/; + try_files $uri $uri/ /index.html; + add_header 'Access-Control-Allow-Origin' '*'; + add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range'; + } +} \ No newline at end of file