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

Rails 7无法从环境变量读取数据库密码问题排查求助

Rails 7.0.4.3 容器部署中数据库密码为nil的排查与解决

问题场景

我有一个Rails 7.0.4.3应用,部署在远程服务器的Docker容器中,启动时出现数据库连接错误,提示无密码提供。容器控制台和rails控制台中能正常获取到DATABASE_PASSWORD环境变量,但执行Rails.configuration.database_configuration后,对应环境的password值始终为nil。

database.yaml配置

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 10
  postgis_schema: public
  schema_search_path: public,postgresql
  host: <%= ENV.fetch("DATABASE_HOST") { "localhost" } %>
  port: <%= ENV.fetch("DATABASE_PORT") { 5432 } %>
  username: <%= ENV.fetch("DATABASE_USERNAME") { %x(whoami).strip } %>
  password: <%= ENV.fetch("DATABASE_PASSWORD") { "password" } %>

development:
  <<: *default
  username: 'postgres'
  password: 'password'
  database: <%= "#{ENV['PROJECT_NAME']}_development" %>

test:
  <<: *default
  username: 'postgres'
  password: 'password'
  database: <%= "#{ENV['PROJECT_NAME']}_test" %>

staging:
  <<: *default
  database: <%= "#{ENV['PROJECT_NAME']}_staging" %>

production:
  <<: *default
  database: <%= "#{ENV['PROJECT_NAME']}_production" %>

dev_remote:
  <<: *default
  database: <%= "#{ENV['PROJECT_NAME']}_dev_remote" %>

启动错误日志

rails aborted!
ActiveRecord::ConnectionNotEstablished: connection to server at "REDACTED", port 5438 failed: fe_sendauth: no password supplied

Caused by:
PG::ConnectionBad: connection to server at "REDACTED", port 5438 failed: fe_sendauth: no password supplied

配置检查结果

执行Rails.configuration.database_configuration输出(关键部分):

=> 
{"default"=>{"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>10, "postgis_schema"=>"public", "schema_search_path"=>"public,postgresql", "host"=>"REDACTED", "port"=>5438, "username"=>"user"},
 "staging"=>{"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>10, "postgis_schema"=>"public", "schema_search_path"=>"public,postgresql", "host"=>"REDACTED", "port"=>5438, "username"=>"user", "database"=>"project_staging"},
 "production"=>{"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>10, "postgis_schema"=>"public", "schema_search_path"=>"public,postgresql", "host"=>"REDACTED", "port"=>5438, "username"=>"user", "database"=>"project_production"},
 "dev_remote"=>{"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>10, "postgis_schema"=>"public", "schema_search_path"=>"public,postgresql", "host"=>"REDACTED", "port"=>5438, "username"=>"user", "database"=>"project_dev_remote", "password"=>nil}}

Dockerfile配置

FROM ruby:3.1.4-alpine

RUN apk add --update --no-cache bash build-base postgresql-dev tzdata git openssh ssmtp nano

WORKDIR /myapp
ENV RAILS_ENV $RAILS_ENV

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN gem install bundler -v 2.2.32 && bundle config set --local without 'development test' && bundle install -j $(nproc)

COPY . /myapp

RUN chmod +x /myapp/start-app.sh
CMD /myapp/start-app.sh

排查与解决步骤

  • 直接验证ERB渲染结果
    在容器内执行以下命令,查看database.yaml经过ERB渲染后的原始内容,确认password字段是否正确填充:

    erb config/database.yaml
    

    如果渲染后的password为空或异常,说明ERB解析或环境变量传递存在问题;如果渲染结果正确,问题则出在Rails加载配置的环节。

  • 修复YAML解析的特殊字符问题
    如果数据库密码包含&、#、空格等YAML特殊字符,未加引号的字符串可能被解析错误,导致password变为nil。修改database.yaml中的password行,强制用引号包裹:

    password: "<%= ENV.fetch("DATABASE_PASSWORD") { "password" } %>"
    
  • 检查Rails配置加载逻辑

    • 确认当前运行的RAILS_ENV,执行echo $RAILS_ENV验证环境是否匹配预期。
    • 在对应环境的rails控制台中,执行ActiveRecord::Base.configurations[Rails.env],再次确认password字段值。
    • 检查config/initializers/目录下的文件,是否有代码修改了数据库配置。
  • 确认Docker环境变量传递完整性

    • 检查启动容器的命令(或docker-compose配置),确保DATABASE_PASSWORD被正确传递到容器内。
    • 查看start-app.sh脚本内容,确认启动Rails进程时没有覆盖或丢失环境变量,建议用exec命令启动Rails,确保环境变量继承:
      exec bundle exec rails server -b 0.0.0.0
      
  • 清理Rails配置缓存
    生产/预发布环境下Rails会缓存配置文件,若之前的空配置被缓存,会导致问题。执行以下命令清理缓存:

    rm -rf tmp/cache
    

    重启容器后再验证配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:47:10