Maintain database.yml on server - ruby-on-rails

I have a Rails 4 app version controlled with git.
I would like to have a version of database.yml on my server that never changes. What's the best way to allow me to continue to edit this file locally, without changing the remote database.yml file?

You should include your local version of database.yml in .gitignore, so that it's not in the repository and won't change with subsequent deployments.
For instance, in your application root, create a ".gitignore" file and add the following in:
config/database.yml
You can also hide entire directories:
config/*
Basic shell wildcard syntax will work.
*.sql
Etc.

Take it out of version control, it shouldn't be there anyway.

We don't track our config/database.yml in version control (we do track a sample file so it's easier to get setup on new development machines). Our deployment script symlinks in a custom database.yml that's stored in the application user's home directory with permissions set to "600". This way the app user is the only user that can see the database password, and we don't have to do anything manual on deploy.

move database.yml to some secure folder, like /etc/config/database.yml and then create symlink
of that file with rails database.yml after deployment but before starting server.

Related

Rails app on Heroku doesn't seem to need database.yml file

I'm working on a Rails app with a few collaborators and we decided to begin using separate database.yml files for some time until we can a configuration that works for all of us.
After adding database.yml to the .gitignore file and pushing a version without it, I realized that this would likely prevent the Heroku app from running.
My confusion is that the deployment was successful and the database.yml file was not needed. Why is this? Is our old database.yml file cached?
This is actually the expected behavior. For more details see: https://devcenter.heroku.com/articles/rails-database-connection-behavior
Which boils down to (for Rails 4.1+):
While the default connection information will be pulled from
DATABASE_URL, any additional configuration options in your
config/database.yml will be merged in.
Heroku will always use DATABASE_URL and merge the rest from database.yml to the config contained in that url.
Ah yes the old db config developer war.
Heroku actually uses the solution to this issue - Rails merges the database configuration from database.yml with a hash created from parsing ENV["DATABASE_URL"]. The ENV var takes precedence over the file based configuration.
When you first push a Rails app, Heroku automatically attaches a Postgres addon and sets ENV["DATABASE_URL"] and presto your app magically connects to the database.
Even if you add complete nonsense settings like setting the database name in database.yml the ENV var still wins.
How can this solve our developer war?
Do the opposite of what you are currently doing. Strip everything except the bare minimum required to run the application out of database.yml and check it back into version control.
Developers can use direnv or one of the many tools available to set ENV[DATABASE_URL] to customize the settings while database.yml should be left untouched unless you actually need to tweak the db.

Different local database configuration Rails

I'm working in a team in a Rails project.
Each of us have a local database for development purpose. We have a problem: Everyone have different configuration for the local database. When someone make a commit without reset the /config/database.yml the other members of the team can't use their database because the access is not configured.
Can I have a local configuration not commited? To each one can works without problem and without the need of re-set the file every time? Sometime like the local_settings.py in Django
You can configure the database in Rails via both the config/database.yml file and the DATABASE_URL env var. They are merged but settings from DATABASE_URL take precedence.
A good solution is to check in the config/database.yml with a basic configuration thats just enough to support postgres.app or whatever is the most common solution.
Developers that need other settings can set the DATABASE_URL env var to customize the database configuration. Gems like figaro and dotenv make this easier.
If you have ever wondered this how Heroku manages to use the correct DB no matter what you throw into database.yml and the DATABASE_URL ENV var is how you should be configuring your production DB.
Why should I use ENV vars and not more database_*.yaml files?
The twelve-factor app stores config in environment variables (often
shortened to env vars or env). Env vars are easy to change between
deploys without changing any code; unlike config files, there is
little chance of them being checked into the code repo accidentally;
and unlike custom config files, or other config mechanisms such as
Java System Properties, they are a language- and OS-agnostic standard.
https://12factor.net/config
Add config/database.yml in to the .gitignore file at root path of your rails-app.
Copy config/database.yml with the values you need for production into config/database_example.yml.
Now you can modify your local database and in production you copy config/database_expample.yml to config/database.yml
If the config file is ignored by git, everyone can change it locally without getting tracked by git.
EDIT:
HERE YOU SEE HOW YOU CAN REMOVE FILE FROM TRACKING!!!
Ignore files that have already been committed to a Git repository

Which is the safest way to manage Rails database.yml?

Since database.yml file contains some private information, we shouldn't put it under version control.
I just dig out a bunch of solutions for sync database.yml to my server, such as this, I just want to know which is the safest way? Do I should only use scp to for that when I use Cap3 deploy?
You should just create the database.yml on your server manually when you first deploy, and then use Capistrano's linked_files directive to persist the file across deployments. I think the default capistrano configuration contains an example of using the linked_files directive for your database.yml.
Copy the database.yml during deployment from your development machine to your server to shared/db if it doesn't already exist. After deploy and before assets are compiled copy the database.yml to current/config/database.yml.

where to put secure passwords/keys in a rails app?

I have a few web services that require secure tokens/keys/passwords to be passed in. Where should I define these secure values for my rails app to see? I want the development keys in version control, but don't want the production keys in version control. How should I set this up? I'm new to rails.
You see the question properly.
Put your passwords and keys in some yml file excluded from version control.
Then on your production server, create the very same file and symlink your app to it every time you deploy.
EDIT.
Capistrano is almost made to fits these needs:
put your yml files in the shared folder
In your capistrano deploy.rbfile:
after 'deploy' do
run "ln -s #{shared_path}/database.yml #{release_path}/config/database.yml"
end
to work with yml files: http://railscasts.com/episodes/85-yaml-configuration-file
apneadiving is right, symlinking the files is a good idea. Another approach is to put the keys in the shell variables, accessible only to the user that runs the app. Then, in your rails app you'll have
login = ENV['SERVICE_LOGIN']
password = ENV['SERVICE_PASSWORD']
As of Rails 4.1.0, check out secrets.yml.

Files in gitignore

I have a repository with a rails app in the production Server.
In the repo there is the .gitignore file:
...
config/database.yaml
...
Every developing client have a cloned repo with different config/database.yaml.
My problem is this:
database.yaml is in .gitignore, then when I run git clone (on the server) the database.yaml will not be created, but I need it.
I thought than I am doing wrong something.
Can you see where is my mistake ?
thank you,
Alessandro
In my projects, I usually make a copy of a usable database config in a database.example.yml, then when someone clones the projects, copy the database.example.yml to database.yml and make the needed changes.
(here is a copy of my original answer to your first question)
You don't version the right file.
You should version:
a database.yaml.template
2 files (one for server values, and one for generic client values)
1 script able to build database.yaml on the checkout
That script would be called by the smudge step of a filter driver.
The resulting database.yaml would be "private" (never versioned/pushed or pulled), and can be modified at will.
keep a template like database.example.yml as robertokl suggests
when you deploy your application to production server you should be using something like capistrano and part of your capistrano recipe(script) will be to rename that file or to place the correct database.yml file in the config dir
All these database.yaml files have something in common: you can commit a base configuration, and let all your developing clients maintain a fork of it in their own branches with appropriate settings filled in; they can rebase on top of the base configuration in the master branch whenever it gets updated.
aleds - it's generally a bad idea to have your database.yml in a repository which is why you see it in .gitignore. robertokl is right about providing a template file.

Resources