Dan
Dan

Reputation: 3367

Passenger Ignoring RAILS_ENV

Background

I've got an env file with various variables depended upon by my Rails app, including RAILS_ENV, which is initialized to development in this file. I've also got database.yml file defining DB connections for my environments (below). When I run the rails console, everything looks as it should. Checking Rails.configuration.database_configuration[Rails.env] returns the following:

{"adapter"=>"postgresql",
"encoding"=>"utf8",
"database"=>"dev",
"username"=>"rails",
"password"=>"***",
"host"=>"localhost",
"pool"=>5,
"timeout"=>5000}

However, when I try to visit the app, I get a 502 and the following error is logged:

Exception ActiveRecord::NoDatabaseError in Rack application object (FATAL: database "prod" does not exist.

Obviously, the error message is accurate, but does not represent what I would expect to be happening.

I'm assuming this is a Passenger/Apache issue since running rails console everything is happy.

NOTE: I've seen this come up in other posts, so no -- there is no DATABASE_URL environment variable floating around overriding things from database.yml.

What I've Tried

  1. .bashrc: Passenger is supposed to source the bashrc for the user apache is running as, which in turn is setup to source the relevant env file.
  2. /etc/sysconfig/httpd: I've tried manually sourcing the file directly from Apache config and verified by dumping env to file when the script runs that the correct values are making it into the env, however this too does not change the broken behavior.

database.yml

development:
  adapter: postgresql
  encoding: utf8
  database: dev
  username: rails
  password: <%= ENV['RAILS_DB_PWD'] %>
  host: <%= ENV['RAILS_DB_HOST'] %>
  pool: 5
  timeout: 5000

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  adapter: postgresql
  encoding: utf8
  database: test
  username: rails
  password: <%= ENV['RAILS_DB_PWD'] %>
  host: <%= ENV['RAILS_DB_HOST'] %>
  pool: 5
  timeout: 5000

production:
  adapter: postgresql
  encoding: utf8
  database: prod
  username: rails
  password: <%= ENV['RAILS_DB_PWD'] %>
  host: <%= ENV['RAILS_DB_HOST'] %>
  port: 5432
  pool: 5
  timeout: 5000

Upvotes: 1

Views: 700

Answers (1)

max
max

Reputation: 102134

A better way to do this is by simply using the DATABASE_URL env var.

If you have both config/database.yml and ENV['DATABASE_URL'] set then Rails will merge the configuration together.
Rails Guides: Configuring a Database

common: &common
  adapter: postgresql
  encoding: utf8
  template: template0 # Required for UTF8 encoding
  pool: 5
  timeout: 5000

development:
  <<: *common
  database: dev

test:
  <<: *common
  database: test

production:
  <<: *common
  database: prod

I would generally recommend you avoid specifying DB user names and passwords in database.yml. Use the ENV vars Luke! While you are halfway there its better to stick to a convention over configuration approach rather than introducing seperate vars.

A litmus test for whether an app has all config correctly factored out of the code is whether the codebase could be made open source at any moment, without compromising any credentials. https://12factor.net/config

Upvotes: 1

Related Questions