推 main → 自动上线。但「自动」不等于「不用看」—— 这一页讲清楚部署链路、必须遵守的验证规范、以及出问题时怎么回滚。
本地直接推 main 即可(2 人团队约定);或 PR 合并触发
type-check + lint + unit/integration test,失败则停
~3 minbuildx + GHA cache;NEXT_PUBLIC_* 通过 build-args 注入
~4 min显式跑 pnpm db:migrate,否则线上 schema 落后
滚动更新 app + worker;新机器健康后旧机下线
~2 minCI 与 Docker 构建并行执行,整体约 7-9 分钟。
git push 后必须确认 CI 通过才能告诉用户"已部署"。gh run list --limit 1 看最新状态;gh run view <id> --log-failed 查原因;curl https://www.softie.ai/<path> 验证生产文件包含改动(CDN 可能没刷新)。
scripts/check-payment-health.ts。~/scripts/ 全局,crontab 触发,与项目独立。lax(洛杉矶,目标用户在美西)app(Next.js)+ worker(BullMQ)—— 独立扩缩容NEXT_PUBLIC_*,因为 CI 用独立的 docker/build-push-action 构建,fly.toml 的 build args 只对本地 fly deploy 生效,workflow 里得重复声明一遍(这是踩过的坑)headers() 调用# 找上一个 good commit
git log --oneline --all -20
# 回滚 commit 并推
git revert <bad-sha>
git push origin main
# CI 走完即生效
fly releases list -a softieweb
fly releases rollback <version> -a softieweb
这只回滚 Docker 镜像,不回滚 DB。如果 migration 已经跑了 destructive 改动(drop column 等),必须先 restore 备份再回滚镜像。
# Dashboard: Caching → Configuration → Purge Everything
# 或用 API(token 在记忆库 reference_cloudflare_token.md)
gh run list --limit 1 → CI successfly status -a softieweb → 所有机器 passingcurl https://www.softie.ai/api/health(如有)或关键页面 → 200 + 改动内容在 HTML 里| 症状 | 真相 | 修法 |
|---|---|---|
| 新代码部署后线上行为没变 | Cloudflare 橙云 CDN 缓存(24h+) | Purge Everything;或在 Cloudflare 侧加 Cache Rule override |
| 线上 42703 column does not exist | Fly 部署不会自动跑 migration | 用 fly ssh console 进容器跑 pnpm db:migrate;后续 GHA 显式加这一步 |
| NEXT_PUBLIC_FOO 在生产是 undefined | fly.toml 的 build-args 没同步到 GHA workflow | 在 .github/workflows/fly-deploy.yml 的 build-push-action 里也加一份 |
| Docker 构建慢(10+ 分钟) | BuildKit mount cache 在 GHA 无效 | 用 actions/cache 或 cache-from/cache-to: type=gha |
| 新 secret 写了 GHA workflow 但运行时空值 | ${{ secrets.FOO }} 引用不代表 secret 已配置 |
gh secret list 确认存在再触发;不要相信 workflow 文件 |
| fly scale 后内存没变 | 命令可能不持久 | 事后 fly status 验证;混合机型必须逐台求和 |
| Vercel 莫名其妙又部署了一份 | 旧账号 GitHub App 没卸载,影子部署 | Vercel 控制台 disconnect + GitHub Settings → Apps 卸载 fly-io app |
--no-verify、--no-gpg-sign(CLAUDE.md 全局规则)flyctl deploy --depot,必须 --depot=false —— Depot 会让 internal 网络失败gh secret listlatest.apk 类)—— Cloudflare 缓存 7+ 天会让用户拿不到新版;APK 必须版本化文件名