Rails没有正确读取database.yml中的环境变量

时间:2013-01-15 05:16:58

标签: database ruby-on-rails-3 environment-variables passenger

我的database.yml设置如下:

development:
  adapter: mysql2
  encoding: utf8
  database: devel
  username: root
  host: localhost
  port: 3306
  timeout: 5000

# ... snip ...

production:
  adapter: mysql2
  encoding: utf8
  database: prod
  username: <%= ENV["DB_USER"] %>
  password: <%= ENV["DB_PASSWORD"] %>
  host: <%= ENV["DB_HOST"] %>
  port: 3306
  timeout: 5000

但问题是,尽管设置了环境变量,但Rails并未正确阅读这些变量。当我在EC2上启动我的Phusion支持的Nginx服务器时,我收到此消息:

Access denied for user 'root'@'localhost' (using password: NO) (Mysql2::Error)

我确认Phusion正在生产环境中启动Rails;我将开发和测试配置中的用户名和主机更改为唯一名称,'root'@'localhost'始终显示为错误消息。此外,如果我将用户名和密码硬编码到YAML文件中,服务器将正常启动。

我怀疑我没有正确设置我的环境变量,因为MySQL一直声称我试图以没有密码的“root”身份登录。我最初从.bashrc文件导出它们,但在阅读this question后,我意识到这不是正确的方法。在四处搜索之后,我遇到了this blog post,所以我按照说明创建了这三个文件:

的/ usr /本地/ etc / env的

export RAILS_ENV=production
export DB_PASSWORD= (snip)
export DB_USER=doorbells

的/ usr /本地/ etc / ruby​​_wrapper

#!/bin/sh

source /usr/local/etc/env
exec /home/rooby/.rvm/wrappers/ruby-1.9.3-p362@doorbells-dev/ruby "$@"

/etc/profile.d/env.sh

#!/bin/sh

source /usr/local/etc/env

在我的nginx.conf文件中,我使用以下行:

passenger_ruby /usr/local/etc/ruby_wrapper;

我重新启动了我的服务器无济于事。有什么想法吗?

3 个答案:

答案 0 :(得分:2)

我在Ubuntu 12.04上遇到了同样的问题。

在我看过的nginx错误日志(/var/log/nginx/error.log/)中,

[ ... ]: [App 8509 stderr] /path/to/ruby_wrapper.sh: 2: /path/to/ruby_wrapper.sh: 
[ ... ]: [App 8509 stdout] 
[ ... ]: [App 8509 stderr] source: not found

/bin/sh似乎不理解source命令。因此,我已将其更改为简单.,它也是如此。

完整更改的ruby_wrapper.sh将如下所示:

#!/bin/sh

. /usr/local/etc/env
exec /home/rooby/.rvm/wrappers/ruby-1.9.3-p362@doorbells-dev/ruby "$@"

这对你有帮助吗?

答案 1 :(得分:2)

上述解决方案对我不起作用。但是,我找到了解决方案 How do I use variables in a YAML file?

我的.yml文件包含以下内容:

development:
gmail_username: <%= ENV["GMAIL_USERNAME"] %>
gmail_password: <%= ENV["GMAIL_PASSWORD"] %>

解决方案如下:

template = ERB.new File.new("path/to/config.yml.erb").read
processed = YAML.load template.result(binding)

因此,当您在.yml文件中引入scriptlet标记时,它更像是erb模板。因此,首先将其作为erb模板阅读,然后如上所示加载yml。

答案 2 :(得分:-5)

首先,使用

username: ENV["DB_USER"]
password: ENV["DB_PASSWORD"]
host: ENV["DB_HOST"]

代替

username: <%= ENV["DB_USER"] %>
password: <%= ENV["DB_PASSWORD"] %>
host: <%= ENV["DB_HOST"] %>