从Supabase迁移到Cloudflare D1,速度更快更省钱
1. 为什么迁移到Cloudflare?
之前NextJS项目从Vercel迁移到了CloudFlare,很重要的原因是Vercel 在使用量激增时容易产生高额账单,而 Cloudflare 则提供可预测、按使用量付费的模式。
虽然Vercel原生支持 Next.js 全栈功能,SSR/ISR 无缝运行;但Cloudflare 拥有 300+ 个全球节点,跑在全球边缘,响应延迟极低,而且配套完善。
2. 为什么从Supabase迁移到了CF D1?
当项目迁移到了Cloudflare之后,数据库连接的还是Supabase,但是随着项目的增多,Supabase free版本只支持两个project,更多的需要升级到Pro版本,需要$25/月。
那为什么不选择接入CF D1数据库呢?免费,而且与Cloudflare无缝集成,边缘场景下能避免额外网络开销。
3. 整体部署方案
先看一下当前整体的部署方案,项目为了部署到CF pages/workers上,需要使用OpenNext将NextJS生成物转化成CF平台上的。

- workers是属于边缘运行时,缩短了和用户之间的延迟,同时为了提升运行速度,对node运行时做了精简。
- OpenNext是个开源项目,为了让NextJs项目做到跨平台自托管,摆脱Vercel的限制。而OpenNext Cloudflare由CF团队运营,帮我解决这些维护和NextJS的更新适配问题。
4. 如何集成CF D1,适配开发和部署?
先看下面这个整体架构图

-
这个架构解决了下面几个问题:
1、 最重要的一点,NextJS项目开发,实时编译热加载,不影响开发效率
2、本地worker环境调试本地D1数据库;
3、NextJS项目转化成workers并部署;
4、Cloudflare workers集成D1数据库;
这里需要指出的是:
1、使用OpenNext转化workers时,需要编译生成,花费时间比较多,无法做到实时编译。
2、其中DrizzleORM主要提供两方面功能,屏蔽底层不同的数据库的差异。
- 针对数据库,提供统一的数据库连接和增删改查方式;
- 针对数据表,将TS的对象转换成表结构的SQL
4.1 具体配置实现
- 生产环境
D1数据库配置,具体内容根据自己项目配置
[[d1_databases]]
binding = "DB"
database_name = "***"
database_id = "***"
migrations_dir = "***"
D1数据库绑定
1export function db() {
2 if (isCloudflareWorker) {
3 // Cloudflare Workers 环境
4 const env = globalThis as any
5 if (!env.DB) {
6 throw new Error('D1 database binding not found')
7 }
8 return drizzle(env.DB)
9 }
10
11 return dbInstance
12}- 测试环境
配置本地数据库
1import 'dotenv/config'
2import { config } from 'dotenv'
3import { defineConfig } from 'drizzle-kit'
4
5config({ path: '.env' })
6config({ path: '.env.development' })
7config({ path: '.env.local' })
8
9export default defineConfig({
10 out: './src/db/migrations',
11 schema: './src/db/schema.ts',
12 dialect: 'sqlite',
13 dbCredentials: {
14 url: './.local.db',
15 },
16})本地数据库
1export function db() {
2 if (dbInstance) return dbInstance
3 const sqlite = new Database('./.local.db')
4 dbInstance = drizzleSqlite(sqlite)
5
6 return dbInstance
7}vscode安装SQLite Viewer插件,直接打开.local.db可查询
4.2 相关命令
1# drizzle 相关
2npx drizzle-kit generate
3npx drizzle-kit migrate
4
5## 启动本地node环境
6pnpm dev
7
8## nextjs编译生成workers产物
9opennextjs-cloudflare build
10
11## 启动本地workers环境
12wrangler dev
13
14## 部署到线上cf workers
15opennextjs-cloudflare deploy
165. 其他失败的尝试
-
node环境+DrizzleORM API:
本地node环境无法获取D1数据库绑定
-
node环境+DrizzleORM+ 自定义D1 adapter + D1 HTTP API:
当存取数据的时候,数据返回错误,是个DrizzleORM和D1 HTTP API适配的已知BUG
-
node环境,通过openNext适配到workers环境,然后连接本地D1环境开发:
每次改动代码都需要从NextJS到workers的环境,非常耗时