3c2alg
Last Updated: March 02, 2016
·
14.36K
· hopsoft
0fbffbe15c943a15957a0c7caf778039

Use Rails 4 secrets.yml for database config

Don't spread your configuration across multiple files. Here's how to leverage secrets.yml for your database config too.

  • Rename config/secrets.yml to config/secrets.yml.example
  • Commit
  • cp config/secrets.yml.example config/secrets.yml
  • Update .gitignore to include config/secrets.yml
  • Add the a database section to config/secrets.yml Note the explicit use of symbols.

    development:
      database:
        :host: localhost
        :name: my_project_development
        :username: root
        :password: password
    
    # add database section to all envs...
  • Update config/database.yml to look like something like this.

    default: &default
      host: <%= Rails.application.secrets[:database][:host] %>
      adapter: postgresql
      encoding: UTF8
      database: <%= Rails.application.secrets[:database][:name] %>
      pool: 10
      reaping_frequency: 30
      username: <%= Rails.application.secrets[:database][:username] %>
      password: <%= Rails.application.secrets[:database][:password] %>
    
    development: *default
    test: *default
    production: *default
Say Thanks
Respond

13 Responses
Add your response

15405
Steven wilson pen and ink by ergasterd d4syzje

But why ? We have database.yml for that propuse.

over 1 year ago ·
15412
645e3d650bbb6769aaa1ae84932b1bc6

This is what I like using Dotenv for, configuration files reference environment variables then they can be configured on the server or a .env file.

over 1 year ago ·
15416
Avatar

I was just chatting on Twitter about this exact topic. What timing. The advantages of this are stubbing and working with a clear API. Having ENV variables spread throughout the codebase can be hard to reason with. I'd like it if it were possible to add validation rules though ala a Yaml-backed ActiveModel record to mitigate malicious or simply invalid ENV variables.

over 1 year ago ·
15417
Avatar

I wouldn't limit this to Database configuration though.

@dvito I think the advantage of this vs just modifying database.yml is single source of truth though.

over 1 year ago ·
15429
Echo freelance

Excellent work.

over 1 year ago ·
15435
0fbffbe15c943a15957a0c7caf778039

We use this technique for the simplicity of having a single source of truth for all app configuration that's easy to manage & reason about.

We deploy with our apps with Docker & use Chef to provision the metal.

  • The canonical source of secrets.yml lives in our Chef setup
  • Chef copies the secrets.yml file to all servers in the cluster
  • Docker containers mount the directory where secrets.yml is kept
  • On startup, the containers copy secrets.yml to APP/config/secrets.yml then start the app

It's working nicely for us & removes the cognitive load of having configs spread across multiple files & environment variables. YMMV

over 1 year ago ·
15488
E0a4126e958fdd08425b773421732aad

You can load all your ENV vars to the application in the same place: But I tend to agree with 12 factors in that things should be based on ENV vars so that you can deploy without worrying about config files. This also works really well from things like Docker.

http://12factor.net/config

over 1 year ago ·
15498
10534 128567884189 828694189 2287781 3877042 n

Symfony2 uses something called Incenteev ParameterHandler which generates config (yml files) on the fly. I've ported it to ruby: https://github.com/khasinski/fillparams

You basically ship .dist (like .sample) files and during build it will ask for missing parameters. Useful for development (new developer doesn't have to guess where to look for config files and what else is there to configure). It copies missing parameters when you run it in non-interactive environment.

over 1 year ago ·
16777
1509185ff0d6276bdb18dc9e54f791cd

I ran into a lot of trouble getting this working in docker until I finally read all of the details around how nginx deals with environmental variables. In my scenario I could see all of my variables but when nginx started passenger, passenger would default to a local database and not see the environmental variables that I was passing.

https://github.com/phusion/passenger-docker#setting-environment-variables-in-nginx

over 1 year ago ·
17259
None

You'll want to change out the secrets in secrets.yml unless you are ok with those going out to the interweb

over 1 year ago ·
18862
Fc8316d8f8494a220141b60edbec0be7 normal

how to use secret.yml to production mode if you add that in .gitignore?

over 1 year ago ·
21084
None

Do you still use this approach? I'm trying it in Rails 4.2 and it seems like the secrets aren't available at the time the database.yml is parsed. I'm going to look into it some more but wanted to check in with you as well.

over 1 year ago ·
21086
None

Whoops - that was my mistake. I'm dynamically building the secrets.yml file and was doing it in an initializer. Initializers fire after database.yml gets parsed so the secrets weren't available to database.yml.

over 1 year ago ·