如何连接Heroku数据库与Serverless Framework?Ruby on Rails服务数据库配置求助
Hey there! Let’s walk through how to set up database configuration in your serverless.yml and connect your Heroku database to Serverless Framework for your Ruby on Rails-based serverless service.
1. Configuring Database in serverless.yml
Serverless Framework uses serverless.yml to define infrastructure and runtime settings. For Rails, we’ll focus on environment variables (since Rails relies on these for database connections) and optionally defining cloud-hosted databases directly in the config.
Option A: Use Environment Variables (For Existing Databases)
Rails reads database credentials from environment variables by default, so we’ll pass these into our Lambda functions via serverless.yml:
provider: name: aws # Adjust if using another cloud provider (e.g., google, azure) runtime: ruby3.2 # Match your Ruby version environment: # Use a full database URL (simplest for Rails) DATABASE_URL: ${env:DATABASE_URL} # Or split into individual params if you need granular control # DB_HOST: ${env:DB_HOST} # DB_PORT: ${env:DB_PORT} # DB_NAME: ${env:DB_NAME} # DB_USER: ${env:DB_USER} # DB_PASSWORD: ${env:DB_PASSWORD}
Then update your Rails config/database.yml to reference these variables:
production: url: <%= ENV['DATABASE_URL'] %> # Or use individual params if you split them: # host: <%= ENV['DB_HOST'] %> # port: <%= ENV['DB_PORT'] %> # database: <%= ENV['DB_NAME'] %> # username: <%= ENV['DB_USER'] %> # password: <%= ENV['DB_PASSWORD'] %>
Option B: Define a Cloud Database Directly (e.g., AWS RDS)
If you want to deploy a new database alongside your serverless functions (instead of using Heroku), add a resources block to serverless.yml to define the infrastructure. Here’s an example for AWS RDS PostgreSQL:
provider: # Add VPC config so Lambda can access the RDS instance vpc: securityGroupIds: - !Ref LambdaSecurityGroup subnetIds: - ${env:SUBNET_1} - ${env:SUBNET_2} resources: Resources: # RDS Database Instance ServerlessRDS: Type: AWS::RDS::DBInstance Properties: AllocatedStorage: 20 DBInstanceClass: db.t3.micro Engine: PostgreSQL MasterUsername: ${env:DB_USER} MasterUserPassword: ${env:DB_PASSWORD} DBName: ${env:DB_NAME} PubliclyAccessible: false # Keep private for production VpcSecurityGroups: - !Ref DBSecurityGroup # Security Group for RDS (allow access from Lambda) DBSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow Lambda to access RDS VpcId: ${env:VPC_ID} SecurityGroupIngress: - IpProtocol: tcp FromPort: 5432 ToPort: 5432 SourceSecurityGroupId: !Ref LambdaSecurityGroup # Security Group for Lambda LambdaSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Lambda execution security group VpcId: ${env:VPC_ID}
2. Connecting Heroku Database to Serverless Framework
Heroku’s managed databases (like Heroku Postgres) provide a public connection URL that you can use to connect your serverless functions. Here’s how to set it up:
Step 1: Get Your Heroku Database URL
Use the Heroku CLI to fetch your database’s connection string:
heroku config:get DATABASE_URL -a your-heroku-app-name
Copy the output (it’ll look like postgres://user:password@host:port/dbname).
Step 2: Pass the URL to Serverless Functions
You have a few secure ways to inject this URL into your serverless deployment:
Method 1: Local Environment Variable
Create a .env file in your project root:
DATABASE_URL=your-heroku-db-url-here
Serverless will automatically read this when you run serverless deploy (make sure .env is in your .gitignore!).
Method 2: Cloud Parameter Store (For Production)
For production, store the encrypted URL in a service like AWS SSM Parameter Store, then reference it in serverless.yml:
provider: environment: DATABASE_URL: ${ssm:/your-service/production/database-url~true}
The ~true flag tells Serverless to decrypt the parameter before passing it to Lambda.
Step 3: Allow Serverless Access to Heroku Database
Heroku databases restrict IP access by default. You need to whitelist the IP addresses your Lambda functions use:
- If your Lambda runs in a VPC: Whitelist the VPC’s NAT gateway IP(s) in your Heroku database’s trust settings.
- If your Lambda runs in the public cloud: Whitelist Lambda’s public IP range (note: this can be dynamic, so using a VPC is more secure).
To update Heroku’s trust settings:
- Go to your Heroku Dashboard → Your App → Resources → Click your database.
- Navigate to Settings → Database credentials → Trust settings.
- Add the IP/CIDR range of your Lambda environment.
Step 4: Test the Connection
Add a simple Lambda handler to verify the connection works:
require 'active_record' require 'json' def handler(event:, context:) # Establish connection using the Heroku DB URL ActiveRecord::Base.establish_connection(ENV['DATABASE_URL']) # Run a test query (replace with your model) user_count = User.count { statusCode: 200, body: { total_users: user_count }.to_json } rescue => e { statusCode: 500, body: { error: e.message }.to_json } end
Make sure your Gemfile includes activerecord and any database adapters (e.g., pg for PostgreSQL), then deploy with serverless deploy.
Key Notes
- Security: Never hardcode database credentials in
serverless.yml. Use environment variables or parameter stores instead. - Performance: Lambda cold starts will re-establish database connections. For high-traffic apps, consider connection pooling or using a proxy like AWS RDS Proxy.
- Heroku Limits: Heroku databases have connection limits—ensure your Lambda concurrency doesn’t exceed this limit.
内容的提问来源于stack exchange,提问作者Chitra

