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

AWS Elastic Beanstalk部署Rails应用时无法连接AWS RDS数据库

解决AWS Elastic Beanstalk上Rails应用无法连接RDS数据库的问题

问题背景

基于Ruby 3.2.2、Rails 7.1和Bundler 2.5.23的Rails应用部署到AWS Elastic Beanstalk后,默认路由可正常访问,但调用涉及数据库查询的API时出现连接错误。数据库托管在AWS RDS上,已在app/config/database.yml中配置主机、数据库名、密码和用户名等信息,且在EC2实例上手动使用相同凭证可正常连接RDS。

报错信息

{
    "error": "Database connection error. Please check your database configuration.",
    "details": "We could not find your database: my_db. Available database configurations can be found in config/database.yml file.\n\nTo resolve this error:\n\n- Did you create the database for this app, or delete it? You may need to create your database.\n- Has the database name changed? Check your database.yml config has the correct database name.\n\nTo create your database, run:\n\n        bin/rails db:create\n"
}

现有配置

database.yml 内容

development:
  adapter: postgresql
  encoding: utf8
  database: <%= ENV['database_name'] %> #musea_staging
  pool: 5
  username: <%= ENV['database_username'] %>
  password: <%= ENV['database_password'] %>
  host: <%= ENV['database_url'] %>
  port: <%= ENV['database_port'] %>
  reaping_frequency: 10

staging:
  adapter: postgresql
  encoding: utf8
  database: musea_staging
  pool: <%= ENV['database_pool'] %>
  username: <%= ENV['database_username'] %>
  password: <%= ENV['database_password'] %>
  host: <%= ENV['database_url'] %>
  port: <%= ENV['database_port'] %>
  reaping_frequency: 10

beta:
  adapter: postgresql
  database: musea_beta
  encoding: utf8
  username: <%= ENV['database_username'] %>
  port: <%= ENV['database_port'] %>
  password: <%= ENV['database_password'] %>
  host: <%= ENV['database_url'] %>
  pool: <%= ENV['database_pool'] %>
  reaping_frequency: 10

production:
  adapter: postgresql
  database: musea
  encoding: utf8
  username: <%= ENV['database_username'] %>
  port: <%= ENV['database_port'] %>
  password: <%= ENV['database_password'] %>
  host: <%= ENV['database_url'] %>
  pool: <%= ENV['database_pool'] %>
  reaping_frequency: 10

部署脚本

require 'aws-sdk'
require 'fileutils'
require 'yaml'

def current_branch
  `git rev-parse --abbrev-ref HEAD`.chomp
end

def current_sha
  `git rev-parse --short HEAD`.chomp
end

def archive_path(name)
  File.join(File.expand_path(File.dirname(__FILE__)), "#{name}-#{current_sha}.zip")
end

def export_archive(archive_path, branch)
  `git archive --format zip --output #{archive_path} #{branch}`
end

def upload_archive(key, data_path)
  Aws.config.update({
    region: 'us-east-1',
    credentials: Aws::Credentials.new(
    ENV['deploy_aws_key'],
    ENV['deploy_aws_secret'])})

  s3_uploader = Aws::S3::FileUploader.new
  bucket_name = ENV['app_backup_bucket']
  retry_on_failure do
    s3_uploader.upload(data_path ,{bucket: bucket_name, key: key} )
    #s3.put_object(
      #bucket: bucket_name,
      #key: key,
      #content_type: "application/zip",
      #body: open(data_path)
    #)
  end
end

def retry_on_failure
  3.times do
    begin 
      return yield 
    rescue => e
      puts "#{e}. retrying operation"
    end
  end

  fail "3 attempts failed !!!"
end

def create_application_version(beanstalk, config, data_key)
  version_label = File.basename(data_key, '.zip')

  unless has_application_version?(beanstalk, config['application_name'], version_label)
    bucket_name = ENV['app_backup_bucket']
    beanstalk.create_application_version(
        application_name: config['application_name'],
        version_label: version_label,
        description: "Created by deployment script.",
        source_bundle: {
            s3_bucket: bucket_name,
            s3_key: data_key,
        },
        auto_create_application: false,
    )
  end
end

def has_application_version?(beanstalk, application_name, version_label)
  response = beanstalk.client.describe_application_versions(
    application_name: application_name
  )
  response.data[:application_versions].any? {|version| version[:version_label] == version_label}
end

def update_environment(beanstalk, config, data_key)
  beanstalk.client.update_environment(
    environment_name: config['environment_name'],
    version_label: File.basename(data_key, '.zip'),
  )
end

def deploy_application(config, branch)
  data_path = archive_path(config['application_name'])
  data_key = "#{config['application_name']}/#{File.basename(data_path)}"

  export_archive(data_path, branch)
  upload_archive(data_key, data_path)

  Aws.config.update({
    region: 'us-east-1',
    credentials: Aws::Credentials.new(
    ENV['deploy_aws_key'],
    ENV['deploy_aws_secret'])})

  beanstalk = Aws::ElasticBeanstalk::Client.new(region: 'us-east-1')

  create_application_version(beanstalk, config, data_key)
  update_environment(beanstalk, config, data_key)
  cleanup_local_archive(data_path)
end

def cleanup_local_archive(archive_file)
  FileUtils.rm_f(archive_file)
  puts "Cleaned up local archive"
end

def get_configuration
  yaml = File.join(File.dirname(File.expand_path(__FILE__)),'/beanstalk.yml')
  config = YAML.load_file(yaml)
end

namespace :beanstalk do

  desc 'Deploy application to Elastic Beanstalk'
  task :deploy => :environment do

    branch_config = get_configuration
    target = current_branch

    puts "Deploying branch #{target}."
    deploy_application(branch_config[target], target)
    puts "Deployed #{current_sha}."
  end

  desc 'Create archive without uploading'
  task :dry_run => :environment do

    branch_config = get_configuration
    target = current_branch

    puts "Creating archive for branch #{target}."
    dry_run(branch_config[target], target)
  end

end

排查与解决方案

  • 确认Rails运行环境:AWS Elastic Beanstalk默认使用production环境,若部署的是staging分支,需确保EB环境变量中设置RAILS_ENV=staging。报错中提到找不到my_db,说明当前加载的数据库名与配置不符,大概率是环境变量未正确设置导致Rails使用了错误的database.yml配置段。
  • 验证环境变量有效性:登录EB的EC2实例,执行printenv | grep RAILS_ENV和printenv | grep database_,确认所有数据库相关环境变量(database_username、database_password等)与手动连接时的凭证一致且已正确加载。
  • 检查database.yml环境匹配:若部署staging分支,确认EB环境对应staging配置段,该段数据库名为硬编码的musea_staging,无依赖未设置的环境变量。注意development段的database依赖ENV['database_name'],若误加载development环境且该变量未设置,会导致数据库找不到。
  • 确认数据库存在性:手动连接RDS后执行\l命令,查看对应环境的数据库(如staging的musea_staging)是否存在。
  • 检查安全组配置:确保EB的EC2安全组被允许访问RDS的安全组,RDS入站规则需开放5432端口给EB安全组。
  • 查看Rails日志:登录EB实例,查看/var/app/current/log/[对应环境].log(如production.log或staging.log),获取更详细的数据库连接错误信息,定位具体问题(如权限、主机地址错误等)。
  • 硬编码配置测试:若环境变量存在问题,可先在database.yml对应环境段硬编码所有正确的数据库信息(主机、用户名、密码、数据库名),重新部署测试,排除环境变量问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 07:17:32