v0.app 的 Supabase、Blob 迁移到阿里云教程

用 v0.app 做了一个音乐播放器,v0 采用 Next.js + Supabase + Blob 来进行开发的,做好后,要把该项目部署到自己的服务器,因为部署到 v0 自己的服务器的话,国内访问不了。。。
简单介绍下:
- Next.js:v0 采用的前后端框架,属于 React
- Supabase:v0 采用的 supabase.com 的云数据库(包含用户验证等服务),免费的
- Blob:v0 采用的存储音乐等文件的云存储,收费的
部署项目
直接下载代码,部署到自己的服务器后,运行也很简单:
bash
npm install
npm run dev
然后公网访问就可以。但是有几个问题:
- Supabase.com 的云数据库是国外的,直接运行的话,国内也是访问不了网站的数据。。
- Blob 也是国外的云存储,国内访问很慢。。。
解决方案
首先,阿里云有提供免费的 Supabase(1 核 2G 的)。其次,阿里云也有提供云存储 OSS 。
所以,这两个迁移到阿里云就能保证国内访问速度了。
分别如何迁移
Blob 迁移
这个不用自己去修改代码,让v0自己改。下面内容发给v0即可:
请参考下面代码,把项目里面所有上传音乐等文件的,改为在前端直接上传到阿里云 OSS:
ts
import OSS from "ali-oss"
// STS 凭证缓存
let stsCache: {
credentials: any
expiration: number
} | null = null
// OSS 客户端缓存
let ossClientCache: OSS | null = null
/**
* 获取 STS 临时凭证
*/
async function fetchSTSCredentials() {
console.log("[v0] OSS: Fetching STS credentials...")
// 检查缓存是否有效(提前5分钟刷新)
if (stsCache && Date.now() < stsCache.expiration - 5 * 60 * 1000) {
console.log("[v0] OSS: Using cached STS credentials")
return stsCache.credentials
}
try {
// https://test.com/index/web_music_player/get_oss_sts改为自己服务器的阿里云oss临时授权接口,请查看阿里云oss文档进行设置
const response = await fetch("https://test.com/index/web_music_player/get_oss_sts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
})
if (!response.ok) {
throw new Error(`Failed to fetch STS credentials: ${response.status}`)
}
const data = await response.json()
console.log("[v0] OSS: STS credentials fetched successfully")
// 缓存凭证
stsCache = {
credentials: data.config,
expiration: new Date(data.config.Expiration).getTime(),
}
return data.config
} catch (error) {
console.error("[v0] OSS: Failed to fetch STS credentials:", error)
throw error
}
}
/**
* 创建 OSS 客户端(带缓存和自动刷新)
*/
async function createOSSClient(): Promise<OSS> {
console.log("[v0] OSS: Creating OSS client...")
// 如果客户端存在且凭证未过期,直接返回
if (ossClientCache && stsCache && Date.now() < stsCache.expiration - 5 * 60 * 1000) {
console.log("[v0] OSS: Using cached OSS client")
return ossClientCache
}
const credentials = await fetchSTSCredentials()
ossClientCache = new OSS({
region: 'oss-cn-hangzhou',
accessKeyId: credentials.AccessKeyId,
accessKeySecret: credentials.AccessKeySecret,
stsToken: credentials.SecurityToken,
authorizationV4: true,
endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
bucket: credentials.BucketName,
refreshSTSToken: async () => {
console.log("[v0] OSS: Refreshing STS token...")
const newCredentials = await fetchSTSCredentials()
return {
accessKeyId: newCredentials.AccessKeyId,
accessKeySecret: newCredentials.AccessKeySecret,
stsToken: newCredentials.SecurityToken,
}
},
refreshSTSTokenInterval: 3000000, // 50分钟刷新一次
})
console.log("[v0] OSS: OSS client created successfully")
return ossClientCache
}
/**
* 上传文件到阿里云 OSS
* @param file 要上传的文件
* @param folder 文件夹路径,如 'audio'、'images'、'videos'
* @returns 上传后的文件 URL
*/
export async function uploadToOSS(file: File, folder: string): Promise<string> {
console.log(`[v0] OSS: Starting upload for ${file.name} to folder ${folder}`)
console.log(`[v0] OSS: File size: ${(file.size / 1024 / 1024).toFixed(2)} MB`)
try {
const client = await createOSSClient()
// 生成文件名:tlbfq/folder/timestamp-filename
const timestamp = Date.now()
const fileName = `tlbfq/${folder}/${timestamp}-${file.name}`
console.log(`[v0] OSS: Uploading to ${fileName}...`)
// 上传文件
const result = await client.put(fileName, file, {
headers: {
"Content-Type": file.type,
},
})
console.log("[v0] OSS: Upload successful")
console.log("[v0] OSS: File URL:", result.url)
return result.url
} catch (error) {
console.error("[v0] OSS: Upload failed:", error)
throw error
}
}
/**
* 删除 OSS 文件
* @param fileUrl 文件 URL
*/
export async function deleteFromOSS(fileUrl: string): Promise<void> {
console.log(`[v0] OSS: Deleting file: ${fileUrl}`)
try {
const client = await createOSSClient()
// 从 URL 中提取文件路径
const url = new URL(fileUrl)
const fileName = url.pathname.substring(1) // 移除开头的 /
console.log(`[v0] OSS: Deleting ${fileName}...`)
await client.delete(fileName)
console.log("[v0] OSS: File deleted successfully")
} catch (error) {
console.error("[v0] OSS: Delete failed:", error)
throw error
}
}
Supabase 迁移
这个比较复杂,因为还涉及到迁移数据。
假设自己电脑是 Mac 系统,先安装导出工具:
bash
brew install postgresql@17
export PATH="/opt/homebrew/opt/postgresql@17/bin:$PATH"
安装完后验证:
bash
➜ ~ pg_dump --version
pg_dump (PostgreSQL) 17.7 (Homebrew)
然后,从 v0 复制 Supabase 链接和密码,点击 v0 聊天窗口右侧的 Vars,如下图:

