独立造物局登录
部署托管28 分钟

Next.js + Supabase 项目部署上线完整流程

从本地构建、Vercel 部署、Cloudflare 域名解析,到 Supabase Auth 与 Google OAuth 生产环境配置的完整上线教程。

结论

一个使用 Next.js + Supabase Auth + Google 登录 的产品上线,不能只把代码部署到 Vercel。完整上线至少要同时处理 4 个地方:

  1. Vercel:部署项目、绑定域名、配置生产环境变量。
  2. Cloudflare:把域名 DNS 指向 Vercel。
  3. Supabase:把 Auth 的 Site URL 和 Redirect URLs 改成正式域名。
  4. Google Cloud:把正式域名加入 OAuth Client 的 Authorized JavaScript origins。

这篇教程按生产项目的真实顺序写。你可以把域名、项目名、Supabase 项目 ref 替换成自己的。

上线前准备

开始前先确认你已经有这些东西:

txt
1. 一个可以本地运行的 Next.js 项目
2. 一个 Supabase 项目
3. 一个 Vercel 账号
4. 一个 Cloudflare 账号
5. 一个已经购买并托管在 Cloudflare 的域名
6. 如果支持 Google 登录,还需要一个 Google Cloud OAuth Client

本文示例用这些占位值:

txt
正式域名
https://your-domain.com

www 域名
https://www.your-domain.com

Supabase 项目 URL
https://your-project-ref.supabase.co

Supabase OAuth Callback URL
https://your-project-ref.supabase.co/auth/v1/callback

网站登录回调地址
https://your-domain.com/auth/callback

注意:截图里会出现示例项目名和示例域名。你操作时以自己的项目为准。

第 1 步:本地确认项目可以构建

部署前先在本地跑一次构建:

bash
npm run build

如果这里失败,不要先去 Vercel 调。先在本地把 TypeScript、环境变量、路由、依赖问题修好。

常见失败原因:

txt
1. 缺少 NEXT_PUBLIC_SUPABASE_URL
2. 缺少 NEXT_PUBLIC_SUPABASE_ANON_KEY
3. 代码里使用了只能在浏览器执行的 API,但放在了服务端组件里
4. 动态路由缺少必要数据
5. ESLint 或 TypeScript 报错

一个 Supabase 项目通常至少需要这两个前端环境变量:

env
NEXT_PUBLIC_SUPABASE_URL=https://your-project-ref.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-supabase-anon-key

如果你的项目会生成 sitemap、邮件链接、OAuth redirect URL,建议再加一个站点 URL:

env
NEXT_PUBLIC_SITE_URL=https://your-domain.com

第 2 步:部署到 Vercel

进入 Vercel Dashboard:

txt
https://vercel.com/dashboard

点击:

txt
Add New... -> Project

选择你的 GitHub 仓库,导入项目。

如果是 Next.js 项目,Vercel 通常会自动识别:

txt
Framework Preset: Next.js
Build Command: npm run build
Output Directory: 自动
Install Command: npm install

首次部署前,在 Environment Variables 填入生产环境变量。

txt
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
NEXT_PUBLIC_SITE_URL

先部署一次,让项目得到一个 Vercel 默认域名,例如:

txt
https://your-project.vercel.app

这个默认域名可以先用于测试,但最终生产配置应切到你的正式域名。

第 3 步:在 Vercel 绑定正式域名

进入 Vercel 项目后,打开:

txt
Project -> Settings -> Domains

点击:

txt
Add

添加你的根域名:

txt
your-domain.com

再添加 www 子域名:

txt
www.your-domain.com

添加后,Vercel 会给出 DNS 配置建议。使用 Cloudflare 管理 DNS 时,常见推荐是:

txt
Type: CNAME
Name: @
Value: xxxxx.vercel-dns-xxx.com
Proxy: DNS only

Type: CNAME
Name: www
Value: xxxxx.vercel-dns-xxx.com
Proxy: DNS only

也有些项目会看到根域名推荐 A 记录。以 Vercel 当前页面给出的建议为准。

Vercel Domains 配置页面

检查点:

txt
1. 根域名已经添加到当前项目
2. www 域名已经添加到当前项目
3. 两个域名最终状态都是 Valid Configuration / Configured Correctly
4. 域名没有被其他 Vercel 项目占用

第 4 步:在 Cloudflare 配置 DNS

打开 Cloudflare Dashboard:

txt
https://dash.cloudflare.com

进入你的域名,打开:

txt
DNS -> Records

如果 Vercel 推荐 CNAME,就添加两条记录:

txt
Type: CNAME
Name: @
Target: Vercel 给你的 CNAME 值
Proxy status: DNS only
TTL: Auto
txt
Type: CNAME
Name: www
Target: Vercel 给你的 CNAME 值
Proxy status: DNS only
TTL: Auto

Cloudflare DNS Records 配置页面

这里最容易错的是代理状态。

Vercel 通常要求:

txt
Proxy status: DNS only

不要选:

txt
Proxied

