跳转到主要内容
这是「我 clone 了 vibestrap,到底要做哪些事,钱才能真的进我账户」的完整走查。 覆盖每个外部服务、每个后台 URL、每个环境变量名——按照真正合理的顺序排列。

心智模型

vibestrap 走的是 「用什么填什么」 模式。应用启动只需 两个 真值 (DATABASE_URL + BETTER_AUTH_SECRET);其它都可选,留空时优雅地降级为空操作。 还没有 Stripe 账号?定价页就把 checkout 按钮藏掉。没填 Resend key?忘记密码页面 照样渲染,只是不发邮件。 但有一个大坑大多数人都会踩:
应用启动了 ≠ 应用工作正常。 Zod 校验的是环境变量的结构min(1).url() 等), 不是语义。一个 pod 完全可以 1/1 Running,而网站每次访问都返回 500,因为占位 DATABASE_URL 根本不指向真实数据库。所以配置完之后,一定要走真实的用户流程 (注册、登录、付款)——别只盯着 kubectl get pods

三层配置

vibestrap 的配置分三处,各有理由:
文件控制什么
品牌 & 商品src/config/site.ts名字、文案、价格展示、社交链接
翻译messages/{en,zh}.json所有用户可见的字符串
密钥 & 开关k8s/.env(线上)或 .env.local(本地)API key、DB URL、provider 切换
本篇说的是第三层。前两层见 配置定制

在哪里改值

线上集群的流程:
# 1. 在自己电脑上改 k8s/.env(已 gitignore,永远不要提交)
vim k8s/.env

# 2. 把 env 文件作为 Secret 推进集群
./k8s/create-secrets.sh

# 3. pod 不会自动重载 secret——重启 deployment
kubectl rollout restart deployment/vibestrap -n vibestrap
本地开发把同样的变量名写到 .env.localpnpm dev 自动加载——不用重启。

必填:少一个站点就 500 的 4 个值

下面任何一个少了,站点都跑不起来。先把这四个搞定。
1

DATABASE_URL —— 你的 Postgres

为什么:每个读写数据的页面都走它。没有真实 DB 时,所有非静态路由都 500。 营销首页可能能加载,但 /login/register/pricing/admin 都开不了。在哪注册neon.tech——serverless Postgres,免费额度大方, 对独立开发者友好。(替代品:Supabase、Railway、RDS——任何 Postgres 15+ 都行。)
1

创建项目

  1. https://neon.tech 注册
  2. 新建项目——区域选离 K8s 集群最近的(节点在 us-east-2 就选这个)
  3. 等 ~10 秒,provisioning 结束
2

拿连接串

  1. 左侧栏点 Connection Details
  2. 重要:选 Pooled connection(serverless 和突发流量场景比 direct 稳得多)
  3. 复制 URL
  4. 确保末尾是 ?sslmode=require——Neon 强制 TLS,少了这个连不上
3

粘到 k8s/.env

DATABASE_URL=postgres://neondb_owner:[email protected]/neondb?sslmode=require
变量示例
DATABASE_URLpostgres://neondb_owner:[email protected]/neondb?sslmode=require
首次部署必须手动建表——跟 ShipAny / mksaas 一致,runtime 镜像不会 自动应用迁移。配好 DATABASE_URL 之后,立刻在你笔记本上对生产 URL 跑下面任意一条
# 生产环境推荐:按顺序应用 src/db/migrations/ 里的 SQL 文件,
# 在 __drizzle_migrations 表里留痕,便于将来增量升级。
DATABASE_URL='postgres://...prod...' DATABASE_PROVIDER=postgres pnpm db:migrate

# 或者最快路径(不留迁移历史):
DATABASE_URL='postgres://...prod...' DATABASE_PROVIDER=postgres pnpm db:push
跳过这步会怎样:应用能启动,但每个查 DB 的页面都 500,日志里写 relation "user" does not exist将来改 schema 流程一样:pnpm db:generate 生成新的迁移文件 → commit → 应用新镜像前先对生产 DB 跑 pnpm db:migrate
2

