Merge pull request #23 from yyyCode/feat/web-footer-black-bar #156
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # OpenBlog:push 到 master 时编译后端、打包前端,并将静态资源与 Docker 相关文件同步到阿里云,在服务器执行 docker.sh 更新 Nginx 容器。 | |
| # 后端由内网自托管 Runner 构建为 Docker 容器(openblog-business,8082)。 | |
| # | |
| # 需在仓库 Settings → Secrets and variables → Actions 中配置: | |
| # SERVER_SSH_KEY 服务器 SSH 私钥(完整 PEM) | |
| # SERVER_REMOTE_HOST 公网 IP 或域名 | |
| # SERVER_REMOTE_USER SSH 登录用户(如 root 或 deploy) | |
| # SERVER_TARGET 服务器上部署目录绝对路径(如 /opt/openblog/web),该目录下会有 dist、Dockerfile、docker.sh、nginx.conf | |
| # | |
| # 后端 Spring Boot 以 Docker 容器运行(openblog-business,8082),前端容器内 Nginx 通过 host.docker.internal 反代到宿主机 8082。 | |
| # 前端容器默认映射宿主机端口 18088 → 容器 80,访问 http://IP:18088/ ,请在安全组放行 TCP 18088。 | |
| name: Build and deploy OpenBlog | |
| on: | |
| workflow_dispatch: | |
| push: | |
| branches: | |
| - master | |
| # 文档(*.md)变更不触发部署;具体哪些 job 要跑由 jobs.changes 细粒度过滤 | |
| paths-ignore: | |
| - '**/*.md' | |
| jobs: | |
| # 检测变更范围,供后续 job 条件判断 | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| backend: ${{ steps.filter.outputs.backend }} | |
| frontend: ${{ steps.filter.outputs.frontend }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dorny/paths-filter@v3 | |
| id: filter | |
| with: | |
| filters: | | |
| backend: | |
| - 'OpenBlog-business/**' | |
| - 'OpenBlog-framework*/**' | |
| - 'OpenBlog-message/**' | |
| - 'OpenBlog-message-api/**' | |
| - 'deploy/business/**' | |
| - 'pom.xml' | |
| frontend: | |
| - 'vue/**' | |
| build-backend: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.backend == 'true' || github.event_name == 'workflow_dispatch' }} | |
| runs-on: ubuntu-latest | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up JDK 17 | |
| uses: actions/setup-java@v4 | |
| with: | |
| java-version: "17" | |
| distribution: "temurin" | |
| cache: "maven" | |
| - name: Build backend (Maven) | |
| run: mvn -B -ntp package -DskipTests -pl OpenBlog-business -am | |
| - name: Upload backend JAR | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: backend-jar | |
| path: OpenBlog-business/target/OpenBlog-business-*.jar | |
| retention-days: 1 | |
| deploy-backend: | |
| needs: build-backend | |
| if: ${{ needs.build-backend.result == 'success' || github.event_name == 'workflow_dispatch' }} | |
| runs-on: openblog-backend | |
| steps: | |
| - name: Checkout(获取 deploy/business 下的 Docker 部署文件) | |
| uses: actions/checkout@v4 | |
| - name: Download backend JAR | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: backend-jar | |
| path: backend | |
| - name: Deploy via Docker(构建镜像 + 重启容器) | |
| run: | | |
| set -euo pipefail | |
| TARGET_DIR="/www/wwwroot/java/openblog" | |
| TARGET_JAR="$TARGET_DIR/OpenBlog-business-1.0.0-SNAPSHOT.jar" | |
| # 1. 停掉旧 systemd 服务(释放 8082,避免与容器抢端口) | |
| systemctl stop openblog 2>/dev/null || true | |
| systemctl disable openblog 2>/dev/null || true | |
| # 2. 备份旧 jar | |
| if [ -f "$TARGET_JAR" ]; then | |
| mkdir -p "$TARGET_DIR/backup" | |
| cp "$TARGET_JAR" "$TARGET_DIR/backup/OpenBlog-business-$(date +%Y%m%d-%H%M%S).jar" 2>/dev/null || true | |
| fi | |
| # 3. 拷贝新 jar + Docker 部署文件(.dockerignore 缩小构建上下文) | |
| JAR_FILE=$(ls backend/OpenBlog-business-*.jar | head -1) | |
| cp "$JAR_FILE" "$TARGET_JAR" | |
| cp deploy/business/Dockerfile deploy/business/docker-compose.yml deploy/business/.dockerignore "$TARGET_DIR/" | |
| # 4. Docker 构建并启动容器(兼容 compose v2「docker compose」/ v1「docker-compose」) | |
| cd "$TARGET_DIR" | |
| docker info >/dev/null 2>&1 || { echo "!! Docker 守护进程未运行,请先启动 Docker(宝塔 → Docker 管理器)" >&2; exit 1; } | |
| if docker compose version >/dev/null 2>&1; then | |
| DC="docker compose" | |
| elif docker-compose version >/dev/null 2>&1; then | |
| DC="docker-compose" | |
| else | |
| echo "!! 服务器上没有 docker compose / docker-compose,请先安装 Docker(宝塔 → Docker 管理器)" >&2 | |
| exit 1 | |
| fi | |
| echo "==> 使用: $DC" | |
| $DC up -d --build --remove-orphans | |
| $DC ps | |
| echo "==> Deployed OpenBlog-business via Docker" | |
| build-frontend: | |
| needs: changes | |
| if: ${{ needs.changes.outputs.frontend == 'true' || github.event_name == 'workflow_dispatch' }} | |
| runs-on: ubuntu-latest | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: "npm" | |
| cache-dependency-path: vue/package-lock.json | |
| - name: Install frontend dependencies and build | |
| working-directory: vue | |
| run: | | |
| npm ci | |
| npm run build | |
| - name: Prepare release bundle for server | |
| run: | | |
| mkdir -p release | |
| cp -r vue/dist release/dist | |
| cp vue/Dockerfile vue/docker.sh vue/nginx.conf release/ | |
| - name: Build Docker image on runner | |
| run: | | |
| docker build -t openblog-web release/ | |
| docker save openblog-web | gzip > release/openblog-web.tar.gz | |
| - name: Upload release bundle | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-frontend | |
| path: release/ | |
| deploy-frontend: | |
| needs: build-frontend | |
| if: ${{ needs.build-frontend.result == 'success' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Download release bundle | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: release-frontend | |
| path: release/ | |
| - name: Deploy files to server | |
| uses: easingthemes/ssh-deploy@v5.1.1 | |
| with: | |
| SSH_PRIVATE_KEY: ${{ secrets.SERVER_SSH_KEY }} | |
| ARGS: "-rlgoDzvc --delete --exclude=dist/.user.ini" | |
| SOURCE: "release/dist release/Dockerfile release/docker.sh release/nginx.conf release/openblog-web.tar.gz" | |
| REMOTE_HOST: ${{ secrets.SERVER_REMOTE_HOST }} | |
| REMOTE_USER: ${{ secrets.SERVER_REMOTE_USER }} | |
| TARGET: ${{ secrets.SERVER_TARGET }} | |
| SCRIPT_BEFORE: ls -la | |
| - name: Run Docker commands on server | |
| uses: appleboy/ssh-action@v1.2.0 | |
| with: | |
| host: ${{ secrets.SERVER_REMOTE_HOST }} | |
| username: ${{ secrets.SERVER_REMOTE_USER }} | |
| key: ${{ secrets.SERVER_SSH_KEY }} | |
| command_timeout: 30m | |
| script: | | |
| cd ${{ secrets.SERVER_TARGET }} | |
| sh docker.sh |