原因是 Vercel 需要直接校验域名解析和证书签发。上线初期先保持 DNS only,等你明确理解 Vercel 与 Cloudflare 代理、缓存、SSL 模式的关系后,再考虑是否打开代理。

如果你原来已经有冲突记录,先删除旧记录:

txt
A @ -> 旧 IP
A www -> 旧 IP
CNAME www -> 旧平台

同一个名称下不能同时存在冲突的 A/CNAME 记录。

第 5 步:等待 Vercel 域名校验通过

回到 Vercel:

txt
Project -> Settings -> Domains

等待两个域名变成正常状态。

你也可以用命令检查:

bash
npx vercel domains inspect your-domain.com
npx vercel domains inspect www.your-domain.com

或者直接检查 HTTP:

bash
curl -I https://your-domain.com
curl -I https://www.your-domain.com

期望结果:

txt
HTTP/2 200
server: Vercel

如果刚改完 DNS 没生效,等几分钟再查。DNS 传播不是实时的。

第 6 步:更新 Vercel 生产环境变量

域名可以访问后,进入:

txt
Project -> Settings -> Environment Variables

把生产环境的站点 URL 改成正式域名:

env
NEXT_PUBLIC_SITE_URL=https://your-domain.com

Vercel Environment Variables 页面

如果你用 Vercel CLI,也可以这样操作:

bash
npx vercel env rm NEXT_PUBLIC_SITE_URL production
printf '%s' 'https://your-domain.com' | npx vercel env add NEXT_PUBLIC_SITE_URL production

注意:

txt
1. NEXT_PUBLIC_ 开头的变量会暴露给前端,不能放私钥
2. Supabase anon key 可以放 NEXT_PUBLIC_,service role key 绝对不能放前端
3. 修改环境变量后,必须重新部署才会在生产环境生效

重新部署:

bash
npx vercel --prod

或者在 Vercel Dashboard 里点 Redeploy。

部署完成后,进入:

txt
Project -> Deployments

确认最新生产部署是 Ready / Production。

Vercel Production Deployments 页面

第 7 步:更新 Supabase Auth URL Configuration

如果项目使用 Supabase Auth,这一步必须做。否则用户登录后可能跳回旧域名、本地域名,或者被 Supabase 拦截。

打开 Supabase:

txt
https://supabase.com/dashboard

进入项目后打开:

txt
Authentication -> URL Configuration

把 Site URL 改成正式域名:

txt
Site URL
https://your-domain.com

在 Redirect URLs 里添加正式登录回调地址:

txt
https://your-domain.com/auth/callback

建议保留本地开发地址:

txt
http://localhost:3000/auth/callback

如果你还想保留 Vercel 默认域名用于测试,也可以保留:

txt
https://your-project.vercel.app/auth/callback

Supabase URL Configuration 页面

配置完成后,最终应该类似:

txt
Site URL
https://your-domain.com

Redirect URLs
http://localhost:3000/auth/callback
https://your-project.vercel.app/auth/callback
https://your-domain.com/auth/callback

不要把 Google 的 Supabase callback URL 填到这里。这里填的是你网站自己的回调地址。

第 8 步:确认 Supabase Google Provider 已启用

如果你的网站支持 Google 登录,继续打开:

txt
Authentication -> Sign In / Providers

找到:

txt
Google

确认 Provider 是启用状态,并且 Client ID / Client Secret 已经填好。

Supabase Auth Providers 页面

在 Google Provider 面板里,Supabase 会提供一个 OAuth Callback URL,格式是:

txt
https://your-project-ref.supabase.co/auth/v1/callback

这个地址要填到 Google Cloud 的 Authorized redirect URIs。

第 9 步:更新 Google Cloud OAuth Client

打开 Google Cloud Console:

txt
https://console.cloud.google.com

进入:

txt
Google Auth Platform -> 客户端

找到你的 Web OAuth Client,进入编辑页。

在:

txt
已获授权的 JavaScript 来源

添加正式域名:

txt
https://your-domain.com

注意这里不要加路径:

txt
正确
https://your-domain.com

错误
https://your-domain.com/auth/callback

在:

txt
已获授权的重定向 URI

保持 Supabase callback:

txt
https://your-project-ref.supabase.co/auth/v1/callback

Google OAuth Client 生产域名配置页面

Google OAuth 的关键关系是:

txt
浏览器来源:
https://your-domain.com

Google 回调到 Supabase:
https://your-project-ref.supabase.co/auth/v1/callback

Supabase 再跳回你的网站:
https://your-domain.com/auth/callback

不要把这三个地址混在一起。

Google 页面会提示:

txt
设置可能需要 5 分钟到几小时才会生效

所以如果刚保存就测试失败,先等几分钟,再重新测试。

第 10 步:检查线上访问

正式域名配置完成后,至少检查这些 URL:

bash
curl -I https://your-domain.com
curl -I https://www.your-domain.com
curl -I https://your-domain.com/login
curl -s https://your-domain.com/robots.txt
curl -s https://your-domain.com/sitemap.xml | head

