<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Andrei Maxim</title>
    <description>The latest articles on Forem by Andrei Maxim (@andreimaxim).</description>
    <link>https://forem.com/andreimaxim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F873127%2Fcfd8d6f8-f4d6-4e79-a834-28fada5dbab5.jpg</url>
      <title>Forem: Andrei Maxim</title>
      <link>https://forem.com/andreimaxim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/andreimaxim"/>
    <language>en</language>
    <item>
      <title>The Rails database.yml File</title>
      <dc:creator>Andrei Maxim</dc:creator>
      <pubDate>Sun, 09 Jul 2023 13:12:37 +0000</pubDate>
      <link>https://forem.com/andreimaxim/the-rails-databaseyml-file-4dm9</link>
      <guid>https://forem.com/andreimaxim/the-rails-databaseyml-file-4dm9</guid>
      <description>&lt;p&gt;I was browsing through the &lt;a href="https://leanpub.com/therails7way" rel="noopener noreferrer"&gt;"The Rails 7 Way"&lt;/a&gt; and I read the following paragraph:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An old best practice within the Rails community has been not to store &lt;code&gt;config/database.yml&lt;/code&gt; in version control. Foremost, if a hacker gained access to the application repository, they would have all the connection settings to your production database. Furthermore, developers on the team might have a different development and test database settings. This allows each developer working on the project to have their own copy of &lt;code&gt;config/database.yml&lt;/code&gt; that is not stored in version control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is definitely correct: most of the Rails developers I've worked with in the last 15 years thought it was a best practice to &lt;em&gt;not&lt;/em&gt; store &lt;code&gt;config/database.yml&lt;/code&gt; in the version control system. But is it still a best practice for modern Rails applications? &lt;/p&gt;

&lt;p&gt;Let's explore.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bit of history
&lt;/h2&gt;

&lt;p&gt;First, let's see how the file looked like in the initial version of Rails. This is a screenshot taken from &lt;a href="https://www.youtube.com/watch?v=Gzj723LkRJY" rel="noopener noreferrer"&gt;DHH's now famous 15 minute blog video from 2005&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnnr044hg7b8g6cnwiva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpnnr044hg7b8g6cnwiva.png" alt="The original database.yml"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The initial &lt;code&gt;database.yml&lt;/code&gt; was very simple (most likely on purpose) and basically contained just this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;However, people quickly noticed that there is a lot of repetition so it became common to use YAML merge keys to remove duplication, so the above &lt;code&gt;database.yml&lt;/code&gt; would be converted to this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;defaults&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;

&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;

&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*defaults&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This approach became popular and it was included in the &lt;a href="https://www.amazon.com/Rails-Recipes-Pragmatic-Programmers-Fowler/dp/0977616606" rel="noopener noreferrer"&gt;"Rails Recipes" book by Chad Fowler&lt;/a&gt;. I think David tries to do something similar in the 15 minute video (at &lt;a href="https://youtu.be/Gzj723LkRJY?t=189" rel="noopener noreferrer"&gt;3:09&lt;/a&gt;), but messes up the YAML syntax.&lt;/p&gt;

&lt;p&gt;Now, the obvious issue is that you need a username and a password to connect to a database for development, but not all developers use the &lt;code&gt;root&lt;/code&gt; database account and it was a significant security issue to share the production database password via source control. &lt;/p&gt;

&lt;p&gt;In order to tackle this problem, developers generally opted for one of the following approaches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;check in a &lt;code&gt;config/database.yml.example&lt;/code&gt; file and configure the version control software to ignore &lt;code&gt;config/database.yml&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;check in the &lt;code&gt;config/database.yml&lt;/code&gt; file, but use Erb to fill values like &lt;code&gt;username&lt;/code&gt; or &lt;code&gt;password&lt;/code&gt; from environment variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In both cases, the differences were minimal since most teams had some sort of automation in place (like &lt;a href="https://github.com/rails/rails/pull/15189" rel="noopener noreferrer"&gt;using the &lt;code&gt;bin/setup&lt;/code&gt; script&lt;/a&gt;). However, I've seen a preference for the first approach because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers couldn't accidentally commit credentials to the &lt;code&gt;config/database.yml&lt;/code&gt; since it was ignored&lt;/li&gt;
&lt;li&gt;Capistrano had built-in support for symlink-ing the database configuration after deployment (the &lt;a href="https://capistranorb.com/documentation/getting-started/configuration/" rel="noopener noreferrer"&gt;&lt;code&gt;linked_files&lt;/code&gt; variable documentation specifically mentions &lt;code&gt;database.yml&lt;/code&gt;&lt;/a&gt;) which would fail if there was a file already present&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Changes in the last decade
&lt;/h2&gt;