然后把图片中圈起来的眼睛点开来,复制 POSTGRES_URL_NON_POOLING 的值,替换到下面的导出命令中:
bash
pg_dump \
"POSTGRES_URL_NON_POOLING" \
-Fc \
--verbose \
-f backup.dump
在 Mac 的终端运行命令后会输出如下:
pg_dump: 最后的内置 OID 是 16383
pg_dump: 读扩展
pg_dump: 识别扩展成员
pg_dump: 读取模式
...
这样就得到了 backup.dump,可以用于导入阿里云 Supabase。
开始申请免费的阿里云 Supabase:
阿里云 Supabase 指南
然后,创建项目。在"是否放开白名单限制"那边选择"是",注意数据库密码不能有特殊字符(如@!),用大小写和数字和下划线就可以了,数据库密码要存起来,等会儿要用。
稍微等下时间,等创建好后,点击管理,输入提供的账号密码后,就进入了supabase后台管理页面。
导入数据
在supabase后台管理页面,点击 Connect 并复制 DIRECT_URL 的值,如下图:


然后生成导入命令(替换 [YOUR-PASSWORD] 为自己设置的数据库密码):
bash
pg_restore \
-d "postgresql://postgres:[YOUR-PASSWORD]@sbp-bmzv1wkocfbp53cd.supabase.opentrust.net:5432/postgres" \
backup.dump
错误信息不用管,进入阿里云 Supabase 后台页面查看,已经有表格和数据了,说明顺利导入成功。
修改项目配置
在项目根目录创建 .env.local 文件,内容如下:
env
# ============================================
# Supabase 配置(阿里云)
# ============================================
NEXT_PUBLIC_SUPABASE_URL=https://sbp-test.supabase.opentrust.net
NEXT_PUBLIC_SUPABASE_ANON_KEY=test-key
SUPABASE_SERVICE_ROLE_KEY=test-role-key
# ============================================
# 数据库配置
# ============================================
POSTGRES_URL="postgresql://postgres:passwd@sbp-test.supabase.opentrust.net:5432/postgres"
POSTGRES_URL_NON_POOLING=postgresql://postgres:passwd@sbp-test.supabase.opentrust.net:5432/postgres
POSTGRES_PRISMA_URL=postgresql://postgres:passwd@sbp-test.supabase.opentrust.net:5432/postgres?pgbouncer=true
POSTGRES_USER=postgres # 这个不用改
POSTGRES_PASSWORD=passwd # 这个改为自己的数据库密码
POSTGRES_DATABASE=postgres # 这个不用改
POSTGRES_HOST=sbp-test.supabase.opentrust.net # 这个参考POSTGRES_URL的值来改下即可
获取 NEXT_PUBLIC_SUPABASE_URL 和 ANON_KEY 的方式如下图:

获取 POSTGRES_URL 的方式如下图:

POSTGRES_URL_NON_POOLING 和POSTGRES_PRISMA_URL 参考POSTGRES_URL的值来修改即可。
SUPABASE_SERVICE_ROLE_KEY 的值参考https://www.alibabacloud.com/help/zh/analyticdb/analyticdb-for-postgresql/user-guide/supabase/ 的 "使用Supabase项目" 的 "2. 获取API Keys"部分获取
配置完成后,重新运行:
bash
npm run dev
即可使用阿里云 Supabase。
顺便也说下,怎么在v0那边直接修改配置,让v0也连接到阿里云的supabase,修改下图的值和上面.env.local中的一样即可:

还有,如果想查看v0的项目的数据库的内容的话,可以去下面查看:



好了,以上结束。有问题欢迎讨论。