如何在Vercel部署的Next.js(Prisma+MySQL)应用中安全连接DigitalOcean受限MySQL
解决Vercel部署的Next.js+Prisma连接仅本地访问的DigitalOcean MySQL问题
因为你的MySQL仅允许本地(127.0.0.1)访问,且不想开放公网权限,Vercel服务器无法直接像本地那样手动建立SSH隧道,你可以通过以下两种方案实现安全连接:
方案一:在Prisma初始化前通过代码建立SSH隧道
这种方式无需修改数据库的访问规则,完全基于代码层实现加密隧道连接:
安装SSH隧道依赖
在项目中安装tunnel-ssh轻量库:npm install tunnel-ssh创建带隧道的Prisma客户端实例
新建lib/prisma.js文件,替换默认的Prisma初始化逻辑,先建立SSH隧道再初始化客户端:import { PrismaClient } from '@prisma/client'; import tunnel from 'tunnel-ssh'; let prisma; async function createPrismaClient() { // 从Vercel环境变量读取SSH隧道配置 const tunnelConfig = { host: process.env.SSH_HOST, // DigitalOcean Droplet的公网IP port: 22, username: process.env.SSH_USER, // Droplet的登录用户名 privateKey: Buffer.from(process.env.SSH_PRIVATE_KEY, 'base64'), // 私钥转base64后存入环境变量 dstHost: '127.0.0.1', // MySQL绑定的本地地址 dstPort: 3306, // MySQL端口 localHost: '127.0.0.1', localPort: 3307, // 本地映射端口(避免和本地MySQL冲突) }; // 建立SSH隧道 await tunnel(tunnelConfig); // 初始化Prisma客户端,连接到隧道映射的本地端口 const client = new PrismaClient({ datasources: { db: { url: `mysql://${process.env.DB_USER}:${process.env.DB_PASSWORD}@127.0.0.1:3307/${process.env.DB_NAME}`, }, }, }); return client; } // 确保在Vercel环境中只初始化一次客户端 if (process.env.NODE_ENV === 'production') { createPrismaClient().then((client) => { prisma = client; }); } else { if (!global.prisma) { createPrismaClient().then((client) => { global.prisma = client; prisma = client; }); } prisma = global.prisma; } export default prisma;在Vercel配置环境变量
添加以下环境变量到Vercel项目:SSH_HOST: DigitalOcean Droplet的公网IPSSH_USER: Droplet的登录用户名SSH_PRIVATE_KEY: 你的SSH私钥(先执行cat ~/.ssh/id_rsa | base64转成base64格式,避免换行符导致配置异常)DB_USER: MySQL的用户名DB_PASSWORD: MySQL的密码DB_NAME: 目标数据库名称
方案二:允许Vercel出站IP访问MySQL(可选)
如果你能接受仅开放给Vercel的出站IP段访问,可以修改DigitalOcean Droplet的防火墙规则:
- 登录DigitalOcean控制台,找到对应Droplet的防火墙,添加入站规则:允许
3306端口,来源为Vercel的出站IP段 - 此时
DATABASE_URL可直接配置为:
注意:Vercel的出站IP可能会更新,需要定期维护规则,安全性不如方案一。mysql://DB_USER:DB_PASSWORD@DROPLET_IP:3306/DB_NAME
额外注意事项
- 私钥转base64是为了避免环境变量中换行符导致的解析错误
- Vercel Serverless Function冷启动时会重新建立隧道,可能有轻微延迟,可通过Edge Functions或调整函数超时时间优化
- 确保MySQL用户仅允许从
127.0.0.1(方案一)或Vercel IP段(方案二)访问,进一步加固安全
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