&lt;p&gt;The issue of storing secrets like passwords was not limited to databases as more and more applications started integrating with third-party services like Amazon S3.&lt;/p&gt;

&lt;p&gt;Storing credentials required several iterations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rails 4.1 &lt;a href="https://guides.rubyonrails.org/4_1_release_notes.html#config-secrets-yml" rel="noopener noreferrer"&gt;added support for &lt;code&gt;config/secrets.yml&lt;/code&gt;&lt;/a&gt;, as a unified interface for interacting with secrets&lt;/li&gt;
&lt;li&gt;Based on the work done on the &lt;code&gt;sekrets&lt;/code&gt; gem, Rails 5.1 introduced &lt;a href="https://guides.rubyonrails.org/5_1_release_notes.html#encrypted-secrets" rel="noopener noreferrer"&gt;encrypted secrets&lt;/a&gt;, so you could check in an encrypted &lt;code&gt;config/secrets.yml.enc&lt;/code&gt; with all the required secrets and use a master key to decode it&lt;/li&gt;
&lt;li&gt;Rails 5.2 &lt;a href="https://github.com/rails/rails/pull/30067" rel="noopener noreferrer"&gt;switched to credentials&lt;/a&gt; and deprecated &lt;code&gt;config/secrets.yml.enc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Rails 6.0 added support for &lt;a href="https://github.com/rails/rails/pull/33521" rel="noopener noreferrer"&gt;encrypted credentials for multiple environments&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since the credentials are loaded before the &lt;code&gt;database.yml&lt;/code&gt; file is read, we could revisit the &lt;code&gt;defaults&lt;/code&gt; block so it uses the encrypted credentials:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;defaults&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= Rails.application.credentials.database_password %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;localhost&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;However, since Rails 4.1 there has been &lt;a href="https://github.com/rails/rails/pull/13582" rel="noopener noreferrer"&gt;support for the &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable which allowed you to override the &lt;code&gt;config/database.yml&lt;/code&gt; settings&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;This is useful for platforms like Heroku because now they can provide a &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable with the entire connection path and override the database name (for example) in you &lt;code&gt;config/database.yml&lt;/code&gt; (previously Heroku's approach was to write a new file, which can cause other issues).&lt;/p&gt;

&lt;h2&gt;
  
  
  Improving the defaults
&lt;/h2&gt;

&lt;p&gt;Ruby on Rails has been around for almost two decades and many defaults changed quite a lot, including the database settings, in order to make the developer experience great out of the box. &lt;/p&gt;

&lt;p&gt;I'd argue we can trade a bit of convenience when it comes to the initial setup for the ability to allow colleagues to run the database however they see fit since some might not be comfortable with a passwordless MySQL root account and some might not want the extra hassle of using a password.&lt;/p&gt;

&lt;h3&gt;
  
  
  MySQL
&lt;/h3&gt;

&lt;p&gt;If you create a new Rails 7.0 application, the default &lt;code&gt;config/database.yml&lt;/code&gt; looks like this, assuming you have selected MySQL as the database:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# MySQL. Versions 5.5.8 and up are supported.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Install the MySQL driver&lt;/span&gt;
&lt;span class="c1"&gt;#   gem install mysql2&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Ensure the MySQL gem is defined in your Gemfile&lt;/span&gt;
&lt;span class="c1"&gt;#   gem "mysql2"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# And be sure to use new-style password hashing:&lt;/span&gt;
&lt;span class="c1"&gt;#   https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql2&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;utf8mb4&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;socket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/run/mysqld/mysqld.sock&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;

&lt;span class="c1"&gt;# Warning: The database defined as "test" will be erased and&lt;/span&gt;
&lt;span class="c1"&gt;# re-generated from your development database when you run "rake".&lt;/span&gt;
&lt;span class="c1"&gt;# Do not set this db to the same as development or production.&lt;/span&gt;
&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;

&lt;span class="c1"&gt;# As with config/credentials.yml, you never want to store sensitive information,&lt;/span&gt;
&lt;span class="c1"&gt;# like your database password, in your source code. If your source code is&lt;/span&gt;
&lt;span class="c1"&gt;# ever seen by anyone, they now have access to your database.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Instead, provide the password or a full connection URL as an environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable when you boot the app. For example:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# If the connection URL is provided in the special DATABASE_URL environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable, Rails will automatically merge its configuration values on top of&lt;/span&gt;
&lt;span class="c1"&gt;# the values provided in this file. Alternatively, you can specify a connection&lt;/span&gt;
&lt;span class="c1"&gt;# URL environment variable explicitly:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   production:&lt;/span&gt;
&lt;span class="c1"&gt;#     url: &amp;lt;%= ENV["MY_APP_DATABASE_URL"] %&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database&lt;/span&gt;
&lt;span class="c1"&gt;# for a full overview on how database connection configuration can be specified.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV["BLOG_DATABASE_PASSWORD"] %&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here are some thoughts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We don't need the first eleven lines of comments after the initial application setup since the &lt;code&gt;mysql2&lt;/code&gt; gem will be added to the &lt;code&gt;Gemfile&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We can move the &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;password&lt;/code&gt; and &lt;code&gt;socket&lt;/code&gt; settings to the default &lt;code&gt;~/.my.cnf&lt;/code&gt; configuration file, allowing developers to set them up as they see fit&lt;/li&gt;
&lt;li&gt;In most cases, we'll define a &lt;code&gt;DATABASE_URL&lt;/code&gt; in the production environment, overriding whatever settings we have in our database configuration file, so the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt; section can be removed, keeping the comments so people looking for the credentials will know what to look for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's the slightly better &lt;code&gt;config/database.yml&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mysql2&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;utf8mb4&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;
  &lt;span class="na"&gt;default_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~/.my.cnf&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;

&lt;span class="c1"&gt;# Warning: The database defined as "test" will be erased and&lt;/span&gt;
&lt;span class="c1"&gt;# re-generated from your development database when you run "rake".&lt;/span&gt;
&lt;span class="c1"&gt;# Do not set this db to the same as development or production.&lt;/span&gt;
&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;

&lt;span class="c1"&gt;# As with config/credentials.yml, you never want to store sensitive information,&lt;/span&gt;
&lt;span class="c1"&gt;# like your database password, in your source code. If your source code is&lt;/span&gt;
&lt;span class="c1"&gt;# ever seen by anyone, they now have access to your database.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Instead, provide the password or a full connection URL as an environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable when you boot the app. For example:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# If the connection URL is provided in the special DATABASE_URL environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable, Rails will automatically merge its configuration values on top of&lt;/span&gt;
&lt;span class="c1"&gt;# the values provided in this file. Alternatively, you can specify a connection&lt;/span&gt;
&lt;span class="c1"&gt;# URL environment variable explicitly:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   production:&lt;/span&gt;
&lt;span class="c1"&gt;#     url: &amp;lt;%= ENV["MY_APP_DATABASE_URL"] %&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database&lt;/span&gt;
&lt;span class="c1"&gt;# for a full overview on how database connection configuration can be specified.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Here's a sample &lt;code&gt;~/.my.cnf&lt;/code&gt; file:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

[client]
user = andrei
password = AMERCE_sewage9borsch
socket = /var/run/mysqld/mysqld.sock


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  PostgreSQL
&lt;/h3&gt;

&lt;p&gt;The Rails generated &lt;code&gt;config/database.yml&lt;/code&gt; for a PostgreSQL database looks like this:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# PostgreSQL. Versions 9.3 and up are supported.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Install the pg driver:&lt;/span&gt;
&lt;span class="c1"&gt;#   gem install pg&lt;/span&gt;
&lt;span class="c1"&gt;# On macOS with Homebrew:&lt;/span&gt;
&lt;span class="c1"&gt;#   gem install pg -- --with-pg-config=/usr/local/bin/pg_config&lt;/span&gt;
&lt;span class="c1"&gt;# On macOS with MacPorts:&lt;/span&gt;
&lt;span class="c1"&gt;#   gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config&lt;/span&gt;
&lt;span class="c1"&gt;# On Windows:&lt;/span&gt;
&lt;span class="c1"&gt;#   gem install pg&lt;/span&gt;
&lt;span class="c1"&gt;#       Choose the win32 build.&lt;/span&gt;
&lt;span class="c1"&gt;#       Install PostgreSQL and put its /bin directory on your path.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Configure Using Gemfile&lt;/span&gt;
&lt;span class="c1"&gt;# gem "pg"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="c1"&gt;# For details on connection pooling, see Rails configuration guide&lt;/span&gt;
  &lt;span class="c1"&gt;# https://guides.rubyonrails.org/configuring.html#database-pooling&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;

  &lt;span class="c1"&gt;# The specified database role being used to connect to postgres.&lt;/span&gt;
  &lt;span class="c1"&gt;# To create additional roles in postgres see `$ createuser --help`.&lt;/span&gt;
  &lt;span class="c1"&gt;# When left blank, postgres will use the default role. This is&lt;/span&gt;
  &lt;span class="c1"&gt;# the same name as the operating system user running Rails.&lt;/span&gt;
  &lt;span class="c1"&gt;#username: blog&lt;/span&gt;

  &lt;span class="c1"&gt;# The password associated with the postgres role (username).&lt;/span&gt;
  &lt;span class="c1"&gt;#password:&lt;/span&gt;

  &lt;span class="c1"&gt;# Connect on a TCP socket. Omitted by default since the client uses a&lt;/span&gt;
  &lt;span class="c1"&gt;# domain socket that doesn't need configuration. Windows does not have&lt;/span&gt;
  &lt;span class="c1"&gt;# domain sockets, so uncomment these lines.&lt;/span&gt;
  &lt;span class="c1"&gt;#host: localhost&lt;/span&gt;

  &lt;span class="c1"&gt;# The TCP port the server listens on. Defaults to 5432.&lt;/span&gt;
  &lt;span class="c1"&gt;# If your server runs on a different port number, change accordingly.&lt;/span&gt;
  &lt;span class="c1"&gt;#port: 5432&lt;/span&gt;

  &lt;span class="c1"&gt;# Schema search path. The server defaults to $user,public&lt;/span&gt;
  &lt;span class="c1"&gt;#schema_search_path: myapp,sharedapp,public&lt;/span&gt;

  &lt;span class="c1"&gt;# Minimum log levels, in increasing order:&lt;/span&gt;
  &lt;span class="c1"&gt;#   debug5, debug4, debug3, debug2, debug1,&lt;/span&gt;
  &lt;span class="c1"&gt;#   log, notice, warning, error, fatal, and panic&lt;/span&gt;
  &lt;span class="c1"&gt;# Defaults to warning.&lt;/span&gt;
  &lt;span class="c1"&gt;#min_messages: notice&lt;/span&gt;

&lt;span class="c1"&gt;# Warning: The database defined as "test" will be erased and&lt;/span&gt;
&lt;span class="c1"&gt;# re-generated from your development database when you run "rake".&lt;/span&gt;
&lt;span class="c1"&gt;# Do not set this db to the same as development or production.&lt;/span&gt;
&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;

&lt;span class="c1"&gt;# As with config/credentials.yml, you never want to store sensitive information,&lt;/span&gt;
&lt;span class="c1"&gt;# like your database password, in your source code. If your source code is&lt;/span&gt;
&lt;span class="c1"&gt;# ever seen by anyone, they now have access to your database.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Instead, provide the password or a full connection URL as an environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable when you boot the app. For example:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# If the connection URL is provided in the special DATABASE_URL environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable, Rails will automatically merge its configuration values on top of&lt;/span&gt;
&lt;span class="c1"&gt;# the values provided in this file. Alternatively, you can specify a connection&lt;/span&gt;
&lt;span class="c1"&gt;# URL environment variable explicitly:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   production:&lt;/span&gt;
&lt;span class="c1"&gt;#     url: &amp;lt;%= ENV["MY_APP_DATABASE_URL"] %&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database&lt;/span&gt;
&lt;span class="c1"&gt;# for a full overview on how database connection configuration can be specified.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;
  &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV["blog_DATABASE_PASSWORD"] %&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;There are slightly more comments than the default MySQL version, but this is most likely because the out-of-the-box setup with PostgreSQL and Rails might not work.&lt;/p&gt;

&lt;p&gt;The first thing you need to do is create a superuser account that matches your system username, so you can create and destroy databases (there are more granular permissions, but we're talking about a development machine, so...):&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="n"&gt;andrei&lt;/span&gt; &lt;span class="n"&gt;superuser&lt;/span&gt; &lt;span class="n"&gt;login&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="s1"&gt;'accursed5ground_BACILLI'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Just replace &lt;code&gt;andrei&lt;/code&gt; with your account name.&lt;/p&gt;

&lt;p&gt;Then, create a &lt;code&gt;~/.pgpass&lt;/code&gt; file that stores the password. Here's an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

localhost:*:*:andrei:accursed5ground_BACILLI


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Just keep in mind that the &lt;code&gt;.pgpass&lt;/code&gt; file does not behave the same as the &lt;code&gt;~/.my.cnf&lt;/code&gt; file, meaning that connecting to the localhost will not force the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;, but instead it will provide the password when the connection host, port, database and usename match a line.&lt;/p&gt;

&lt;p&gt;Then, we can apply the same treatment to the &lt;code&gt;config/database.yml&lt;/code&gt; file as we did before, however we don't have to specify a &lt;code&gt;default_file&lt;/code&gt; since Postgres uses the system account and picks up the &lt;code&gt;.pgpass&lt;/code&gt; file automatically:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;default&lt;/span&gt;
  &lt;span class="na"&gt;adapter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql&lt;/span&gt;
  &lt;span class="na"&gt;encoding&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unicode&lt;/span&gt;
  &lt;span class="c1"&gt;# For details on connection pooling, see Rails configuration guide&lt;/span&gt;
  &lt;span class="c1"&gt;# https://guides.rubyonrails.org/configuring.html#database-pooling&lt;/span&gt;
  &lt;span class="na"&gt;pool&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %&amp;gt;&lt;/span&gt;

&lt;span class="na"&gt;development&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_development&lt;/span&gt;


&lt;span class="c1"&gt;# Warning: The database defined as "test" will be erased and&lt;/span&gt;
&lt;span class="c1"&gt;# re-generated from your development database when you run "rake".&lt;/span&gt;
&lt;span class="c1"&gt;# Do not set this db to the same as development or production.&lt;/span&gt;
&lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_test&lt;/span&gt;

&lt;span class="c1"&gt;# As with config/credentials.yml, you never want to store sensitive information,&lt;/span&gt;
&lt;span class="c1"&gt;# like your database password, in your source code. If your source code is&lt;/span&gt;
&lt;span class="c1"&gt;# ever seen by anyone, they now have access to your database.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Instead, provide the password or a full connection URL as an environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable when you boot the app. For example:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase"&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# If the connection URL is provided in the special DATABASE_URL environment&lt;/span&gt;
&lt;span class="c1"&gt;# variable, Rails will automatically merge its configuration values on top of&lt;/span&gt;
&lt;span class="c1"&gt;# the values provided in this file. Alternatively, you can specify a connection&lt;/span&gt;
&lt;span class="c1"&gt;# URL environment variable explicitly:&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#   production:&lt;/span&gt;
&lt;span class="c1"&gt;#     url: &amp;lt;%= ENV["MY_APP_DATABASE_URL"] %&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Read https://guides.rubyonrails.org/configuring.html#configuring-a-database&lt;/span&gt;
&lt;span class="c1"&gt;# for a full overview on how database connection configuration can be specified.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="na"&gt;production&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*default&lt;/span&gt;
  &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blog_production&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's about it!&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>database</category>
    </item>
  </channel>
</rss>
