Jelajahi Sumber

feat: Drone 仅在 tag 时打生产 Docker 交付包到 /root/zkxw-releases

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 6 hari lalu
induk
melakukan
c2c5078ee6

+ 41 - 54
.drone.yml

@@ -1,73 +1,60 @@
-# zkxw:仅编译打包,不自动部署测试环境
-# 触发:push / tag
-# 机器内存约 3.6G:分步构建 + 限制 Node 堆
+# 生产 Docker 交付包:仅 tag 触发
+# 产物:/root/zkxw-releases/zkxw-docker-deploy-<tag>.tar.gz
+# 脚本:./scripts/package-docker-deploy.sh(docker build + save + 组包)
 
 kind: pipeline
 type: docker
-name: build-package
+name: package-prod
 
 concurrency:
   limit: 1
 
 trigger:
   event:
-    - push
     - tag
 
-# 使用本机已预拉的 drone/git(默认 clone 镜像)
 clone:
   depth: 1
 
-steps:
-  - name: build-web-admin
-    image: node:20-bookworm
-    environment:
-      NODE_OPTIONS: --max-old-space-size=3072
-    commands:
-      - set -eu
-      - cp web-admin/.env.docker web-admin/.env.test
-      - corepack enable
-      - corepack prepare pnpm@9.15.9 --activate
-      - cd web-admin
-      - pnpm install --frozen-lockfile
-      # 降低并行以减轻内存峰值
-      - NODE_OPTIONS=--max-old-space-size=3072 pnpm exec vite build --mode test
-      - cd ..
-      - mkdir -p artifacts
-      - tar -C web-admin -czf artifacts/web-admin-dist.tar.gz dist
-      - sha256sum artifacts/web-admin-dist.tar.gz
-      - ls -lh artifacts/web-admin-dist.tar.gz
+volumes:
+  - name: dockersock
+    host:
+      path: /var/run/docker.sock
+  - name: releases
+    host:
+      path: /root/zkxw-releases
 
-  - name: build-oa-h5
-    image: node:20-bookworm
+steps:
+  - name: package-docker
+    image: docker:27-cli
+    privileged: true
+    volumes:
+      - name: dockersock
+        path: /var/run/docker.sock
+      - name: releases
+        path: /releases
     environment:
-      NODE_OPTIONS: --max-old-space-size=1024
-    commands:
-      - set -eu
-      - cp mobile-oa-h5/.env.docker mobile-oa-h5/.env.test
-      - cd mobile-oa-h5
-      - npm ci
-      - npm run build -- --mode test
-      - cd ..
-      - mkdir -p artifacts
-      - tar -C mobile-oa-h5 -czf artifacts/oa-h5-dist.tar.gz dist
-      - sha256sum artifacts/oa-h5-dist.tar.gz
-      - ls -lh artifacts/oa-h5-dist.tar.gz
-
-  - name: package-backend
-    image: node:20-bookworm
+      DOCKER_BUILDKIT: '1'
+      NODE_MAX_OLD_SPACE_SIZE: '3072'
+      NPM_REGISTRY: https://registry.npmmirror.com
+      PIP_INDEX_URL: https://mirrors.aliyun.com/pypi/simple/
+      PIP_TRUSTED_HOST: mirrors.aliyun.com
+      # 若宿主机存在该文件,可在打包前复制为 deploy/docker/.env 以注入微信/RSA
+      # 见 测试环境部署/drone/README.md
     commands:
       - set -eu
-      - mkdir -p artifacts
+      - apk add --no-cache bash git python3
+      - test -n "${DRONE_TAG}"
+      - echo "==> packaging production docker bundle for tag=${DRONE_TAG}"
+      - chmod +x scripts/package-docker-deploy.sh scripts/build-docker-images.sh
       - |
-        tar -czf artifacts/backend-src.tar.gz \
-          --exclude='backend/.venv' \
-          --exclude='backend/venv' \
-          --exclude='backend/__pycache__' \
-          --exclude='backend/**/__pycache__' \
-          --exclude='backend/logs' \
-          --exclude='backend/.pytest_cache' \
-          --exclude='backend/graphify-out' \
-          backend
-      - sha256sum artifacts/backend-src.tar.gz
-      - ls -lh artifacts/backend-src.tar.gz
+        if [ -f /releases/.deploy-docker.env ]; then
+          mkdir -p deploy/docker
+          cp /releases/.deploy-docker.env deploy/docker/.env
+          echo "using /releases/.deploy-docker.env for secret inject"
+        fi
+      - ./scripts/package-docker-deploy.sh "${DRONE_TAG}"
+      - mkdir -p /releases
+      - cp -v dist/zkxw-docker-deploy-"${DRONE_TAG}".tar.gz /releases/
+      - ls -lh /releases/zkxw-docker-deploy-"${DRONE_TAG}".tar.gz
+      - sha256sum /releases/zkxw-docker-deploy-"${DRONE_TAG}".tar.gz

