You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Vercel部署的Next.js(Prisma+MySQL)应用中安全连接DigitalOcean受限MySQL

解决Vercel部署的Next.js+Prisma连接仅本地访问的DigitalOcean MySQL问题

因为你的MySQL仅允许本地(127.0.0.1)访问,且不想开放公网权限,Vercel服务器无法直接像本地那样手动建立SSH隧道,你可以通过以下两种方案实现安全连接:

方案一:在Prisma初始化前通过代码建立SSH隧道

这种方式无需修改数据库的访问规则,完全基于代码层实现加密隧道连接:

  1. 安装SSH隧道依赖
    在项目中安装tunnel-ssh轻量库:

    npm install tunnel-ssh
    
  2. 创建带隧道的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;
    
  3. 在Vercel配置环境变量
    添加以下环境变量到Vercel项目:

    • SSH_HOST: DigitalOcean Droplet的公网IP
    • SSH_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可直接配置为:
    mysql://DB_USER:DB_PASSWORD@DROPLET_IP:3306/DB_NAME
    
    注意:Vercel的出站IP可能会更新,需要定期维护规则,安全性不如方案一。

额外注意事项

  • 私钥转base64是为了避免环境变量中换行符导致的解析错误
  • Vercel Serverless Function冷启动时会重新建立隧道,可能有轻微延迟,可通过Edge Functions或调整函数超时时间优化
  • 确保MySQL用户仅允许从127.0.0.1(方案一)或Vercel IP段(方案二)访问,进一步加固安全

内容的提问来源于stack exchange,提问作者Ryan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 10:55:50