wxs 6cc703ada2 feat: monorepo 重构 + 新增 5 个平台适配器
项目从单体结构重构为 pnpm monorepo (shared/backend/frontend),
新增 YouTube、Instagram、Twitter/X、哔哩哔哩、微博 5 个平台适配器,
包含完整的单元测试和 E2E 测试覆盖。

- 完成 T-031~T-044: 5 个适配器实现、注册、配置和测试
- 重构前后端分离: Hono 后端 + Next.js 前端
- 151 个单元测试 + 21 个 Mock E2E + 25 个真实 E2E
- 适配器基于真实 TikHub API 响应结构实现

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 15:43:25 +08:00

10 KiB
Raw Blame History

name description
deploy Drone CI + 服务器 CD 全流程引导:从基础设施检查到生成配置文件到验证部署,交互式完成。

Deploy - CI/CD 全流程部署引导

定位:基于公司 Drone CI + 私有 Docker Registry + Docker Compose 的自动化部署方案,交互式引导用户从零完成 CI/CD 接入。

当用户调用 /deploy/deploy <指令> 时,执行以下步骤:

1. 收集项目信息

快速了解项目情况(已知的不重复问):

项目 说明 示例
项目名称 用于镜像命名 douyin, crm, blog
需构建的服务 每个服务对应一个镜像 backend, frontend
各服务的 Dockerfile 路径 Docker build context ./backend, ./frontend
生产服务器 SSH 端口 默认 22 22, 3141
部署目录 生产服务器上的路径 /opt/docker/myproject
数据库迁移命令 如有 alembic upgrade head, npx prisma migrate deploy
健康检查方式 三选一 python / curl / host
健康检查 URL 容器内地址 http://127.0.0.1:8000/health
通知 Webhook 可选,不配则跳过 企业微信/钉钉/飞书

确认后进入下一步。

2. 基础设施检查

输出 Checklist让用户逐项确认首次接入需全部完成后续项目可跳过

□ 基础设施(一次性,已完成则跳过)
  □ Drone CI Server + Runner 已部署运行
  □ 私有 Docker Registry 已运行(默认 :5000
  □ insecure-registries 已配置Drone CI 服务器 + 生产服务器)
  □ SSH 密钥已配置Drone CI 服务器 → 生产服务器免密登录)
  □ 生产服务器用户已加入 docker 组

如果用户表示基础设施未就绪,输出对应的一次性搭建指引(参见下方「附录:基础设施搭建」)。

3. 生成配置文件

基于收集到的信息,生成以下文件:

3.1 .drone.yml

核心原则(踩坑总结,不可违反):

  1. 使用 docker:27-cli + 宿主机 Docker socket不用 plugins/docker DinD
  2. 使用 environment: { VAR: { from_secret: name } } 注入密钥,不用 secrets: 字段
  3. 使用 ${DRONE_TAG:-latest} 作为镜像 tag不自定义中间变量Drone 变量替换冲突)
  4. 触发条件只用 event: [tag, cron]不叠加 cron: [name]AND 运算陷阱)

生成内容包括:

  • trigger: tag + cron
  • volumes: 挂载宿主机 Docker socket
  • 每个服务的 build-<service> step
  • deploy step使用 appleboy/drone-ssh
  • notify-success / notify-failure step如配置了 Webhook

3.2 scripts/deploy-remote.sh

部署脚本要点:

  • set -euo pipefail 严格模式
  • 部署锁PID 文件防并发)
  • 同时 export IMAGE_TAGVERSION(兼容不同 compose 变量命名)
  • 按顺序pull → 停 beat → 更新核心服务 → 健康检查 → 数据库迁移 → 启动剩余服务 → 最终健康检查
  • 健康检查根据用户选择的方式生成python / curl / host

3.3 生成后展示

已生成:
  📄 .drone.yml                    — Drone CI 流水线配置
  📄 scripts/deploy-remote.sh      — 远程部署脚本

确认写入?[Y/n]

用户确认后写入文件。

4. Drone 面板配置引导

生成文件后,输出需要在 Drone 面板手动配置的清单:

4.1 仓库设置

在 Drone 面板完成以下配置:

1. 激活仓库SYNC → 找到仓库 → ACTIVATE
2. 开启 TrustedSettings → General → Project Settings → 勾选 Trusted

4.2 Secrets 配置

根据收集到的信息,输出具体的 Secret 列表:

在 Drone 面板 → 仓库 Settings → Secrets 添加:

| Secret 名称      | 填写内容                                           |
|-------------------|----------------------------------------------------|
| backend_repo      | docker.internal.intelligrow.cn:5000/{project}-backend  |
| frontend_repo     | docker.internal.intelligrow.cn:5000/{project}-frontend |
| deploy_host       | {生产服务器 IP}                                    |
| deploy_user       | {SSH 用户}                                         |
| deploy_ssh_key    | cat ~/.ssh/drone_deploy 的完整内容                 |
| deploy_path       | {部署目录}                                         |
| wecom_webhook     | {Webhook URL}(如已配置)                          |

4.3 Cron 配置(可选)

如需定时构建,在 Settings → Cron Jobs 添加:

| 字段     | 值               | 说明                    |
|----------|------------------|-------------------------|
| Name     | nightly-build    | 任务名称                |
| Branch   | main             | 构建分支                |
| Schedule | 0 16 * * *       | UTC 16:00 = 北京 00:00  |

5. 生产服务器配置引导

在生产服务器上确认:

1. 部署目录结构:
   {deploy_path}/
   ├── docker-compose.prod.yml
   ├── .env
   └── scripts/
       └── deploy-remote.sh    ← 需从代码仓库复制

