New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use DATABASE_URL by default #13578

Merged
merged 1 commit into from Jan 2, 2014

Conversation

Projects
None yet
2 participants
@schneems
Member

schneems commented Jan 2, 2014

See #13463 (comment) for full conversation.

I'm still looking into behavior of Active Record concerning environment variables. I would like to address consistency of behavior across multiple ways AR can be used, and re-visit the bike shed that is naming environment variables.

tl;dr I'm working on making behavior of Active Record consistent across all scenarios with regard to DATABASE_URL being present. I'm also recommending we switch back to using DATABASE_URL in the database.yml file. For more info read my super long explanations below.

Consistency of Environments

Here are all the ways that AR initiates a connection today:

  • Stand Alone (without rails)
    • rake db:<tasks>
    • ActiveRecord.establish_connection
  • With Rails
    • rake db:<tasks>
    • rails <server> | <console>
    • rails dbconsole

We should make all of these behave exactly the same way, which if you dig into AR is non-trivial. I'm working to see if I can put all of this logic in one place for consistency, but as I mentioned, it's a non-trivial task.

Currently AR can be configured via the environment variable DATABASE_URL or by manually injecting a hash of values which is what Rails does, reading in database.yml and setting AR appropriately. AR expects to be able to use DATABASE_URL without the use of Rails, and we cannot rip out this functionality without deprecating IMHO. This presents a problem though when both config is set, and a DATABASE_URL is present. Currently the DATABASE_URL should "win" and none of the values in database.yml are used. This is somewhat unexpected to me if I were to set values such as pool in the production: group of database.yml they are ignored. Here is my prosed matrix of how this behavior should work:

No database.yml
No DATABASE_URL
=> Error
database.yml present
No DATABASE_URL
=> Use database.yml configuration
No database.yml
DATABASE_URL present
=> use DATABASE_URL configuration
database.yml present
DATABASE_URL present
=> Merged into `url` sub key. If both specify `url` sub key, the `database.yml` `url` 
   sub key "wins". If other paramaters `adapter` or `database` are specified in YAML, 
   they are discarded as the `url` sub key "wins".

Implementation

I'm currently working on getting the above to work and be consistent with all environments, the last barrier I have to overcome is the Rake tasks. I expect this last bit to take 80% of the effort. This also brings me to my second topic: env var naming.

Env Var Naming

As I mentioned above, AR already has built in support for DATABASE_URL and as of today if DATABASE_URL is present, the database.yml values won't be used at all. If I am able to implement and get accepted my above proposal, this won't be much of an issue but right now it is.

I was originally 馃憤 on name-spacing the environment variables with RAILS_ though after digging in AR for a few days and thinking about it more, I think we should use non-namespaced urls, so DATABASE_URL instead of RAILS_DATABASE_URL. Why?

DATABASE_URL isn't just a Rails concept, it's actually used in other frameworks, most notably: DATABASE_URL is used in django. And there's no reason it cannot be used in other frameworks.

One of the initial reasons for namespacing was to prevent conflicts between different languages running on the same box. I think this is the minority case, a more likely use case would be multiple Rails applications on the same box. Using the RAILS_ namespacing would do nothing to help there. If you wanted truly multi-tennant database url connections they would need to be something like RAILS_<appname>_<uuid>_DATABASE_URL which is unweildy to work with and likely causes more problems than it solves.

Deployment seems to be leaning towards using containers (through LXC, docker, or similar) which allows you to set a clean ENV per each app. If you need to deploy multiple apps to one box, you can use .env files, or your own custom database.yml setup. Any of these solutions eliminate the problem of cross app ENV var contamination.

By keeping this value standard, you could have your container generation code create a DATABASE_URL env var by default, and not have to worry about it. The alternative isn't horrible, you just alias export RAILS_DATABASE_URL=$DATABASE_URL but as I mentioned before, unless I (or someone else) fixes the above behavior this will cause unexpected behavior in your app, as database.yml gets ignored :grimmace:

I'm out to lunch on namespacing of SECRET_KEY_BASE, it's not already a pseudo-standard the way that DATABASE_URL has become. I also see no real benefit of keeping the RAILS_ namespace.

I'm interested in talking about this point more, right now I would recommend switching back from RAILS_DATABASE_URL => DATABASE_URL. I'm happy to do all the conversion work here.

rafaelfranca added a commit that referenced this pull request Jan 2, 2014

@rafaelfranca rafaelfranca merged commit 5aa8698 into rails:master Jan 2, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment