1- # OpenBlog:push 到 master 时编译后端、打包前端,并将静态资源与 Docker 相关文件同步到阿里云,在服务器执行 docker.sh 更新 Nginx 容器。
2- # 后端由内网自托管 Runner 构建为 Docker 容器(openblog-business,8082)。
3- #
4- # 需在仓库 Settings → Secrets and variables → Actions 中配置:
5- # SERVER_SSH_KEY 服务器 SSH 私钥(完整 PEM)
6- # SERVER_REMOTE_HOST 公网 IP 或域名
7- # SERVER_REMOTE_USER SSH 登录用户(如 root 或 deploy)
8- # SERVER_TARGET 服务器上部署目录绝对路径(如 /opt/openblog/web),该目录下会有 dist、Dockerfile、docker.sh、nginx.conf
9- #
10- # 后端 Spring Boot 以 Docker 容器运行(openblog-business,8082),前端容器内 Nginx 通过 host.docker.internal 反代到宿主机 8082。
11- # 前端容器默认映射宿主机端口 18088 → 容器 80,访问 http://IP:18088/ ,请在安全组放行 TCP 18088。
121name : Build and deploy OpenBlog
132
143on :
154 workflow_dispatch :
165 push :
176 branches :
187 - master
19- # 文档(*.md)变更不触发部署;具体哪些 job 要跑由 jobs.changes 细粒度过滤
208 paths-ignore :
219 - ' **/*.md'
2210
2311jobs :
24- # 检测变更范围,供后续 job 条件判断
12+ # 检测变更范围。business 与 message 两条链互不影响;共享契约(OpenBlog-api/**)变更会同时触发双链。
2513 changes :
2614 runs-on : ubuntu-latest
2715 outputs :
28- backend : ${{ steps.filter.outputs.backend }}
16+ business : ${{ steps.filter.outputs.business }}
17+ message : ${{ steps.filter.outputs.message }}
2918 frontend : ${{ steps.filter.outputs.frontend }}
3019 steps :
3120 - uses : actions/checkout@v4
3221 - uses : dorny/paths-filter@v3
3322 id : filter
3423 with :
3524 filters : |
36- backend :
25+ business :
3726 - 'OpenBlog-business/**'
3827 - 'OpenBlog-framework*/**'
39- - 'OpenBlog-message /**'
40- - 'OpenBlog-message- api/**'
28+ - 'OpenBlog-common /**'
29+ - 'OpenBlog-api/**'
4130 - 'deploy/business/**'
4231 - 'pom.xml'
32+ message:
33+ - 'OpenBlog-message/**'
34+ - 'OpenBlog-common/**'
35+ - 'OpenBlog-api/**'
36+ - 'deploy/message/**'
37+ - 'pom.xml'
4338 frontend:
4439 - 'vue/**'
4540
46- build-backend :
41+ # ============ business 链(独立) ============
42+ build-business :
4743 needs : changes
48- if : ${{ needs.changes.outputs.backend == 'true' || github.event_name == 'workflow_dispatch' }}
44+ if : ${{ needs.changes.outputs.business == 'true' || github.event_name == 'workflow_dispatch' }}
4945 runs-on : ubuntu-latest
5046 env :
5147 FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 : true
5248
5349 steps :
5450 - name : Checkout
5551 uses : actions/checkout@v4
56-
5752 - name : Set up JDK 17
5853 uses : actions/setup-java@v4
5954 with :
6055 java-version : " 17"
6156 distribution : " temurin"
6257 cache : " maven"
63-
64- - name : Build backend (Maven)
58+ - name : Build business (Maven)
6559 run : mvn -B -ntp package -DskipTests -pl OpenBlog-business -am
66-
67- - name : Upload backend JAR
60+ - name : Upload business JAR
6861 uses : actions/upload-artifact@v4
6962 with :
70- name : backend -jar
63+ name : business -jar
7164 path : OpenBlog-business/target/OpenBlog-business-*.jar
7265 retention-days : 1
7366
74- deploy-backend :
75- needs : build-backend
76- if : ${{ needs.build-backend .result == 'success' || github.event_name == 'workflow_dispatch' }}
67+ deploy-business :
68+ needs : build-business
69+ if : ${{ needs.build-business .result == 'success' || github.event_name == 'workflow_dispatch' }}
7770 runs-on : openblog-backend
7871
7972 steps :
8073 - name : Checkout(获取 deploy/business 下的 Docker 部署文件)
8174 uses : actions/checkout@v4
82-
83- - name : Download backend JAR
75+ - name : Download business JAR
8476 uses : actions/download-artifact@v4
8577 with :
86- name : backend-jar
87- path : backend
88-
78+ name : business-jar
79+ path : business
8980 - name : Deploy via Docker(构建镜像 + 重启容器)
9081 run : |
9182 set -euo pipefail
@@ -102,28 +93,113 @@ jobs:
10293 cp "$TARGET_JAR" "$TARGET_DIR/backup/OpenBlog-business-$(date +%Y%m%d-%H%M%S).jar" 2>/dev/null || true
10394 fi
10495
105- # 3. 拷贝新 jar + Docker 部署文件(.dockerignore 缩小构建上下文)
106- JAR_FILE=$(ls backend /OpenBlog-business-*.jar | head -1)
96+ # 3. 拷贝新 jar + Docker 部署文件
97+ JAR_FILE=$(ls business /OpenBlog-business-*.jar | head -1)
10798 cp "$JAR_FILE" "$TARGET_JAR"
10899 cp deploy/business/Dockerfile deploy/business/docker-compose.yml deploy/business/.dockerignore "$TARGET_DIR/"
109100
110- # 4. Docker 构建并启动容器(兼容 compose v2「docker compose」/ v1「docker-compose」)
101+ # 4. Docker 构建并启动容器
111102 cd "$TARGET_DIR"
112- docker info >/dev/null 2>&1 || { echo "!! Docker 守护进程未运行,请先启动 Docker(宝塔 → Docker 管理器) " >&2; exit 1; }
103+ docker info >/dev/null 2>&1 || { echo "!! Docker 守护进程未运行,请先启动 Docker" >&2; exit 1; }
113104 if docker compose version >/dev/null 2>&1; then
114105 DC="docker compose"
115106 elif docker-compose version >/dev/null 2>&1; then
116107 DC="docker-compose"
117108 else
118- echo "!! 服务器上没有 docker compose / docker-compose,请先安装 Docker(宝塔 → Docker 管理器) " >&2
109+ echo "!! 服务器上没有 docker compose / docker-compose" >&2
119110 exit 1
120111 fi
121112 echo "==> 使用: $DC"
122113 $DC up -d --build --remove-orphans
123114 $DC ps
124-
125115 echo "==> Deployed OpenBlog-business via Docker"
126116
117+ # ============ message 链(独立,与 business 互不影响) ============
118+ build-message :
119+ needs : changes
120+ if : ${{ needs.changes.outputs.message == 'true' || github.event_name == 'workflow_dispatch' }}
121+ runs-on : ubuntu-latest
122+ env :
123+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 : true
124+
125+ steps :
126+ - name : Checkout
127+ uses : actions/checkout@v4
128+ - name : Set up JDK 17
129+ uses : actions/setup-java@v4
130+ with :
131+ java-version : " 17"
132+ distribution : " temurin"
133+ cache : " maven"
134+ - name : Build message (Maven)
135+ run : mvn -B -ntp package -DskipTests -pl OpenBlog-message -am
136+ - name : Upload message JAR
137+ uses : actions/upload-artifact@v4
138+ with :
139+ name : message-jar
140+ path : OpenBlog-message/target/OpenBlog-message-*.jar
141+ retention-days : 1
142+
143+ deploy-message :
144+ needs : build-message
145+ if : ${{ needs.build-message.result == 'success' || github.event_name == 'workflow_dispatch' }}
146+ runs-on : openblog-backend
147+
148+ steps :
149+ - name : Checkout(获取 deploy/message 下的 Docker 部署文件)
150+ uses : actions/checkout@v4
151+ - name : Download message JAR
152+ uses : actions/download-artifact@v4
153+ with :
154+ name : message-jar
155+ path : message
156+ - name : Deploy via Docker(构建镜像 + 重启容器 + 注入阿里云凭据)
157+ env :
158+ ALIYUN_AK : ${{ secrets.ALIYUN_AK }}
159+ ALIYUN_SK : ${{ secrets.ALIYUN_SK }}
160+ ALIYUN_FROM : ${{ secrets.ALIYUN_FROM }}
161+ run : |
162+ set -euo pipefail
163+ TARGET_DIR="/www/wwwroot/java/openblog-message"
164+ TARGET_JAR="$TARGET_DIR/OpenBlog-message-1.0.0-SNAPSHOT.jar"
165+
166+ # 1. 停掉旧 宝塔/手动部署的 message 进程(释放 8083/20883;若无则该步 no-op)
167+ systemctl stop openblog-message 2>/dev/null || true
168+
169+ # 2. 备份旧 jar
170+ mkdir -p "$TARGET_DIR"
171+ if [ -f "$TARGET_JAR" ]; then
172+ mkdir -p "$TARGET_DIR/backup"
173+ cp "$TARGET_JAR" "$TARGET_DIR/backup/OpenBlog-message-$(date +%Y%m%d-%H%M%S).jar" 2>/dev/null || true
174+ fi
175+
176+ # 3. 拷贝新 jar + Docker 部署文件
177+ JAR_FILE=$(ls message/OpenBlog-message-*.jar | head -1)
178+ cp "$JAR_FILE" "$TARGET_JAR"
179+ cp deploy/message/Dockerfile deploy/message/docker-compose.yml deploy/message/.dockerignore "$TARGET_DIR/"
180+
181+ # 4. 阿里云凭据写入服务器 .env(compose 自动加载),供 message 容器读取
182+ printf 'ALIYUN_AK=%s\nALIYUN_SK=%s\nALIYUN_FROM=%s\n' \
183+ "$ALIYUN_AK" "$ALIYUN_SK" "$ALIYUN_FROM" \
184+ > "$TARGET_DIR/.env"
185+
186+ # 5. Docker 构建并启动容器
187+ cd "$TARGET_DIR"
188+ docker info >/dev/null 2>&1 || { echo "!! Docker 守护进程未运行,请先启动 Docker" >&2; exit 1; }
189+ if docker compose version >/dev/null 2>&1; then
190+ DC="docker compose"
191+ elif docker-compose version >/dev/null 2>&1; then
192+ DC="docker-compose"
193+ else
194+ echo "!! 服务器上没有 docker compose / docker-compose" >&2
195+ exit 1
196+ fi
197+ echo "==> 使用: $DC"
198+ $DC up -d --build --remove-orphans
199+ $DC ps
200+ echo "==> Deployed OpenBlog-message via Docker"
201+
202+ # ============ 前端链(原样保留) ============
127203 build-frontend :
128204 needs : changes
129205 if : ${{ needs.changes.outputs.frontend == 'true' || github.event_name == 'workflow_dispatch' }}
@@ -134,31 +210,26 @@ jobs:
134210 steps :
135211 - name : Checkout
136212 uses : actions/checkout@v4
137-
138213 - name : Set up Node.js
139214 uses : actions/setup-node@v4
140215 with :
141216 node-version : " 22"
142217 cache : " npm"
143218 cache-dependency-path : vue/package-lock.json
144-
145219 - name : Install frontend dependencies and build
146220 working-directory : vue
147221 run : |
148222 npm ci
149223 npm run build
150-
151224 - name : Prepare release bundle for server
152225 run : |
153226 mkdir -p release
154227 cp -r vue/dist release/dist
155228 cp vue/Dockerfile vue/docker.sh vue/nginx.conf release/
156-
157229 - name : Build Docker image on runner
158230 run : |
159231 docker build -t openblog-web release/
160232 docker save openblog-web | gzip > release/openblog-web.tar.gz
161-
162233 - name : Upload release bundle
163234 uses : actions/upload-artifact@v4
164235 with :
@@ -176,7 +247,6 @@ jobs:
176247 with :
177248 name : release-frontend
178249 path : release/
179-
180250 - name : Deploy files to server
181251 uses : easingthemes/ssh-deploy@v5.1.1
182252 with :
@@ -187,7 +257,6 @@ jobs:
187257 REMOTE_USER : ${{ secrets.SERVER_REMOTE_USER }}
188258 TARGET : ${{ secrets.SERVER_TARGET }}
189259 SCRIPT_BEFORE : ls -la
190-
191260 - name : Run Docker commands on server
192261 uses : appleboy/ssh-action@v1.2.0
193262 with :
0 commit comments