BETTER_AUTH_SECRET —— 鉴权签名密钥

为什么:用来签 session cookie 和 JWT。如果留着占位符,任何看过模板仓库的人 都能伪造任意用户的 session。这是上线第一天就会让生意做不下去的安全洞。在哪注册:不用注册,自己电脑生成。
1

生成

openssl rand -base64 32
输出 44 个字符,末尾是 =
2

粘到 k8s/.env

BETTER_AUTH_SECRET=S8sFO3lhBaqfDD0p308BqjBNQ6TssHA9i2p4JoMYSb4=
变量示例
BETTER_AUTH_SECRETS8sFO3lhBaqfDD0p308BqjBNQ6TssHA9i2p4JoMYSb4=
绝对不要提交。绝对不要 staging 和 prod 共用同一个。绝对不要在聊天或截图里贴出来。 一旦泄露,立刻重新生成——所有用户被强制登出,但这是唯一安全的做法。
3

NEXT_PUBLIC_APP_URL —— 你的域名

为什么:这个值会在 build 时烤进 client bundle。被 OG 图、sitemap、OAuth 重定向 URI、 邮件里的链接共用。如果指向 localhost,所有分享出去的链接都会坏掉。
变量示例
NEXT_PUBLIC_APP_URLhttps://vibestrap.dev
必须是生产环境的 https URL。末尾不要带斜杠。不要用 http://
4

BETTER_AUTH_URL —— 鉴权回调根地址

为什么:Better Auth 的 OAuth 回调签名依赖它。如果错了,登录回调会被拒 (“invalid origin”),用户看到一个莫名其妙的报错页。99% 的情况下应该等于 NEXT_PUBLIC_APP_URL。只有当你的鉴权放在不同子域名上时 才需要拆开。
变量示例
BETTER_AUTH_URLhttps://vibestrap.dev
这四个填好之后,pod 起得来,首页能渲染。下面让它真正能用。

强烈建议:用户预期能用的功能

不填这些,站点能加载但关键功能是坏的:找回密码不能用、不能用 Google/GitHub 登录、 不能给你付钱。上线前就配好——别等到第一个用户来投诉。

Resend(事务邮件)

为什么:找回密码、邮箱验证、欢迎邮件。不配的话,「忘记密码」按钮纯属装饰。 在哪注册resend.com——免费额度 100 封/天,3000 封/月。 早期上线足够用。
1

注册并验证自己的邮箱

标准注册流程。
2