+ 6 - 4
测试环境部署/README.md

@@ -287,17 +287,18 @@ python3.12 -m venv .venv
 
 ---
 
-## 10. Drone CI(Gogs)
+## 10. Drone CI(Gogs)— 生产 Docker 包
 
-同机 Drone 对接现有 Gogs,仅编译打包、不自动部署。说明与 compose 模板见 **[drone/README.md](drone/README.md)**。
+同机 Drone 对接 Gogs:**仅 tag** 触发生产 Docker 交付打包。说明见 **[drone/README.md](drone/README.md)**。
 
 | 项 | 地址 |
 |------|------|
 | Gogs | `http://101.35.245.122:3000` |
 | Drone UI | `http://101.35.245.122:18088` |
-| 流水线 | 仓库根 `.drone.yml`(激活 `wuzilong/zkxw` 后 push 触发) |
+| 流水线 | 仓库根 `.drone.yml`(`git push origin <tag>`) |
+| 产物 | `/root/zkxw-releases/zkxw-docker-deploy-<tag>.tar.gz` |
 
-服务器部署目录:`/root/drone/`(`.env` 仅机器本地,含 `DRONE_RPC_SECRET`)。
+服务器:`/root/drone/`(含 `DRONE_RPC_SECRET`)、`/root/zkxw-releases/`。
 
 ---
 
@@ -327,3 +328,4 @@ python3.12 -m venv .venv
 | 2026-08-06 | 新增 `deploy_test_env.py` 日常发版脚本 |
 | 2026-08-10 | 启用 `www.chengyantek.cn` HTTPS(443)+ HTTP→HTTPS;MinIO 同域 `/minio/zkxw` |
 | 2026-10-23 | 新增同机 Drone CI(`:18088`)对接 Gogs;仓库 `.drone.yml` 仅编译打包 |
+| 2026-10-24 | Drone 改为仅 tag 打生产 Docker 包,产物 `/root/zkxw-releases/` |

+ 40 - 49
测试环境部署/drone/README.md

@@ -1,72 +1,63 @@
-# 测试机 Drone CI(对接 Gogs)
+# 测试机 Drone CI(对接 Gogs)— 生产 Docker 打包
 
 > 目标机:`101.35.245.122`  
-> Gogs:`http://101.35.245.122:3000`(已有)  
-> Drone UI:`http://101.35.245.122:18088`(云安全组未开 8080,改用已放行的 18088)  
-> 范围:编译打包 artifact,**不**自动部署到 `/root/zkxw`
+> Gogs:`http://101.35.245.122:3000`  
+> Drone UI:`http://101.35.245.122:18088`  
+> 产物目录:`/root/zkxw-releases/`
 
-## 1. 部署(在测试机)
+## 行为
+
+- **仅 `tag` 触发**(普通 push 不打包)
+- 执行 `./scripts/package-docker-deploy.sh <tag>`  
+  → `zkxw-backend:<tag>` + `zkxw-web:<tag>` → `docker save` → 交付包
+- 拷贝到:`/root/zkxw-releases/zkxw-docker-deploy-<tag>.tar.gz`
+
+可选:将发版用 `deploy/docker/.env`(含微信/RSA 等注入项)放到:
+
+```text
+/root/zkxw-releases/.deploy-docker.env
+```
+
+打包前会复制为仓库内 `deploy/docker/.env`(**勿提交 git**)。
+
+## 1. 部署 / 更新 Runner
 
 ```bash
-mkdir -p /root/drone
-# 从本仓库同步模板,或手工 scp 本目录
-cp docker-compose.yml .env.example /root/drone/
+mkdir -p /root/drone /root/zkxw-releases
+# 同步本目录 docker-compose.yml 后:
 cd /root/drone
-cp .env.example .env
-# 生成共享密钥
-sed -i "s/replace-with-openssl-rand-hex-32/$(openssl rand -hex 32)/" .env
-docker compose pull
-# 预拉构建镜像(Docker Hub 慢时用 daoCloud,再 tag 成流水线里的名字)
-docker pull docker.m.daocloud.io/library/node:20-bookworm
-docker tag docker.m.daocloud.io/library/node:20-bookworm node:20-bookworm
 docker compose up -d
-docker compose ps
-docker logs drone-runner 2>&1 | tail -20
-# 期望看到:successfully pinged the remote server
+# 预拉流水线镜像(国内建议 daoCloud)
+docker pull docker.m.daocloud.io/library/docker:27-cli
+docker tag docker.m.daocloud.io/library/docker:27-cli docker:27-cli
 ```
 