期望结果:

txt
首页返回 200
登录页返回 200
robots.txt 里的 Sitemap 使用正式域名
sitemap.xml 里的 loc 使用正式域名

如果 sitemap 里还是旧域名,通常说明:

txt
1. NEXT_PUBLIC_SITE_URL 没改
2. 改了环境变量但没有重新部署
3. 代码里写死了旧域名

第 11 步:检查登录注册流程

打开正式站:

txt
https://your-domain.com/login

测试邮箱注册:

txt
1. 输入邮箱和密码
2. 点击注册
3. 如果开启邮件确认,检查邮箱是否收到确认邮件
4. 确认后回到网站
5. 检查是否进入用户中心

测试邮箱登录:

txt
1. 使用已经注册的邮箱和密码登录
2. 检查是否进入 /account
3. 刷新页面,确认仍然保持登录
4. 退出登录,确认受保护页面不能访问

测试 Google 登录:

txt
1. 点击使用 Google 登录
2. 跳转到 Google 账号选择页
3. 授权后回到网站
4. 检查是否进入 /account
5. 在 Supabase Authentication -> Users 里确认用户记录存在

Google 授权链路异常时,优先检查:

txt
1. Google Cloud JavaScript origin 是否包含正式域名
2. Google Cloud redirect URI 是否是 Supabase callback
3. Supabase URL Configuration 是否包含正式 /auth/callback
4. 代码里的 redirectTo 是否指向正式域名
5. Vercel 是否已经重新部署

第 12 步:生产环境安全检查

上线后做一次最小安全检查。

环境变量:

txt
1. service role key 不允许出现在 NEXT_PUBLIC_ 变量里
2. Vercel token 不要写进仓库
3. .env.local 不要提交到 Git
4. 用过的临时 token 及时撤销

Supabase:

txt
1. public 表必须开启 RLS
2. 策略只允许用户读写自己的数据
3. 不要在前端调用 service role key
4. Auth Redirect URLs 不要随便配置通配符

Cloudflare:

txt
1. DNS 记录不要保留旧平台冲突记录
2. 初期保持 DNS only
3. 如果开启代理,重新检查 Vercel 证书、跳转和缓存

Google OAuth:

txt
1. JavaScript origins 只放可信域名
2. Redirect URIs 只放 Supabase callback
3. 如果仍处于 Testing,需要把测试账号加入测试用户
4. 正式发布给公众用户前,检查 OAuth consent screen 状态

常见问题

1. 域名已经能打开,但 Vercel 还提示 DNS change recommended

先看 Vercel 推荐的记录类型和值。如果实际访问已经是 Vercel 200,通常不是致命问题,但建议最终按 Vercel 推荐记录调整。

Cloudflare 支持根域名 CNAME flattening,所以根域名也可以配置成 CNAME 指向 Vercel 推荐值。

2. www 可以打开,根域名打不开

检查 Cloudflare 是否只有 www 记录,缺少 @ 记录。

至少需要:

txt
@    -> Vercel
www  -> Vercel

3. 登录后跳回旧域名

检查三个地方:

txt
1. Vercel NEXT_PUBLIC_SITE_URL
2. Supabase Site URL
3. Supabase Redirect URLs

改完 Vercel 环境变量后必须重新部署。

4. Google 登录提示 redirect_uri_mismatch

说明 Google Cloud 的 Authorized redirect URIs 不匹配。

Supabase Auth 场景下,Google redirect URI 应该是:

txt
https://your-project-ref.supabase.co/auth/v1/callback

不是:

txt
https://your-domain.com/auth/callback

5. Google 登录提示 origin 不允许

检查 Google Cloud 的 Authorized JavaScript origins。

正式站必须包含:

txt
https://your-domain.com

不要带路径,不要写成 /auth/callback

6. robots.txt 或 sitemap.xml 还是旧域名

检查代码是否使用 NEXT_PUBLIC_SITE_URL 生成站点地址。

然后检查 Vercel Production 环境变量是否已更新,并重新部署。

最终上线清单

上线完成前,逐项确认:

txt
[ ] npm run build 本地通过
[ ] Vercel Production 部署成功
[ ] Vercel 绑定 root 域名
[ ] Vercel 绑定 www 域名
[ ] Cloudflare DNS 指向 Vercel
[ ] Cloudflare 代理状态是 DNS only
[ ] NEXT_PUBLIC_SITE_URL 是正式域名
[ ] Supabase Site URL 是正式域名
[ ] Supabase Redirect URLs 包含正式 /auth/callback
[ ] Google OAuth JavaScript origins 包含正式域名
[ ] Google OAuth redirect URI 是 Supabase callback
[ ] 首页返回 200
[ ] 登录页返回 200
[ ] robots.txt 使用正式域名
[ ] sitemap.xml 使用正式域名
[ ] 邮箱注册可用
[ ] 邮箱登录可用
[ ] Google 登录可用

这份清单全部通过后,项目才算完成一次基本可靠的生产上线。

下一步工作流