如何在私有RDS实例上使用Prisma执行数据库迁移?
解决私有RDS环境下的Prisma迁移执行问题
方案1:本地环境+SSH隧道连接私有RDS执行迁移
- 先通过Terraform在公有子网创建堡垒机(Bastion Host),配置安全组允许堡垒机访问私有RDS的数据库端口。
- Terraform apply完成后,在本地建立SSH端口转发:
ssh -L 5432:<RDS实例端点>:5432 ec2-user@<堡垒机公网IP> -i <你的密钥文件>.pem - 临时用本地转发端口覆盖Prisma的数据库连接URL(可通过环境变量,避免修改配置文件):
DATABASE_URL="postgresql://<数据库用户名>:<密码>@localhost:5432<数据库名>?schema=public" npx prisma migrate deploy - 执行完成后,关闭SSH隧道即可。
方案2:将迁移逻辑打包为Serverless一次性执行函数
- 在Serverless配置中,给临时迁移函数配置VPC权限,关联私有RDS所在的子网和安全组,确保函数能访问RDS。
- 编写简单的Node脚本封装迁移逻辑:
const { execSync } = require('child_process'); const { PrismaClient } = require('@prisma/client'); async function runMigration() { const prisma = new PrismaClient(); try { await prisma.$connect(); // 验证数据库连接 execSync('npx prisma migrate deploy', { stdio: 'inherit' }); console.log('迁移执行成功'); } catch (err) { console.error('迁移失败:', err); process.exit(1); } finally { await prisma.$disconnect(); process.exit(0); } } runMigration(); - 部署该函数后,通过Serverless CLI触发执行:
serverless invoke --function migrate-function - 迁移完成后可删除该临时函数,减少资源占用。
方案3:Terraform结合local-exec执行迁移(依赖本地环境可访问堡垒机)
- 在Terraform配置中添加null_resource,依赖RDS资源创建完成:
resource "null_resource" "prisma_migrate" { depends_on = [aws_db_instance.private_rds] provisioner "local-exec" { command = <<EOT # 建立后台SSH隧道 ssh -f -N -L 5432:${aws_db_instance.private_rds.endpoint}:5432 ec2-user@${aws_instance.bastion.public_ip} -i ~/.ssh/your-key.pem # 执行迁移 DATABASE_URL="postgresql://${aws_db_instance.private_rds.username}:${aws_db_instance.private_rds.password}@localhost:5432/${aws_db_instance.private_rds.db_name}?schema=public" npx prisma migrate deploy # 关闭SSH隧道 pkill -f "ssh -f -N -L 5432:${aws_db_instance.private_rds.endpoint}:5432" EOT } } - 确保本地已安装Prisma,且能通过SSH连接堡垒机,执行
terraform apply时会自动触发迁移。
核心注意事项
- 所有方案都要确保RDS安全组允许对应来源(堡垒机、Serverless子网、本地转发端口)的数据库端口访问。
- 生产环境优先使用
prisma migrate deploy,而非dev,保证迁移执行的确定性。 - 敏感信息(数据库密码、密钥)用环境变量或Terraform变量传递,禁止硬编码。
内容的提问来源于stack exchange,提问作者Willy wonka
相关产品推荐
相关产品推荐