添加并验证你的域名

  1. 左侧栏 → DomainsAdd Domain
  2. 输入域名(比如 vibestrap.dev
  3. Resend 会给出 3 条 DNS 记录(SPF、DKIM、DMARC)——不要关页面
  4. 在域名注册商(Cloudflare、Namecheap、GoDaddy……)那边添加这 3 条记录
  5. Verify DNS Records;等 5–30 分钟,状态变 Verified
3

创建 API key

  1. 左侧栏 → API KeysCreate API Key
  2. 权限选 “Sending access” 就够
  3. 复制 re_xxx key——只显示一次
变量来源示例
RESEND_API_KEYResend → API Keysre_a1b2c3d4...
RESEND_FROM_EMAIL已验证域名下任意邮箱Larry from Vibestrap <[email protected]>
RESEND_REPLY_TO_EMAIL你真会看的收件箱[email protected]
RESEND_FROM_EMAIL 里那个人名(比如 Larry from Vibestrap)可选,但能明显提升送达率—— 裸的 hello@… 看起来像机器人。

管理员访问

你自己得能进 /admin
变量示例
ADMIN_EMAILS[email protected],[email protected]
逗号分隔。登录时按邮箱匹配。第一个匹配的用户首次登录后获得 admin 角色, 之后就能访问 /admin

Google OAuth

为什么:大概 60% 的独立开发者更喜欢「用 Google 登录」而不是输密码。 仅这一个按钮就能显著提升注册转化。 在哪配console.cloud.google.com
1

选或建一个 Google Cloud 项目

左上下拉 → New Project,或选已有项目。
2

配置 OAuth consent screen

  1. 左菜单 → APIs & ServicesOAuth consent screen
  2. User type:External → Create
  3. App nameUser support emailDeveloper contact email
  4. 后面的 scopes / test users 步骤默认即可
3

创建 OAuth client

  1. 左菜单 → APIs & ServicesCredentials
  2. + Create CredentialsOAuth 2.0 Client ID
  3. Application type:Web application
  4. Name:随便(比如 “vibestrap”)
  5. Authorized JavaScript originshttps://vibestrap.dev
  6. Authorized redirect URIshttps://vibestrap.dev/api/auth/callback/google (这个路径必须一字不差——Better Auth 用它)
  7. Create → 弹窗显示 Client ID + Client Secret → 立刻复制两个
变量示例
GOOGLE_CLIENT_ID1234567890-abc...apps.googleusercontent.com
GOOGLE_CLIENT_SECRETGOCSPX-abcdef...
NEXT_PUBLIC_GOOGLE_CLIENT_IDGOOGLE_CLIENT_ID(镜像,client 端 One-Tap 用)
重定向 URI 必须逐字节精确匹配:https vs http、末尾斜杠、大小写都算。 绝大多数「OAuth 不工作」都是这里手滑。换域名当天一定要顺手把这个 URI 也改了。

GitHub OAuth

为什么:vibestrap 面向开发者,「用 GitHub 登录」对开发者的转化率约 80%。 值这 5 分钟。 在哪配github.com/settings/developersOAuth AppsNew OAuth App
1

填表

  • Application name:vibestrap(或者你想让用户看到的名字)
  • Homepage URLhttps://vibestrap.dev
  • Authorization callback URLhttps://vibestrap.dev/api/auth/callback/github
  • Register application
2

拿凭证

  1. 在应用页面复制 Client ID
  2. Generate a new client secret → 立刻复制(只显示一次)
变量示例
GITHUB_CLIENT_IDIv1.abc123...
GITHUB_CLIENT_SECRETghs_abcdef...

Stripe

为什么:收钱。不配的话整个定价页就是装饰品。 在哪配dashboard.stripe.com
1

激活 Stripe 账户

提交税务 + 银行信息。激活后才能拿到 live keys。Test mode 不需要激活,但收不到真钱。
2

拿 API keys

  1. Developers → API keys
  2. 复制 Secret keysk_live_...
  3. 复制 Publishable keypk_live_...
3

建 product 和 price

  1. Products → + Add product
  2. 起名 “vibestrap”(或你的产品名)
  3. 在产品下加 price。vibestrap 通常两个:
    • 标准一次性付款:比如 $99
    • 促销一次性付款:比如 $49(可选促销价)
  4. 点进每个 price,从 URL 或详情面板复制 price_xxx ID
4

注册 webhook

  1. Developers → Webhooks → + Add endpoint
  2. Endpoint URLhttps://vibestrap.dev/api/webhooks/stripe
  3. 勾选要发的事件:
    • checkout.session.completed
    • customer.subscription.created
    • customer.subscription.updated
    • customer.subscription.deleted
    • invoice.payment_succeeded
    • invoice.payment_failed
  4. Add endpoint
  5. 在 endpoint 详情页 RevealSigning secret → 复制 whsec_...
变量示例
STRIPE_SECRET_KEYsk_live_abc...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYpk_live_abc...
STRIPE_WEBHOOK_SECRETwhsec_abc...
STRIPE_PRICE_VIBESTRAP_STANDARDprice_abc...(标准 SKU)
STRIPE_PRICE_VIBESTRAP_PROMOprice_abc...(可选,促销价)
最容易漏的就是 webhook secret。 没有它,Stripe 收了客户的钱,但你的 DB 永远收不到—— 买家付了钱什么也没拿到。上线前一定先用 Stripe endpoint 页的「Send test webhook」按钮 打一发测试。如果签名校验失败,就是 STRIPE_WEBHOOK_SECRET 错了。

SEO + 数据分析——强烈建议

这些不影响站点能不能跑,但直接影响有没有人能找到你的站。

Google Search Console —— 站点验证

为什么:不验证 Google 大概率不收录你的站。没有 SEO 流量 = 没有自然增长 = 只剩付费投流一条路。 在哪search.google.com/search-console
1

添加 property

  1. Add propertyURL prefix → 填 https://vibestrap.dev
  2. 验证方式选 HTML tag
2

只复制 content 值

页面会显示类似 <meta name="google-site-verification" content="ABC123..." />。 你只要引号之间那一段——ABC123...,不要整段标签。
变量示例
GOOGLE_SITE_VERIFICATIONRj7vQ...content="..." 那一段,不带标签)

