<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Simone Carletti&#039;s Blog &#187; database</title>
	<atom:link href="http://www.simonecarletti.com/blog/tags/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.simonecarletti.com/blog</link>
	<description>Simone Carletti&#039;s personal ramblings on programming, syndication, search engines &#38; marketing.</description>
	<lastBuildDate>Thu, 12 Jan 2012 09:16:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Capistrano and database.yml</title>
		<link>http://www.simonecarletti.com/blog/2009/06/capistrano-and-database-yml/</link>
		<comments>http://www.simonecarletti.com/blog/2009/06/capistrano-and-database-yml/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 07:06:26 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=363</guid>
		<description><![CDATA[How to create the database.yml file with Capistrano to prevent sensitive data to be stored in the application repository.]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-374" title="Capistrano logo" src="http://www.simonecarletti.com/blog/wp-content/uploads/2009/06/capistrano-logo.png" alt="Capistrano logo" width="150" height="57" />Last week, an user asked the <a href="http://www.capify.org/">Capistrano</a> mailing list about <a href="http://groups.google.com/group/capistrano/browse_thread/thread/3a71f99570647caf#">database password best practices</a>. This reminded me that I never posted here a Capistrano recipe I created almost one year ago to solve exactly this problem.</p>
<p>Which problem?</p>
<p>Imagine you need to deploy a new Rails application. As you probably know, Rails stores all the database configurations in a single file called <code>config/database.yml</code>, including database authentication credentials.</p>
<p>This file usually lives in your repository along with all your application code base. However, <strong>exposing real world passwords to all developers</strong> with read access to the repository can lead to <strong>major security problems</strong>. It&#8217;s likely you don&#8217;t want to store sensitive data in your repository, thus you need to automatically generate the config.yml file somehow on deploy or on setup.</p>
<p>If you are using Capistrano to deploy your Rails application, you <strong>can ask Capistrano to generate and upload the file for you</strong>. Let me show you how.<span id="more-363"></span></p>
<h2>One Problem, Many Solutions</h2>
<p>As usual, one problem comes with many different solution. That&#8217;s good because this is definitely better than a problem without a reasonable solution&#8230; do you agree?</p>
<p>As Robert James pointed out in its email, there are at least 3 different approaches to solve this issue.</p>
<ul>
<li>You can <strong>store sensitive data in your Capistrano deploy script.</strong> The downside of this solutions is that every developer with read access to the Capistrano script have access to the data as well.</li>
<li>You can <strong>store sensitive data on your server</strong>, but it requires some kind of manual setup.</li>
<li>You can <strong>use a password-less system</strong>, but this is probably the worst idea ever. Don&#8217;t misunderstand me, shared keys are a wonderful authentication system and I widely use them, but I didn&#8217;t find an effective alternative for database authentication.</li>
</ul>
<p>My recipes combines the second choice with some additional features, taking advantage of Capistrano ability to execute commands simultaneously on multiple servers.</p>
<h2>Capistrano database.yml task</h2>
<p>The recipe is <a href="http://gist.github.com/2769">available as a gist</a>. I think it is fairly self-explanatory and the documentation section at the beginning should give you a good overview of how it works.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">#<br />
# = Capistrano database.yml task<br />
#<br />
# Provides a couple of tasks for creating the database.yml<br />
# configuration file dynamically when deploy:setup is run.<br />
#<br />
# Category:: &nbsp; &nbsp;Capistrano<br />
# Package:: &nbsp; &nbsp; Database<br />
# Author:: &nbsp; &nbsp; &nbsp;Simone Carletti<br />
# Copyright:: &nbsp; 2007-2009 The Authors<br />
# License:: &nbsp; &nbsp; MIT License<br />
# Link:: &nbsp; &nbsp; &nbsp; &nbsp;http://www.simonecarletti.com/<br />
# Source:: &nbsp; &nbsp; &nbsp;http://gist.github.com/2769<br />
#<br />
#<br />
<br />
unless Capistrano::Configuration.respond_to?(:instance)<br />
&nbsp; abort &quot;This extension requires Capistrano 2&quot;<br />
end<br />
<br />
Capistrano::Configuration.instance.load do<br />
<br />
&nbsp; namespace :db do<br />
<br />
&nbsp; &nbsp; desc &lt;&lt;-DESC<br />
&nbsp; &nbsp; &nbsp; Creates the database.yml configuration file in shared path.<br />
<br />
&nbsp; &nbsp; &nbsp; By default, this task uses a template unless a template <br />
&nbsp; &nbsp; &nbsp; called database.yml.erb is found either is :template_dir <br />
&nbsp; &nbsp; &nbsp; or /config/deploy folders. The default template matches <br />
&nbsp; &nbsp; &nbsp; the template for config/database.yml file shipped with Rails.<br />
<br />
&nbsp; &nbsp; &nbsp; When this recipe is loaded, db:setup is automatically configured <br />
&nbsp; &nbsp; &nbsp; to be invoked after deploy:setup. You can skip this task setting <br />
&nbsp; &nbsp; &nbsp; the variable :skip_db_setup to true. This is especially useful <br />
&nbsp; &nbsp; &nbsp; if you are using this recipe in combination with <br />
&nbsp; &nbsp; &nbsp; capistrano-ext/multistaging to avoid multiple db:setup calls <br />
&nbsp; &nbsp; &nbsp; when running deploy:setup for all stages one by one.<br />
&nbsp; &nbsp; DESC<br />
&nbsp; &nbsp; task :setup, :except =&gt; { :no_release =&gt; true } do<br />
<br />
&nbsp; &nbsp; &nbsp; default_template = &lt;&lt;-EOF<br />
&nbsp; &nbsp; &nbsp; base: &amp;base<br />
&nbsp; &nbsp; &nbsp; &nbsp; adapter: sqlite3<br />
&nbsp; &nbsp; &nbsp; &nbsp; timeout: 5000<br />
&nbsp; &nbsp; &nbsp; development:<br />
&nbsp; &nbsp; &nbsp; &nbsp; database: #{shared_path}/db/development.sqlite3<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt;: *base<br />
&nbsp; &nbsp; &nbsp; test:<br />
&nbsp; &nbsp; &nbsp; &nbsp; database: #{shared_path}/db/test.sqlite3<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt;: *base<br />
&nbsp; &nbsp; &nbsp; production:<br />
&nbsp; &nbsp; &nbsp; &nbsp; database: #{shared_path}/db/production.sqlite3<br />
&nbsp; &nbsp; &nbsp; &nbsp; &lt;&lt;: *base<br />
&nbsp; &nbsp; &nbsp; EOF<br />
<br />
&nbsp; &nbsp; &nbsp; location = fetch(:template_dir, &quot;config/deploy&quot;) + '/database.yml.erb'<br />
&nbsp; &nbsp; &nbsp; template = File.file?(location) ? File.read(location) : default_template<br />
<br />
&nbsp; &nbsp; &nbsp; config = ERB.new(template)<br />
<br />
&nbsp; &nbsp; &nbsp; run &quot;mkdir -p #{shared_path}/db&quot;<br />
&nbsp; &nbsp; &nbsp; run &quot;mkdir -p #{shared_path}/config&quot;<br />
&nbsp; &nbsp; &nbsp; put config.result(binding), &quot;#{shared_path}/config/database.yml&quot;<br />
&nbsp; &nbsp; end<br />
<br />
&nbsp; &nbsp; desc &lt;&lt;-DESC<br />
&nbsp; &nbsp; &nbsp; [internal] Updates the symlink for database.yml file to the just deployed release.<br />
&nbsp; &nbsp; DESC<br />
&nbsp; &nbsp; task :symlink, :except =&gt; { :no_release =&gt; true } do<br />
&nbsp; &nbsp; &nbsp; run &quot;ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml&quot;<br />
&nbsp; &nbsp; end<br />
<br />
&nbsp; end<br />
<br />
&nbsp; after &quot;deploy:setup&quot;, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &quot;db:setup&quot; &nbsp; unless fetch(:skip_db_setup, false)<br />
&nbsp; after &quot;deploy:finalize_update&quot;, &quot;db:symlink&quot;<br />
<br />
end</div></td></tr></tbody></table></div>
<p>The following instructions basically represents the documentation you can find at the top of the <a href="http://gist.github.com/2769">original recipe</a>.</p>
<h3>Requirements</h3>
<p>This extension requires the original <code>config/database.yml</code> to be excluded from version control. You can easily accomplish this by renaming the file (for example to database.example.yml) and configuring your SCM in order to ignore the <code>database.yml</code> file.</p>
<p>The following example demonstrate how to rename the file and ignore the original one with Subversion.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ svn mv config/database.yml config/database.example.yml<br />
$ svn propset svn:ignore 'database.yml' config</div></td></tr></tbody></table></div>
<p>If your repository is powered by Git, type the following commands.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ git mv config/database.yml config/database.example.yml<br />
$ echo 'config/database.yml' &gt;&gt; .gitignore</div></td></tr></tbody></table></div>
<p>If you don&#8217;t want to rename your file, there&#8217;s an other alternative. You can customize the recipe in order to force Capistrano to delete <code>database.yml</code> file after a successful <code>deploy:code_update</code> and before running the <code>database:symlink</code> task.</p>
<h3>Usage</h3>
<p>Include this file in your <code>deploy.rb</code> configuration file. Assuming you saved this recipe as <code>capistrano_database.rb</code>:</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">require &quot;capistrano_database&quot;</div></td></tr></tbody></table></div>
<p>Now, when <code>deploy:setup</code> is called, this script will automatically create the <code>database.yml</code> file in the shared folder.<br />
Each time you run a new deploy, this script will also create a symlink from your application <code>config/database.yml</code> pointing to the shared configuration file.</p>
<p>In case you need to run <code>deploy:setup</code> again and you don&#8217;t want Capistrano to ask for a database password, set the <code>skip_db_setup</code> option to true. This is especially useful in combination with capistrano multi-stage recipe when you already setup your server and you share the same environment across all the stages.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ cap deploy:setup -s &quot;skip_db_setup=true&quot;</div></td></tr></tbody></table></div>
<h3>Custom template</h3>
<p>By default, this script creates an exact copy of the default <code>database.yml</code> file shipped with a new Rails 2.x application.<br />
If you want to overwrite the default template, simply create a custom Erb template called <code>database.yml.erb</code> and save it into <code>config/deploy</code> folder.</p>
<p>Although the name of the file can&#8217;t be changed, you can customize the directory where it is stored defining a variable called <code>:template_dir</code>.</p>
<div class="codecolorer-container text default code-ruby" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># store your custom template at foo/bar/database.yml.erb<br />
set :template_dir, &quot;foo/bar&quot;<br />
#<br />
# example of database template<br />
<br />
base: &amp;base<br />
&nbsp; adapter: sqlite3<br />
&nbsp; timeout: 5000<br />
development:<br />
&nbsp; database: #{shared_path}/db/development.sqlite3<br />
&nbsp; &lt;&lt;: *base<br />
test:<br />
&nbsp; database: #{shared_path}/db/test.sqlite3<br />
&nbsp; &lt;&lt;: *base<br />
production:<br />
&nbsp; adapter: mysql<br />
&nbsp; database: #{application}_production<br />
&nbsp; username: #{user}<br />
&nbsp; password: #{Capistrano::CLI.ui.ask(&quot;Enter MySQL database password: &quot;)}<br />
&nbsp; encoding: utf8<br />
&nbsp; timeout: 5000</div></td></tr></tbody></table></div>
<p>Because this is an Erb template, you can place variables and Ruby scripts within the file.</p>
<p>For instance, the template above takes advantage of Capistrano CLI to ask for a MySQL database password instead of hard coding it into the template. This solves the original problem of storing sensitive data in your repository or deploy script.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/02/capistrano-uploads-folder/' rel='bookmark' title='Capistrano: Managing an uploads folder'>Capistrano: Managing an uploads folder</a></li>
<li><a href='http://www.simonecarletti.com/blog/2008/12/capistrano-deploy-recipe-with-passenger-mod_rails-taste/' rel='bookmark' title='Running Capistrano with Passenger (mod_rails)'>Running Capistrano with Passenger (mod_rails)</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/07/capistrano-executing-a-command-as-root-without-using-sudo/' rel='bookmark' title='Capistrano: Executing a command as root without using sudo'>Capistrano: Executing a command as root without using sudo</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2009/06/capistrano-and-database-yml/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>