2. .env 至少包含:
   DOCKER_REGISTRY=docker.internal.intelligrow.cn:5000
   (其他数据库密码等生产配置)

3. docker-compose.prod.yml 中镜像引用格式:
   image: ${DOCKER_REGISTRY}/{project}-backend:${VERSION:-latest}

⚠️ 变量一致性Drone Secret 的镜像地址前缀 = .env 的 DOCKER_REGISTRY = compose 中的镜像名拼接结果

6. 验证

自己执行可执行的验证,不能远程执行的给出命令让用户确认结果:

6.1 本地验证(自己执行)

# 检查 .drone.yml 语法合法性YAML 解析)
# 检查 deploy-remote.sh 语法bash -n
# 检查文件是否已正确写入

6.2 远程验证引导(输出命令,让用户在服务器上执行并反馈结果)

# 推送 Tag 触发首次构建
git tag v{version}
git push origin v{version}

# 观察 Drone 面板 pipeline 状态

# 生产服务器检查
ssh -p {port} {user}@{host} "cd {deploy_path} && docker compose -f docker-compose.prod.yml ps"

7. 完成输出

✅ CI/CD 接入完成!

📄 生成的文件:
  - .drone.yml
  - scripts/deploy-remote.sh

🔧 Drone 面板配置(需手动):
  - [x] 仓库已激活
  - [x] Trusted 已开启
  - [x] Secrets 已添加
  - [ ] Cron Job可选

🖥️ 生产服务器:
  - [ ] .env 已配置
  - [ ] deploy-remote.sh 已复制
  - [ ] 首次部署成功

📖 回滚方案:
  方式1: ssh 到生产服务器执行 bash scripts/deploy-remote.sh {旧版本tag}
  方式2: git tag {旧版本}-rollback {旧版本} && git push origin {旧版本}-rollback

主人,用不用我沉淀 or git 提交?

附录:基础设施搭建

当用户表示基础设施未就绪时,按需输出以下指引:

A. Drone CI 部署

在 Drone CI 服务器创建 ~/drone/docker-compose.yml

services:
  drone-server:
    image: drone/drone:2
    container_name: drone-server
    restart: always
    ports:
      - "3080:80"
    environment:
      - DRONE_GITEA_SERVER=https://<your-gitea-domain>
      - DRONE_GITEA_CLIENT_ID=<gitea-oauth-client-id>
      - DRONE_GITEA_CLIENT_SECRET=<gitea-oauth-client-secret>
      - DRONE_SERVER_HOST=<your-drone-domain>
      - DRONE_SERVER_PROTO=https
      - DRONE_RPC_SECRET=<openssl rand -hex 16 生成>
      - DRONE_USER_CREATE=username:<gitea用户名>,admin:true
    volumes:
      - ./data:/data

  drone-runner:
    image: drone/drone-runner-docker:1
    container_name: drone-runner
    restart: always
    depends_on:
      - drone-server
    environment:
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_HOST=drone-server
      - DRONE_RPC_SECRET=<与 server 相同>
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=drone-runner-1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

关键注意:

  • DRONE_RPC_PROTO=httpRunner 走 Docker 内网直连,不走 HTTPS
  • DRONE_USER_CREATE 的 username 必须与 Gitea 登录用户名完全一致(不是邮箱)

B. 私有 Registry

docker run -d --name registry \
  -p 5000:5000 \
  -v /opt/registry-data:/var/lib/registry \
  --restart always \
  registry:2

C. insecure-registries 配置

在 Drone CI 服务器和生产服务器的 /etc/docker/daemon.json 添加:

{
  "insecure-registries": ["<registry-host>:5000"]
}

不要带 http:// 前缀,直接写 host:port。修改后 sudo systemctl restart docker

D. SSH 免密

# Drone CI 服务器上生成密钥
ssh-keygen -t ed25519 -C "drone-ci-deploy" -f ~/.ssh/drone_deploy -N ""

# 将公钥添加到生产服务器
ssh-copy-id -i ~/.ssh/drone_deploy.pub -p <port> <user>@<production-ip>

# 验证
ssh -i ~/.ssh/drone_deploy -p <port> <user>@<production-ip> "echo ok"

踩坑清单(生成配置时必须规避)

# 正确做法
1 insecure-registrieshttp:// 前缀 直接写 host:port
2 Drone ${VAR} 与 shell 变量冲突 直接用 ${DRONE_TAG:-latest},不赋中间变量
3 secrets: 字段注入 secret environment: { VAR: { from_secret: name } }
4 plugins/docker DinD 启动失败 docker:27-cli + 挂载 Docker socket
5 DRONE_USER_CREATE 填邮箱 必须填 Gitea 登录用户名
6 event + cron 触发条件互斥 只用 event: [tag, cron],不加 cron: 过滤
7 Registry 地址不一致IP vs 域名) Drone Secret、.env、compose 三处统一
8 SSH 端口不对 appleboy/drone-ssh 显式指定 port
9 Docker 权限不足 sudo usermod -aG docker <user> 后重新登录
10 daemon.json 被覆盖 修改前先 cat 查看,合并内容

故障排查速查表

现象 检查方向
Pipeline 不触发 Gitea Webhook 是否勾选"创建"事件;.drone.yml trigger
Step 一直 pending Runner 是否连通 Server仓库是否 Trusted
构建报 secret 为空 environment: from_secret 而非 secrets:
Docker push 失败 (HTTPS) 两台服务器 insecure-registries 配置
SSH 部署超时 密钥是否正确端口是否匹配Docker 权限
镜像名 invalid reference .envDOCKER_REGISTRY 变量是否正确
数据库迁移失败 docker compose logs -f <service>
健康检查超时 增大 MAX_ATTEMPTS;检查服务启动日志