Microsoft Clarity —— 热力图 + 录屏

为什么:免费的热力图、session 录屏、死点检测。$0 的用户研究投入里这是最值的。 在哪clarity.microsoft.com
1

建 project

  1. 登录(Microsoft / Google / Facebook 都行)
  2. New project → 起名、填 URL
  3. 跳过安装说明;vibestrap 自动注入脚本
  4. 复制 project ID——10 位字母数字,在安装说明页能看到
变量示例
NEXT_PUBLIC_CLARITY_PROJECT_IDabc123xyz0

PostHog —— 产品分析(可选)

为什么:漏斗、留存、feature flag。免费额度 1M events/月,早期产品远远够用。 在哪posthog.com
1

建项目

  1. 注册,新建项目
  2. Project Settings → Project API Key → 复制 phc_xxx
  3. 注意 host:US cloud 是 https://us.i.posthog.com,EU 是 https://eu.i.posthog.com
变量示例
NEXT_PUBLIC_POSTHOG_KEYphc_abc...
NEXT_PUBLIC_POSTHOG_HOSThttps://us.i.posthog.com(默认)

可选——真正用到再配

其它所有的放一个表里。不要预先全配——每一个都是「变量空着 = 功能关闭」。
功能什么时候配变量注册地址
Bing 站点验证想要 Bing/DuckDuckGo 流量BING_SITE_VERIFICATIONbing.com/webmasters
Yandex 验证面向俄语用户YANDEX_VERIFICATIONwebmaster.yandex.com
Resend Audience 邮件订阅用 Resend 收订阅RESEND_AUDIENCE_IDresend.com → Audiences
Beehiiv 邮件订阅你已经在用 BeehiivBEEHIIV_API_KEYBEEHIIV_PUBLICATION_IDbeehiiv.com
Crisp 在线客服想加一个 chat widgetNEXT_PUBLIC_CRISP_WEBSITE_IDcrisp.chat
Tawk.to 客服Crisp 的免费替代NEXT_PUBLIC_TAWK_PROPERTY_IDNEXT_PUBLIC_TAWK_WIDGET_IDtawk.to
Intercom预算更高、CRM 更强NEXT_PUBLIC_INTERCOM_APP_IDintercom.com
Chatwoot自托管的客服NEXT_PUBLIC_CHATWOOT_WEBSITE_TOKENNEXT_PUBLIC_CHATWOOT_BASE_URLchatwoot.com
Cloudflare Turnstile注册/支付防机器人NEXT_PUBLIC_TURNSTILE_SITE_KEYTURNSTILE_SECRET_KEYcloudflare.com
Affonso 联盟营销跑联盟计划NEXT_PUBLIC_AFFONSO_IDaffonso.io
Rewardful 联盟Stripe 原生联盟NEXT_PUBLIC_REWARDFUL_API_KEYrewardful.com
Tolt 联盟更便宜的替代NEXT_PUBLIC_TOLT_REFERRAL_KEYtolt.io
Creem(Stripe 替代支付)你所在区域 Stripe 不可用CREEM_API_KEYCREEM_WEBHOOK_SECRETCREEM_PRODUCT_IDcreem.io
AI providers(Phase 2)产品里要用 AIAI_PROVIDEROPENAI_API_KEYANTHROPIC_API_KEYOPENROUTER_API_KEYREPLICATE_API_TOKENFAL_KEY各自官网
S3 / R2 存储用户上传、生成的图片S3_ENDPOINTS3_REGIONS3_BUCKETS3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYAWS S3 或 Cloudflare R2
授权下载链接买家从哪里下载 zipLICENSE_DOWNLOAD_URL你的 GitHub 私有 release / S3 链接
每个功能的完整走查在各自页:客服联盟订阅TurnstileLicense 发放AI providers

