65

I have the following developement section of my development.yml file:

development:
  adapter: postgresql
  host: localhost
  database: testtb
  username: app_user
  password: ENV['APP_USER_POSTGRES_PASSWORD']     <= Troublesome line

When I open a rails console via bundle exec rails console and type ENV['APP_USER_POSTGRES_PASSWORD'] I get back the DB password I've specified in my local profile. However, when I start my rails server, it can't connect to the DB, failing with

PGError FATAL:  password authentication failed for user "app_user"

This was previously working when I had the DB password actually typed out in plain text, rather than trying to access it via ENV['...'], but for obvious reasons I want to keep the actual password out of this file entirely (and therefore out of the code repository) while still being able to commit other, non-secure changes to the database.yml file.

Is there something special about the syntax I'm missing, or are the environment variables for some reason not available when the database.yml file is being loaded?

jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • You might want to checkout this guide about configuration, and local variables : http://railsapps.github.io/rails-environment-variables.html tl;dnr: figaro gem can be useful for that. – Antzi May 02 '13 at 12:12
  • @Antzi Note that Figaro doesn't support database.yml as it's read before figaro config, according to Figaro's README. – mahemoff Dec 04 '13 at 13:11
  • Update: Figaro works now for database.yml on all Rails versions. https://github.com/laserlemon/figaro/pull/100 – mahemoff Apr 01 '14 at 21:54

2 Answers2

167

Update: Some people report in the comments that this doesn't work as of Rails 4.2.x.x. I haven't tried it myself, so YMMV.


Ah, finally figured out the simple solution - it accepts embedded Ruby:

password: <%= ENV['APP_USER_POSTGRES_PASSWORD'] %>
Nil
  • 174
  • 1
  • 3
  • 14
jefflunt
  • 33,527
  • 7
  • 88
  • 126
  • Great catch! Definitely works. Figaro should update their docs thanks to you. – rcd Jan 05 '14 at 22:09
  • 5
    jesus christ, you don't know how long I've spent on this checking and double checking my password. thanks! I guess I should remember that YAML ain't markup language but erb is. – Mike H-R Feb 14 '14 at 02:58
  • 1
    @MikeH-R - That's pretty much exactly how I felt when I finally figured this out. – jefflunt Jun 25 '14 at 13:57
  • 1
    This solution doesn't work in the console on Rails 4.2.5.1. It tries to send the whole string. – RubyRedGrapefruit Feb 02 '16 at 16:55
  • 1
    This is case sensitive. – ConstantineK Mar 26 '16 at 22:23
  • 1
    This is not working, I tried both upcase and downcase. for several times. I don't know what's wrong goes here, I have to hard code that to xxx.yml. – crazy_phage Apr 22 '16 at 13:46
  • @crazy_phage - This answer is several years old, but the `ENV` variable should still be available. The `APP_USER_POSTGRES_PASSWORD` is just the name of the environment variable I was using as an example, but yours will be whatever you set it to be. Check that the variable is set in your environment. – jefflunt Apr 23 '16 at 15:28
  • 1
    I wrote those envs in .zshrc file, I don't if this is the cause to this probelm? ENV['what'] can not be accessed from the rails application, that's really strange. – crazy_phage Apr 24 '16 at 07:21
  • 1
    I just want to add and clarify -- this **used to work** but it does *NOT* work anymore. I don't know why?? Version of Rails I assume. You can test out your database.yml file with this quick command: `bin/rails runner 'puts ActiveRecord::Base.configurations'` << this shows me that it's not pulling in environment vars even though I KNOW they are accessible... – FireDragon May 30 '16 at 04:33
  • @FireDragon Thanks a lot. – crazy_phage Jul 06 '16 at 05:32
  • 1
    @crazy_phage i figured out that you have to restart spring server to reload your environment variables in newer versions of Rails that uses spring -- see my answer below if this helps – FireDragon Jul 06 '16 at 20:17
31

Short and quick solution if you are running a Rails version > 4.2 Run the following command:

spring stop

..then run rails console or other rails command. My issue was that Spring server needed to be restarted in order to refresh/pickup my new ENV vars. I was starting up Rails console and it couldn't see them until I shut down Spring.

Previous versions of Rails didn't have this issue since they didn't use Spring server.

Another tool to help you troubleshoot -- Use the following command to print out your database.yml config. You can run it from the command line, but I prefer to run this within Rails console since then you can use awesome_print to make it pretty:

Within rails console:

puts ActiveRecord::Base.configurations

...or using awesome_print

ap ActiveRecord::Base.configurations

Or instead from the command line:

bin/rails runner 'puts ActiveRecord::Base.configurations'
Omer Aslam
  • 4,534
  • 6
  • 25
  • 24
FireDragon
  • 9,325
  • 4
  • 27
  • 34
  • 2
    I don't know why anyone would downvote this answer. It's perfectly valid (and also worked for me) +1 – This company is turning evil. Jul 05 '16 at 13:46
  • thank you @Kroltan, it is quite annoying how people will sometimes downvote a worthy question that actually helps others and then provide no reason why. haters gonna hate i guess. but i'm glad this helped you out. – FireDragon Jul 05 '16 at 21:16
  • 2
    I had issues with both rails console and rails runner and it was all because of this spring reset that is necessary in order to pick up the new env variables! thanks ;) – VAShhh Jan 30 '17 at 15:49
  • so every time when a version is deployed, should this spring needs to be stopped to pick up new variables? – Shanthakumar Aug 27 '18 at 04:44