-云安全组 / 主机防火墙放行 **TCP 18088**(本方案默认端口;勿用未放行的 8080)。
-
-流水线使用默认 `drone/git` clone(`depth: 1`)。构建镜像需预拉 `node:20-bookworm`。  
-测试机内存约 3.6G,已加 `/swap-drone`(4G)并限制 Node 堆,避免 web-admin 构建 OOM。
+云安全组放行 **TCP 18088**。测试机建议保留 `/swap-drone`(前端镜像构建吃内存)。
 
 ## 2. 登录与激活仓库
 
-1. 浏览器打开 `http://101.35.245.122:18088`
-2. 使用 **Gogs 用户名/密码** 登录(Gogs 无 OAuth)
-3. Sync 仓库 → 激活 `wuzilong/zkxw`
-4. 在 Gogs 该仓 **Settings → Webhooks** 确认存在 Drone 回调,例如:  
-   `http://101.35.245.122:18088/hook`
+1. 打开 `http://101.35.245.122:18088`,用 Gogs 账号登录  
+2. 激活 `wuzilong/zkxw`  
+3. Webhook:`http://101.35.245.122:18088/hook`
 
-云安全组 / 本机 YJ 防火墙需放行 **TCP 18088**(本机已按此端口部署)。
+## 3. 发版用法
 
-## 3. 流水线
-
-仓库根目录 [`.drone.yml`](../../.drone.yml):
-
-- `web-admin`:`pnpm build:test` → `artifacts/web-admin-dist.tar.gz`
-- `mobile-oa-h5`:`npm run build -- --mode test` → `artifacts/oa-h5-dist.tar.gz`
-- `backend`:源码打包(排除 venv/logs)→ `artifacts/backend-src.tar.gz`
+```bash
+# 本地打 tag 并推到 Gogs
+git tag v1.2.0
+git push origin v1.2.0
 
-因 `.env.test` 未入库,流水线构建前会用已跟踪的 `.env.docker` 复制为 `.env.test`(仅保证能编过;若需与线上测试配置一致,可在 Drone 仓库 Secrets 中自行注入后再 `printf` 写入)。
+# 构建完成后在测试机取包
+ls -lh /root/zkxw-releases/zkxw-docker-deploy-v1.2.0.tar.gz
+```
 
-**不会** rsync、不会执行 `start-test.sh`。
+Drone UI 可看构建日志;包内结构见 `deploy/docker/README.md`。
 
-## 4. 日常运维
+## 4. 运维
 
 ```bash
 cd /root/drone
 docker compose ps
-docker compose logs -f --tail=100 drone
 docker compose logs -f --tail=100 drone-runner
-docker compose restart
-docker compose down    # 停止(保留 volume drone-data)
-```
-
-## 5. 验收
-
-```bash
-curl -sI http://101.35.245.122:18088 | head -5
-curl -sI http://101.35.245.122:3000 | head -5
-# push 到 wuzilong/zkxw 或在 Drone UI 点 Rebuild,构建应为绿色
+docker compose restart runner
 ```

+ 5 - 3
测试环境部署/drone/docker-compose.yml

@@ -6,8 +6,7 @@
 # 访问:http://101.35.245.122:18088 (用 Gogs 用户名/密码登录)
 # Gogs:http://101.35.245.122:3000
 #
-# Runner 不对外暴露端口。构建镜像请预先 docker pull(见 README),
-# 流水线使用国内可达的 node 镜像,并关闭默认 drone/git clone。
+# 流水线:仅 tag → 生产 Docker 交付包 → /root/zkxw-releases/
 
 services:
   drone:
@@ -15,7 +14,6 @@ services:
     container_name: drone
     restart: always
     ports:
-      # 云安全组未放行 8080;18088 已放行且外网可达
       - '18088:80'
     volumes:
       - drone-data:/data
@@ -45,6 +43,10 @@ services:
       DRONE_RPC_SECRET: ${DRONE_RPC_SECRET}
       DRONE_RUNNER_CAPACITY: ${DRONE_RUNNER_CAPACITY:-1}
       DRONE_RUNNER_NAME: ${DRONE_RUNNER_NAME:-zkxw-test-1}
+      # 允许流水线挂载 docker.sock 与发版目录(host volume allowlist)
+      DRONE_RUNNER_VOLUMES: /var/run/docker.sock:/var/run/docker.sock,/root/zkxw-releases:/releases
+      # 允许 privileged 步骤(docker build)
+      DRONE_RUNNER_PRIVILEGED_IMAGES: docker:27-cli,docker:24-cli,docker:dind
     extra_hosts:
       - '101.35.245.122:host-gateway'
       - 'host.docker.internal:host-gateway'