应用 + 验证

k8s/.env 填好了。下面把它推进集群,然后证明它真的工作。

应用变更

# 1. 改 env 文件(已 gitignore——只在自己电脑或运维同事电脑上存)
vim k8s/.env

# 2. 刷新 K8s Secret
./k8s/create-secrets.sh

# 3. pod 不会自动重载 secret——重启
kubectl rollout restart deployment/vibestrap -n vibestrap

# 4. 看 rollout 完成
kubectl rollout status deployment/vibestrap -n vibestrap

走真实用户流程(别只看 pod 状态)

kubectl get pods 显示 1/1 Running 只能证明进程起来了。证明不了数据库能连、 OAuth 重定向能用、Stripe webhook 能触发。下面这个清单一个一个手动走:
1

首页能渲染

打开 https://vibestrap.dev。应该正常显示。如果 500,最常见的两种原因: DATABASE_URL 拼错了,或你忘了在配置完 DB 后跑 pnpm db:migrate (见”必填”段顶部那个警告)。
2

邮箱注册能用

访问 /register,用邮箱注册。检查收件箱里有欢迎邮件。 验证:Resend API key + 域名验证。
3

Google 登录能用

访问 /login,点 Continue with Google。应该重定向 → 授权 → 回到你的应用且已登录。 验证:Google OAuth client + 重定向 URI。
4

GitHub 登录能用

同样的流程,Continue with GitHub。验证:GitHub OAuth app。
5

找回密码邮件能到

/login 点「忘记密码」,填邮箱。30 秒内邮件应该到。 验证:Resend 进一步 + 鉴权布线。
6

管理员后台能进

ADMIN_EMAILS 里列的邮箱登录。访问 /admin。应该正常加载——不是 403。 验证:ADMIN_EMAILS 解析。
7

定价页 → Stripe Checkout

访问 /pricing,点任意付款按钮。应该跳到 checkout.stripe.com 下的 Stripe Checkout 页。 验证:Stripe live keys + price ID 都配好了。
8

一笔真实的端到端测试购买

在 Stripe Checkout 页,用 Stripe 测试卡 4242 4242 4242 4242(只在 test mode 有效; live mode 可以用真卡然后退款给自己,或者先用沙盒环境跑通整个流程)。确认:
  • Stripe 后台显示一笔付款
  • webhook 触发(Stripe → Webhooks → 你的 endpoint 显示 200
  • payment 表多了一行
  • 你账户的 /settings/licenses/admin/licenses 看到一份授权
验证:webhook secret + price ID 到 credit 的布线 + license 签发。
任何一步失败,看 pod 日志:
kubectl logs -n vibestrap -l app=vibestrap --tail=50
Zod 和 Better Auth 都打人话日志——大多数时候答案就在日志里。

配置参考

三层配置详解。

环境变量参考

vibestrap 读取的所有环境变量列表。

Stripe 深入

更多 Stripe 细节:订阅、退款、争议处理。

Kubernetes 部署

集群搭建、Harbor registry、密钥轮换。
到这里就上线了。接下来去告诉别人吧。