Skip to main content
Kubernetes 部署刻意做得最小化:一个 YAML 文件、一个辅助脚本、一个 CI workflow。 整套设计能在一屏内看完,从上往下读,后面想加东西也好扩展。

Manifest 里有什么

k8s/vibestrap.yaml 按这个顺序定义了四种资源:
  1. Namespace —— vibestrap
  2. Deployment —— Next.js 应用,1 副本,/api/ping 探针,合理的资源 requests/limits
  3. Service —— ClusterIP,端口 80 → 3000
  4. Ingress —— nginx + cert-manager TLS,内置 www → apex 跳转
只从 Harbor 拉一个镜像:harbor.funkro.com/vibestrap/vibestrap。集群里 没有任何迁移 Job——见下文 数据库迁移

CI 帮你做了什么

.github/workflows/docker-build-push.yml 在以下情况会跑:
  • 推送到 main 分支
  • 推送 v* 形式的 tag
  • 在 GitHub Actions UI 手动触发
每次跑会:
1

构建镜像

Dockerfile 的 runner stage 打成 harbor.funkro.com/vibestrap/vibestrap:<version>, 同时额外打 :latest tag。
2

推送到 Harbor

用 GitHub Actions secrets 里的 HARBOR_USERNAME + HARBOR_PASSWORD 登录。
3

计算 version tag

Tag 推送用 git tag(比如 v1.2.0)。分支推送用 main-<sha7>。 两种格式都是不可变的,不像 :latest
4

自动回写 manifest

Workflow 把 k8s/vibestrap.yaml 里的 image: 行改成新版本, 并以 [skip ci] 提交回 main。git 里的 manifest 永远跟仓库里的镜像 版本一致。
CI 里不放 kubeconfig。部署本身仍然是你手动敲命令 —— 这是有意为之。

GitHub Actions secrets

Settings → Secrets and variables → Actions 里加这两个:

首次部署

第一次 kubectl apply 之前,集群里要先准备好三样东西。

1. Harbor 拉取密钥

让集群能从你的私有仓库拉镜像:
K8s 的 pull secret 是 namespace 级隔离的 —— 放在 default 或任何其他 namespace 的 harbor-secretvibestrap namespace 里用不了。 必须加 --namespace vibestrapImagePullBackOff 最常见的原因就是这个 secret 建错了 namespace。
如果同一个集群已经为别的项目建过 harbor-secret,可以直接复制过来,不用 重新输密码:

2. 应用 Secret —— 只有两个字段必填

镜像启动时只校验 DATABASE_URLBETTER_AUTH_SECRET其他环境变量 全部可选,留空时对应功能自动跳过——你可以先把服务跑起来,之后想要哪个 功能再回来填,重跑脚本 + kubectl rollout restart 就行。
辅助脚本会去掉注释、空行和值上意外加的引号(kubectl 会把引号当成值的一部分, Better Auth 和 Stripe SDK 会爆),然后帮你跑 kubectl create secret generic ... --from-env-file。Deployment 通过 envFrom: secretRef 把所有变量一次性注入。
k8s/.env 已 gitignore,别提交进去。新增或改动值之后重跑 create-secrets.sh 即可。

3. ingress-nginx + cert-manager

Ingress 默认 ingressClassName: nginx,并依赖一个名为 letsencrypt-prod 的 ClusterIssuer。如果集群里还没装:
然后照 cert-manager 文档 建一个 letsencrypt-prod ClusterIssuer。

数据库迁移

迁移在集群里跑。运行时镜像不带 drizzle-kit,也没有 Job 要照看。 取而代之,触动 schema 的发布之前,从本机跑:
然后 kubectl apply 新镜像。单副本部署本身就没竞态窗口——schema 什么时候动 完全你说了算。

生产 DB 在私有 VPC 里怎么办

如果本机直接连不到生产 DB,在集群内拉一个一次性 pod,借集群网络跑同一条命令。 完整的 kubectl run 命令在 k8s/README.md 里;大致长这样:
这是兜底方案——只有真的从集群外连不上 DB 时才用。

部署

CI workflow 把 manifest 改好之后,每次部署是这样:
如果只是改了环境变量(没有新代码),刷新 Secret 然后滚一下 Deployment:

长大之后怎么扩

Manifest 故意做得很薄 —— 真有需要再加。下面每一项都很小(10–30 行), 彼此独立。

故障排查

官方文档