<?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>casperfabricius.com &#187; deployment</title>
	<atom:link href="http://casperfabricius.com/site/category/deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://casperfabricius.com/site</link>
	<description>expert ruby on rails development</description>
	<lastBuildDate>Sun, 06 Jun 2010 08:43:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Bundler and Rails 3 environments</title>
		<link>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/</link>
		<comments>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/#comments</comments>
		<pubDate>Sat, 17 Apr 2010 13:50:44 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category>bundler</category>
	<category>bundler</category>
	<category>environments</category>
	<category>gem</category>
	<category>debug</category>
	<category>debug</category>
	<category>beta</category>
	<category>gems</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=312</guid>
		<description><![CDATA[I usually write very long blog posts. Not this time! This is just a small tip, the first of hopefully many learnings I&#8217;ll make as I am working with my first project in Rails 3.
Bundler (Github &#124; Website) is the new way to manage gem dependencies in Rails and other Ruby applications. If you haven&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>I usually write very long blog posts. Not this time! This is just a small tip, the first of hopefully many learnings I&#8217;ll make as I am working with my first project in Rails 3.</p>
<p>Bundler (<a href="http://github.com/carlhuda/bundler">Github</a> | <a href="http://gembundler.com">Website</a>) is the new way to manage gem dependencies in Rails and other Ruby applications. If you haven&#8217;t heard about it, there is (of course) a <a href="http://railscasts.com/episodes/201-bundler">great introduction at Railcasts</a>. It&#8217;s pretty easy and straight-forward to use, especially if you are used to the <code>config.gem</code> format of Rails.</p>
<p>However, one very common use case in Bundler&#8217;s <code>Gemfile</code> that is not explicitly documented anywhere I&#8217;ve seen, is how to configure gems to be installed in <i>both development and test environments, but not in staging and production environments</i>. You have probably seen the examples of how you can assign a gem to a specific environment using the <code>:group</code> option or method. So you&#8217;d probably write something like this:</p>
<pre>
group :test do
  gem "rspec-rails", ">= 2.0.0.beta.1"
end

group :development do
  gem "ruby-debug"
end
</pre>
<p><span id="more-312"></span></p>
<p>The gems you don&#8217;t need on the server are usually all those related to testing, debugging and perhaps generating fake data and so on. But wait a minute. You also need the RSpec in the development environment so you can use it&#8217;s generators, right? And you need Ruby Debug in the test environment so you can put breakpoints in your tests.</p>
<p>Luckily there is a very easy, and &#8211; once you know it &#8211; obvious solution to this: You can pass multiple environments to the </code>group</code> method, just like this:</p>
<pre>
group :development, :test do
  gem "rspec-rails", ">= 2.0.0.beta.1"
  gem "ruby-debug"
end
</pre>
<p>And that's probably the only grouping of gems you'll need in many Rails projects. Most gems installed and required in all environments, and a few just in the development and test environments. Happy Rails 3 coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2010/04/17/bundler-and-rails-3-environments/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hosting a Spree webshop on Heroku</title>
		<link>http://casperfabricius.com/site/2009/10/18/hosting-a-spree-webshop-on-heroku/</link>
		<comments>http://casperfabricius.com/site/2009/10/18/hosting-a-spree-webshop-on-heroku/#comments</comments>
		<pubDate>Sun, 18 Oct 2009 13:09:46 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/cfp/casperfabricius.com/site/wp-content/plugins/autometa/autometa.php</b> on line <b>324</b><br />
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=246</guid>
		<description><![CDATA[Spree is the webshop solution for Ruby on Rails, and Heroku is the place to host your Rails-applications &#8211; especially if you like free hosting :)
Finding myself in the need of a webshop, I decided to try to deploy Spree to Heroku. It wasn&#8217;t too hard, but it did take a few tricks to get [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://spreecommerce.com/">Spree</a> is <em>the</em> webshop solution for <a href="http://www.rubyonrails.com/">Ruby on Rails</a>, and <a href="http://heroku.com/">Heroku</a> is <em>the</em> place to host your Rails-applications &#8211; especially if you like free hosting :)</p>
<p>Finding myself in the need of a webshop, I decided to try to deploy Spree to Heroku. It wasn&#8217;t too hard, but it did take a few tricks to get Spree running on a server that doesn&#8217;t allow you to write to the file system.</p>
<p>I can&#8217;t say I have too much hands-on experience with Spree yet, but it seems to be have borrowed its extension concept from <a href="http://radiantcms.org/">Radiant CMS</a>, which happens to be one of my areas of expertise. So I put together an <a href="http://github.com/RSpace/spree-heroku/">extension</a> for Spree that will easily allow you to deploy the e-commerce system to Heroku.</p>
<p>Just follow the instructions in the <a href="http://github.com/RSpace/spree-heroku/">README on Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2009/10/18/hosting-a-spree-webshop-on-heroku/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Manage and rollback Heroku deployments Capistrano-style</title>
		<link>http://casperfabricius.com/site/2009/09/20/manage-and-rollback-heroku-deployments-capistrano-style/</link>
		<comments>http://casperfabricius.com/site/2009/09/20/manage-and-rollback-heroku-deployments-capistrano-style/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 14:36:17 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
		<br />
<b>Warning</b>:  Invalid argument supplied for foreach() in <b>/home/cfp/casperfabricius.com/site/wp-content/plugins/autometa/autometa.php</b> on line <b>324</b><br />
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/site/?p=241</guid>
		<description><![CDATA[If you are a Rails-developer, and you don&#8217;t know about Heroku, now would definitely be a good time. Heroku is a platform for hosting web-based Ruby applications in &#8220;the cloud&#8221;, in this case Amazon EC2, making you able to scale your application in an effortless and cost-effective manner without worrying about the hardware behind. Heroku [...]]]></description>
			<content:encoded><![CDATA[<p>If you are a Rails-developer, and you don&#8217;t know about <a href="http://heroku.com/">Heroku</a>, now would definitely be a good time. Heroku is a platform for hosting web-based Ruby applications in &#8220;the cloud&#8221;, in this case <a href="http://aws.amazon.com/ec2/">Amazon EC2</a>, making you able to scale your application in an effortless and cost-effective manner without worrying about the hardware behind. Heroku differs from competition by offering by far the fastest and easiest way to deploy your Rails-application. You simply create your application from Heroku&#8217;s web interface or using their API, and then push your git-repository to Heroku&#8217;s git-server. Heroku takes care of the rest, and you can get back to coding.</p>
<p>I use Heroku for <a href="http://darebusters.com>My Big Secret Project</a> (now not so secret anymore ;), and I am quite happy with not just the ease of deployment it offers, but in fact also with the choices and the constraints that the platform imposes on me. I like writing <code>git push heroku</code> and see my code live immediately. This is of course not that different from <a href="http://www.capify.org/">Capistrano</a>, once that has been setup with the right recipes and the server has been setup to corporate and serve our web application properly. But that can also take some time, especially on a brand new server.</p>
<p><span id="more-241"></span></p>
<p>I did miss one important feature of Capistrano when I started using Heroku: Rollback. Writing <code>cap deploy:rollback</code> has saved my behind many, many times. Granted, it has often been because of bad server configuration which shouldn&#8217;t happen with Heroku, but there has also been cases of genuine bugs resulting in all pages returning errors. When we do mess up, it is really nice to have the application back up in a matter of seconds, and then being able to take you to fix the error &#8211; perhaps even do the right thing and write a failing test for that particular bug before you fix the error.</p>
<p>With Heroku you don&#8217;t get rollback per se, as the application always displays the <code>HEAD</code> version of the <code>master</code> branch in the git repository on Heroku&#8217;s servers. However, with git we have the ability to roll back to the state of every single commit ever done. It&#8217;s just not very convenient having to figure out which commit was your last one working, especially not in a situation where your application is down. Also, we need this to be automated like everything else.</p>
<p>The solution I came up with was to tag each release with a timestamp &#8211; just like Capistrano names its release directories. This gives me a series of tags that should all point to successful deployments, and when my hour of distress arise, I can simply tell the <code>master</code> branch on Heroku to point to the previous release. If I further delete the tag of my current release, I have effectively rolled back to my previous release, and hopefully my application is now up and running again.</p>
<p><script src="http://gist.github.com/307479.js"></script></p>
<p>If you want this functionality in your Heroku application, just copy the above code into a <code>.rake</code> in your <code>lib</code> directory. You deploy your application with this command <code>rake deploy</code> and roll back with <code>rake rollback</code>.</p>
<p>Please note that the script also runs migrations on each deploy, but feel free to delete that line. Suggestions and improvements are very welcome. Enjoy.</p>
<p><strong>Update:</strong> Nicola Junior Vitto pointed out that my rollback code was not working correctly, and managed to fix it. <a href="http://gist.github.com/362873">His fork</a> of the deployment script also features support for both a production and a staging environment &#8211; I&#8217;ve updated mine so rollback work, but kept it more simple without support for multiple environments.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2009/09/20/manage-and-rollback-heroku-deployments-capistrano-style/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Radiant CMS on Dreamhost with Phusion Passenger</title>
		<link>http://casperfabricius.com/site/2008/05/24/radiant-cms-on-dreamhost-with-phusion-passenger/</link>
		<comments>http://casperfabricius.com/site/2008/05/24/radiant-cms-on-dreamhost-with-phusion-passenger/#comments</comments>
		<pubDate>Fri, 23 May 2008 22:41:06 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>

	<!-- AutoMeta Start -->
	<category></category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/?p=64</guid>
		<description><![CDATA[Believe it or not, but my mom has quite a lot of websites. I must have built 8-10 websites for my dear mother during the past 10 years, and currently she has three active ones. Most of them has been built in static HTML, a more recent one is a Rails application and one is [...]]]></description>
			<content:encoded><![CDATA[<p>Believe it or not, but my mom has quite a lot of websites. I must have built 8-10 websites for my dear mother during the past 10 years, and currently she has three active ones. Most of them has been built in static HTML, a more recent one is a Rails application and one is no more than a Word document exported as a webpage. Now, a mother loves every excuse to get in touch with her son, but I have grown a bit weary of making minor text changes to one of her websites every few weeks.</p>
<p>Which is why I decided make life easier for myself and for my mom. I have never been fond of content management systems, especially not complex ones, but during the past year I have developed quite a lot of websites using <a href="http://www.rubyonrails.org">Ruby on Rails</a> based <a href="http://radiantcms.org/">Radiant CMS</a> at <a href="http://www.co-plus.com">work</a>, and I find it very simple to use and easy to extend.</p>
<p>Rails applications has never been easy to deploy, especially not on a shared host, so I have been following the development of <a href="http://www.modrails.com/">Phusion Passenger</a>, a.k.a. mod_rails, for the past months with a growing interest. I was quite happy when Dreamhost recently <a href="http://blog.dreamhost.com/2008/05/13/passenger-for-ruby-on-rails/">announced</a> that they now offered to run Rails applications using Passenger, and I was eager to try it out &#8211; which is what I did today.</p>
<p>Now, I didn&#8217;t expect to be hard to get Radiant up and running on Dreamhost with Passenger for a seasoned Rails developer and Dreamhost user such as myself, but I found it in fact to be ridiculously easy &#8211; which is why I had to write this long introduction about my mom, as there is really not much to say. Anyhow I want to take the opportunity to explain exactly  the configuration I selected and how I got it running.</p>
<p>I am running <a href="http://svn.radiantcms.org/radiant/tags/rel_0-6-7/radiant/">Radiant version 0.6.7</a> (the newest as I am writing this, always go for the newest) with two vital extensions: <a href="http://github.com/pilu/radiant-gallery/">Gallery</a>, for facilitating easy upload and display of images, and <a href="http://svn.radiantcms.org/radiant/tags/rel_0-6-7/extensions/multi_site/">MultiSite</a>, for being able to host all three of my mother&#8217;s websites within a single Radiant instance. Also, I of course wanted to deploy from a Subversion repository using Capistrono, as nothing is sweeter than writing <code>cap deploy</code> and get all the heavy deployment lifting done automatically.</p>
<p>The basics of running Passenger on Dreamhost is explained in the <a href="http://wiki.dreamhost.com/Passenger">Dreamhost wiki</a>: You create or edit a domain and check the Ruby on Rails Passenger option. You must also set the web directory to be <code>path/to/rails/application<b>/current/public</b></code>, as Capistrano deploys to the <code>current</code> directory, and Passenger must be pointed to the <code>public</code> directory of the current version.</p>
<p>Let&#8217;s create a new Radiant CMS Rails application and add our extensions. I don&#8217;t use the Radiant gem, as gems can be troublesome to manage on Dreamhost, I simply use a fresh checkout of the version I want:</p>
<pre>
svn export http://svn.radiantcms.org/radiant/tags/rel_0-6-7/radiant/ radiant
cd radiant
git clone git://github.com/pilu/radiant-gallery.git vendor/extensions/gallery
svn export http://svn.radiantcms.org/radiant/tags/rel_0-6-7/extensions/multi_site/ vendor/extensions/multi_site
</pre>
<p>There is one minor snag which will undoubtedly be fixed in the near future. The MultiSite extension is not compatible with Radiant 0.6.7, and two things need to be done to get it up and running: First, the HAML plugin bundled with the extension must be deleted, as it conflicts with the one now bundled with Radiant:</p>
<pre>
rm -rf vendor/extensions/multi_site/vendor/plugins/haml/
</pre>
<p>Second, three lines must be outcommented in <code>vendor/extensions/multi_site/lib/multi_site/page_controller_extensions.rb</code> so that the first few lines looks like this:</p>
<pre>
module MultiSite::PageControllerExtensions
  def self.included(base)
    base.class_eval {
      alias_method_chain :index, :root
      alias_method_chain :clear_model_cache, :site
      alias_method_chain :continue_url, :site
      # %w{remove clear_cache}.each do |m|
      #  alias_method_chain m.to_sym, :back
      # end
    }
  end
  ...
end
</pre>
<p>Both extensions need to copy some files to the public directory of the application before we continue:</p>
<pre>
rake radiant:extensions:update_all
</pre>
<p>Now, let&#8217;s check our Radiant application into a Subversion repository and deploy it Capistrano. I cooked up a Capistrano recipe based on a mix of older recipes. Run <code>capify .</code> and copy and modify this code into <code>config/deploy.rb</code>:</p>
<pre>
set :user, 'my_dreamhost_user'
set :application, "my-passenger-domain.com"
set :repository, "my_svn_repository_url"
set :svn_username, "my_svn_username"

# =============================================================================
# You shouldn't have to modify the rest of these
# =============================================================================

role :web, application
role :app, application
role :db,  application, :primary => true

set :deploy_to, "/home/#{user}/#{application}"
# set :svn, "/path/to/svn"       # defaults to searching the PATH
set :use_sudo, false
# set :restart_via, :run
set(:svn_password) { Capistrano::CLI.password_prompt }

# saves space by only keeping last 3 when running cleanup
set :keep_releases, 3

# issues svn export instead of checkout
set :checkout, "export"

# keeps a local checkout of the repository on the server to get faster deployments
set :deploy_via, :remote_cache

ssh_options[:paranoid] = false

# Shared dirs between releases
set :shared_dirs, ['galleries']

# =============================================================================
# OVERRIDE TASKS
# =============================================================================
namespace :deploy do

  desc "Restart Passenger"
  task :restart, :roles => :app do
    run "touch #{current_path}/tmp/restart.txt"
  end

  desc <<-DESC
    Deploy and run pending migrations. This will work similarly to the \
    `deploy' task, but will also run any pending migrations (via the \
    `deploy:migrate' task) prior to updating the symlink. Note that the \
    update in this case it is not atomic, and transactions are not used, \
    because migrations are not guaranteed to be reversible.
  DESC
  task :migrations do
    set :migrate_target, :latest
    update_code
    migrate
    migrate_extensions # Added to support Radiant Extensions
    symlink
    restart
  end

  desc "Migrates Radiant Extensions"
  task :migrate_extensions do
    rake = fetch(:rake, "rake")
    rails_env = fetch(:rails_env, "production")
    migrate_env = fetch(:migrate_env, "")
    migrate_target = fetch(:migrate_target, :latest)

    directory = case migrate_target.to_sym
      when :current then current_path
      when :latest  then current_release
      else raise ArgumentError, "unknown migration target #{migrate_target.inspect}"
      end

    run "cd #{directory}; #{rake} RAILS_ENV=#{rails_env} #{migrate_env} db:migrate:extensions"
  end

  desc "Tasks to execute after initial setup"
  task :after_setup do
    # create shared dirs
    shared_dirs.each do |dir|
      run "mkdir -p #{shared_path}/public/#{dir}"
    end
  end

  desc "Tasks to execute after code update"
  task :after_update_code do
    # relink shared dirs
    shared_dirs.each do |dir|
  	  run "rm -rf #{release_path}/public/#{dir}"
      run "ln -nfs #{shared_path}/public/#{dir} #{release_path}/public/#{dir}"
    end
  end
end
</pre>
<p>This deployment script does a few clever things. All of it is borrowed from various places, but I simply don't remember who to give credit for the different bits anymore, so - just don't give me any other credit  than explaining it. It overrides the <code>migrations</code> task to also invoke the new <code>migrate_extensions</code> task, making sure that all extensions also have their migrations run. It ensures that any uploaded images into <code>public/galleries</code> is shared between releases using a symlink, as uploaded images would otherwise disappear between releases. Finally, it restarts the Phusion Passenger instance by creating or changing a file called <code>tmp/restart.txt</code>, which is Passenger's solution for allowing easy restart on shared hosts with limited access rights. Clever.</p>
<p>Also, don't forgot to delete unwanted <code>database.yml</code> files in the <code>config</code> directory. Deploying on Dreamhost, you want to rename <code>database.mysql.yml</code> to <code>database.yml</code> and delete the others. Remember to create a MySQL database with an appropriate user using the Dreamhost Panel, and to write <code>host: mysql.mydomain.com</code> instead of <code>socket: /tmp/mysql.sock</code> for the production part of the file.</p>
<p>Okay, we are ready to deploy to deploy our application:</p>
<pre>
cap deploy:setup
cap deploy
</pre>
<p>Now, since both Radiant itself and the Gallery has interactive installation scripts, we need to ssh into the Dreamhost server and run these scripts manually:</p>
<pre>
ssh my_dreamhost_user@my-passenger-domain.com
cd my-passenger-domain.com/current
rake production db:bootstrap
rake production radiant:extensions:gallery:install
</pre>
<p>Log out of the server and do another Capistrano deployment, this time also running migrations:</p>
<pre>
cap deploy:migrations
</pre>
<p>And that's it. You should now have your very own Radiant application running on Dreamhost, and with the MultiSite extension you can even manage multiple sites from the same physical Rails instance. All you need to do is <i>mirror</i> domains to the application and create new sites within the administration panel.</p>
<p>If you have any problems following these steps, please let me know. I might be able to help you out.</p>
<p>UPDATE: You don't <i>have</i> to use Subversion and Capistrano to deploy Radiant on DH, especially not if you aren't going to use any extensions and will only deploy once. Take a look at the <a href="http://wiki.radiantcms.org/How_To_Deploy_on_Dreamhost">Radiant wiki page on deploying to Dreamhost</a> to see which steps you can skip to just upload once using SFTP.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2008/05/24/radiant-cms-on-dreamhost-with-phusion-passenger/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>RailsConf: The DHH keynote &#8211; Rails 2.0 update</title>
		<link>http://casperfabricius.com/site/2007/09/18/railsconf2007-dhh/</link>
		<comments>http://casperfabricius.com/site/2007/09/18/railsconf2007-dhh/#comments</comments>
		<pubDate>Tue, 18 Sep 2007 15:35:25 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[mac]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsconf]]></category>

	<!-- AutoMeta Start -->
	<category>iphone</category>
	<category>iphone</category>
	<category>patch</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2007/09/18/railsconf2007-dhh/</guid>
		<description><![CDATA[This article summarizes some important points from David Heinemeier Hansson’s keynote at RailsConf Europe 2007 in Berlin. Last year, DHH brought us the whole REST way of thinking which I immediately named normalization, but that term didn&#8217;t really catch on.

&#169; 2007 Pinar Ozger

This year, DHH noted that he up until now had started all his [...]]]></description>
			<content:encoded><![CDATA[<p>This article summarizes some important points from David Heinemeier Hansson’s keynote at RailsConf Europe 2007 in Berlin. Last year, DHH brought us the whole <a href="/blog/2006/06/25/railsconf-dhh/">REST way of thinking</a> which I immediately named <i>normalization</i>, but that term didn&#8217;t really catch on.</p>
<div class="photo left"><a href="http://flickr.com/photos/pinarozger/1401290307/"><img src="http://farm2.static.flickr.com/1140/1401290307_f8e971781c_m_d.jpg" alt="David Heinemeier Hansson" /></a>
<div class="caption">&copy; 2007 <a href="http://flickr.com/photos/pinarozger/">Pinar Ozger</a></div>
</div>
<p>This year, DHH noted that he up until now had started all his previous keynotes about Rails celebrating how &#8220;freakin&#8217; fantastic we are&#8221;. For this keynote, he thought &#8211; with Rails being well within in its third year in existence &#8211; that it was time to perhaps be happy with what we have.</p>
<p>He explained that new things tend to go through certain phases: First they ignore you, then they laugh at you, then they fight you, and then you win &#8211; &#8230; and then what? &#8220;Ruby on Rails went through these phases way too fast&#8221;, DHH said, &#8220;I was having a lot of fun going through these phases; I&#8217;m kind of sad it is over.&#8221;</p>
<p>For the last couple of years, David and the Rails community has pushing new concepts; Convention over configuration, AJAX and REST, but these focal points were adopted very fast, so there is no big cause to fight for right now. That leaves Rails 2.0 in a really weird spot, since it won&#8217;t have any groundbreaking new concepts.</p>
<p>This is not a bad thing, though, DHH stressed. &#8220;Even though [the lack of a great cause] is an off-switch for me, it&#8217;s not about me anymore&#8221;, he said. &#8220;Rails are moving from big revolutions to tiny evolutions&#8221; &#8211; a statement that was underlined when David went on to demonstrate new features in Rails; features that were definitely more tiny evolutions than big revolutions.</p>
<p>But before we get to the Rails 2.0 code examples of the keynote, let me just mention something that was news to me: The new policy for <a href="http://trac.rubyonrails.org/2007/9/15/how-to-get-a-patch-into-rails">how to get a patch into Rails</a>, also known as <i>Report #12</i>. The idea is basically that you, once you have written a patch and submitted it to the Rails trac, should get three other Rails developers to check out your patch, verify that your tests run, and then add a &#8220;+1&#8243; in a comment in trac. Once you have your three &#8220;+1&#8243;&#8217;s, you tag your patch with the keyword &#8220;verified&#8221;, and the patch will appear in <a href="http://dev.rubyonrails.org/report/12">Report #12: Verified Patches</a>. The core team should then &#8211; theoretically &#8211; be able to very fast to accept the patch into Rails.</p>
<p>Moving on to the, in my opinion, most interesting part of the presentation: What&#8217;s new in Rails 2.0 &#8211; show me the code! Migrations has been updated to support a new syntax known as &#8220;sexy migrations&#8221;, which basically allows even shorter and more readable migrations by grouping fields of the same type:</p>
<pre>
create_table :blogs do |t|
	t.string :title, :subtitle
	t.text :body, :description
	t.integer :category_id
	t.timestamps # Adds created_at and updated_at fields
end
</pre>
<p>Notice how another evolutionary improvement has been sneaked in: Tired of always adding <code>created_at</code> and <code>updated_at</code> timestamps to most tables, a <code>timestamps</code> method has been added as a shortcut. Also this new syntax, including the timestamps, is now standard in the <code>model</code> and <code>scaffold</code> generators.</p>
<p>A small, but to me significant improvement has also found its way to Rails 2.0: You can now create the needed databases with a rake command. By running this command, all referenced databases in your <code>database.yml</code> will be created:</p>
<pre>
rake db:create:all
</pre>
<p>Another interesting, and perhaps generally quite invisible improvement, is that session data are now stored in a encrypted cookie instead on each server, which makes it easy to partition applications across multiple servers without having to put session data in the database. This requires, of course, the session data to be quite compact (storing id&#8217;s, not entire objects), as a cookie can contain 4 KB of data the most.</p>
<p>My favourite point of DHH&#8217;s keynote was his solution to the common pattern of a resource, which you both need to display to the common user (usually <code>index</code> and <code>show</code>) and to the admin user (usually <code>index</code>, <code>new</code>, <code>create</code>, <code>edit</code>, <code>update</code> and <code>destroy</code>). The normal RESTful solution to this leaves with a problem, because we are only allowed one <code>index</code> action, and we need two; one for the common user and one for the admin user. Also, the admin actions will usually have a different layout than the common user actions, and they require some kind of authorization.</p>
<p>The solution is to used RESTful <i>namespaced</i> routes, referring to <i>two different</i> controllers with the same name, but in different namespaces. To use DHH&#8217;s eternal blog example:</p>
<pre>
./script/generate controller posts # => /controllers/posts_controller.rb
./script/generate controller admin::posts # => /controllers/admin/posts_controller.rb
</pre>
<p>Now we have two different controllers working in the same model; <code>Post</code>, but offering different actions, layouts, authorization and so on. This nice thing about this solution, is that it is very easy to understand and fits well into the Rails structure. The catch is that we have two controllers with the same name, so we need to explicitly express the namespace when referring to the admin controller:</p>
<pre>
form_for([:admin, post]) do |f|
	...
end
</pre>
<p>DHH also pointed out that HTTP authentication is a perfect way of doing authentication for administration pages (which <a href="/blog/2007/08/19/three-rails-plugins/">I&#8217;d already realized</a>). You don&#8217;t really need nice-looking form-authentication and <i>remember me</i> checkboxes for that, and it is so very easy to implement with Rails 2.0:</p>
<pre>
# In a controller or module shared between admin controllers
before_filter :ensure_administrator
def ensure_administrator
	authenticate_or_request_with_http_basic('Blog admin') do |username, password|
		username == 'dhh' &#038;&#038; password == '123'
	end
end
</pre>
<p>A very visible change in Rails 2.0 is the naming of views. The <code>.rhtml</code>, <code>.rxml</code> etc. file endings has been discarded to replaced by the form <code>[name].[mime-type].[renderer]</code>. This leaves the road open for file names such as:</p>
<ul>
<li>index.html.erb</li>
<li>index.xml.builder</li>
<li>index.html.liquid</li>
<li>index.iphone.erb</li>
</ul>
<p>The last example needs a little additional configuration, since <code>iphone</code> is not a &#8220;real&#8221; mime-type, but we can easily make Rails treat it like such:</p>
<pre>
# In mime_types.rb:
Mime::Type.register "application/x-iphone"

# In application.rb:
before_filter :adjust_format_for_iphone
def adjust_format_for_iphone
	if request.env["HTTP_USER:AGENT"] ~= /iPhone/
		request.format = :iphone
	end
end

# In specific controllers
respond_to do |format|
	...
	format.iphone do
		render :text => 'Hello iPhone', :content_type => Mime::Html
	end
end
</pre>
<p>Notice how <code>content_type</code> must manually be set to <code>Mime::Html</code>, as the iPhone browser &#8211; as well as any other browser &#8211; doesn&#8217;t recognize our fake <code>x-iphone</code> mime-type, and Rails will always default to respond with the request mime-type.</p>
<p>My second favourite point was about the &#8220;new&#8221; debugging support in Rails 2.0. As I understood it, the well-known ruby-debugger library has been baked into Rails 2.0, so that we write <code>debugger</code> instead of <code>breakpoint</code>, and need to start the server with a <code>--debugger</code> prefix (<code>./script/server --debugger</code>) to enable these breakpoints. This debugger also support more advanced commands such as &#8220;cont&#8221; (continue), &#8220;list&#8221; (view current code) and &#8220;up&#8221; (step out).</p>
<p>David Heinemeier Hansson rounded off his keynote by announcing the release of a <i>Rails 2.0 Preview Release</i> (how Microsoft-ish does <i>that</i> sound?) either during or shortly after the conference.</p>
<p>You can download my full notes from the keynote <a href="/blog/wp-content/uploads/2007/09/keynote-dhh.txt">here</a>.</p>
<p>UPDATE: My other notes from RailsConf Europe 2007 <a href="/blog/2007/09/20/railsconf2007-notes">are now available</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2007/09/18/railsconf2007-dhh/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>RailsConf: Shared Host Deployment</title>
		<link>http://casperfabricius.com/site/2006/06/24/railsconf-deployment/</link>
		<comments>http://casperfabricius.com/site/2006/06/24/railsconf-deployment/#comments</comments>
		<pubDate>Sat, 24 Jun 2006 20:24:11 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[railsconf]]></category>

	<!-- AutoMeta Start -->
	<category>railsconf</category>
	<category>deployment</category>
	<category>geoff</category>
	<category>ezra</category>
	<category>mongrel</category>
	<category>montastic</category>
	<category>vps</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/06/24/railsconf-deployment/</guid>
		<description><![CDATA[Geoffry Grosenbach is cool. And I&#8217;ve struggled with the same issues as he has, albeit I&#8217;ve been able to build on his work in my own deployment setup. So of course I had to attend his talk on deploying to shared hosts, although most of what he said wasn&#8217;t new to me. Geoff&#8217;s entertaining and [...]]]></description>
			<content:encoded><![CDATA[<p>Geoffry Grosenbach is cool. And I&#8217;ve struggled with the same issues as he has, albeit I&#8217;ve been able to build on his work in <a href="http://casperfabricius.com/blog/2006/05/21/rails-on-dreamhost/">my own deployment setup</a>. So of course I had to attend his talk on deploying to shared hosts, although most of what he said wasn&#8217;t new to me. Geoff&#8217;s entertaining and well-designed presentation focused on three areas: How to design a site to run a shared host, how to maintain the site, and how to troubleshoot problems.</p>
<p><b>Design</b><br />
First of all, Geoff suggested that only really small sites should be deployed to a shared host. By small, it is not as much disk space, as how much memory and how many CPU cycles the site requires running smoothly. You are restricted on all these three factors on most shared hosts, but you also have the benefit of running on multiple servers – usually the database server will quite powerful, you will have a separate mail server, etc.</p>
<p>Another important thing in designing the application is caching. Geoff explained, that by using the <code>caches_page</code> macro, an html file will automatically be created upon the first hit, and after that; the web server will simply serve that static page without even invoking Ruby, Rails, FastCGI or anything else. The html file is stored in a directory structure that corresponds to the mapping of the action, so if you have for instance the action <code>/da-DK/blogs/show/1</code>, it will store that particular blog for that particular language. So that sounds like quite a big possibility to improve on speed. In order to expire the cached pages, a <code>cache_sweeper</code> needs to be implemented.</p>
<p><b>Maintaince</b><br />
Geoff underlined that you need to make sure you don&#8217;t have too many zombie FastCGI processes running on your shared host, since you are restricted on number of processes. Maybe Mongrel will be the holy grail giving a nice, reliable way to run sites on a shared host, Geoff said, and this was somewhat confirmed by the &#8220;Deploying Rails&#8221; presentation by Ezra Zygmuntowicz the following day, stating that the future of Rails deployment definately belongs to Mongrel.</p>
<p>For monitoring our Rails applications, Geoff suggested <a href="http://www.montastic.com">Montastic.com</a> or dwatch, which he has written a <a href="http://nubyonrails.com/articles/2006/03/29/surviving-rails-1-1-with-server-monitoring">great tutorial on using</a>.</p>
<p><b>Troubleshooting</b><br />
Finally, Geoff gave some advice on how to debug and fix your problems when your site is not working on the server. The hash-bang (or is it she-bang?) lines has to actually point to place Ruby exists on the server, and it is a good idea to set <code>export RAILS_ENV="production"</code> in the <code>~/.bashrc</code> or <code>~/.bash_profile</code> to indicate that this the production site, instead of hardcoding it in <code>environment.rb</code> or relying on the shared host to set it.</p>
<p><code>./script/about</code>, <code>./script/server –e production</code> and <code>./script/console production</code> are all good indicators of whether or not the actual site are running on the shared host, but also, the various logs produced can be good indicators of where the problem is, especially <code>apache_log</code>, <code>production.log</code> and <code>fast_cgi.log</code>.</p>
<p><b>Conclusion</b><br />
Deploying Rails can be frustrating, and deploying it to a shared host with no control and lots restrictions can be a nightmare, so, as Geoff started out by saying, his talk was not a tutorial or a lesson, it was therapy.</p>
<p>But really the morale here is: Don&#8217;t use shared hosts for Rails, and if you do, make sure it&#8217;s only very small applications, or only for test purposes. As Ezra said at his talk on deployment: &#8220;Rails is a pig&#8221;. Once you want people to actually use your site, you should go with a Virtual Private Server (VPS) – or of course a dedicated setup if you can afford it – since you will get a certain amount of memory guaranteed, and you will have less users pr. machine. Ezra adds that you always go for a VPS host that uses XEN, since this platform uses almost no resources on its own.</p>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/06/24/railsconf-deployment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Deploying Rails with Edge and Engines to Dreamhost using Capistrano</title>
		<link>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/</link>
		<comments>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/#comments</comments>
		<pubDate>Sun, 21 May 2006 19:59:51 +0000</pubDate>
		<dc:creator>Casper Fabricius</dc:creator>
				<category><![CDATA[deployment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tutorial]]></category>

	<!-- AutoMeta Start -->
	<category>combination</category>
	<category>deploying</category>
	<category>circumstances</category>
	<category>strange</category>
	<category>specifically</category>
	<category>microsoft</category>
	<category>documented</category>
	<category>developers</category>
	<!-- AutoMeta End -->
	
		<guid isPermaLink="false">http://casperfabricius.com/blog/2006/05/21/rails-on-dreamhost/</guid>
		<description><![CDATA[It&#8217;s not that I&#8217;m the first to describe the process of deploying a Rails application, in fact; it&#8217;s rather well-documented, also when it comes specifically to Dreamhost. It&#8217;s just that I have a strange combination of circumstances that none of these articles cover, and also; I know almost nothing about Unix-based systems &#8211; I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not that I&#8217;m the first to describe the process of deploying a Rails application, in fact; it&#8217;s rather <a href="#ressources">well-documented</a>, also when it comes specifically to Dreamhost. It&#8217;s just that I have a strange combination of circumstances that none of these articles cover, and also; I know almost nothing about Unix-based systems &#8211; I don&#8217;t even have a Mac. I am one the of many Microsoft-developers who are starting to see the light, and because 	of that, I need to start entirely from scratch when it comes to understanding the whole Linux/Apache/open-source universe.</p>
<p>(<a href="#solution">Take me straight to the solution, please</a>)</p>
<p><strong>My strange combination of circumstances</strong><br />
The Rails application I&#8217;ve had to learn to deploy the hard way has this configuration:</p>
<ul>
<li>Dependent on Rails 1.1.2</li>
<li>Uses <a href="http://www.rails-engines.org/login_engine">Login</a> and <a href="http://www.rails-engines.org/user_engine">User Engine</a>.</li>
<li>Build for MySQL (so no problem there)</li>
<li>Must run with FastCGI, or it&#8217;s too slow</li>
<li>Developed with RadRails on Windows XP (yes, this makes a difference)</li>
<li>Resides in a Subversion repository</li>
</ul>
<p>If you can live with Rails 1.0.0, if you don&#8217;t use Rails Engines, if you don&#8217;t need FastCGI and if you know about Linux, you are probably better off using <a href="#ressources">shorter and simpler tutorials</a>, because these where my specific problems, and what I am going to dvelve into here.</p>
<p><strong>Linux basics</strong><br />
Although it is possible to <a href="http://airhead.typepad.com/airhead/2006/05/windows_on_rail.html">deploy Rails to a Windows server</a> (and presumably not <em>much</em> harder if you can use Apache instead of IIS), Dreamhost, and all other commercial hosts supporting Ruby on Rails, are using Linux servers. You can develop your entire Rails application completely unknowningly about Linux, but when it gets to deployment you have to learn the basics about this strange operating system:</p>
<ul>
<li>You don&#8217;t use Remote Desktop, you use SSH. Remember DOS? When you connect with SSH, you get a text prompt simular to that, and you need to know some basic commands. I recommend using <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">PuTTY</a> for SSH.</li>
<li>Use <code>pwd</code> to print you current directory.</li>
<li>Use <code>ls</code> to print the contents of the current directory.</li>
<li>Use <code>cd</code> (e.g. <code>cd /home/user/</code>) to move into a directory.</li>
<li>Use <code>vim</code> (e.g. <code>vim environment.rb</code>) to quickly view and edit files directly on the server. Press your INSERT button to enable editing, and press ESCAPE, then write <code>:wq</code> to save and exit the file.</li>
</ul>
<p>Now, in a <em>perfect world</em> (see below) you actually shouldn&#8217;t have to know this, because Capistrano would do all the dirty work for you, but let&#8217;s get real: It&#8217;s just not that easy.</p>
<p><strong>In a perfect world</strong><br />
Here is a quick recap of what you would be all needed to do, if the world was perfect or you are extremely lucky and everything works as expected</p>
<ol class="fluffy">
<li>Now, I expect you have already created MySQL database on Dreamhost and entered the connection details into <code>config/database.yml</code> &#8211; otherwise; start out with that.</li>
<li>Create a new fully hosted domain in the Dreamhost panel, and make sure it is configured like this:
<div><img src="http://casperfabricius.com/site/wp-content/uploads/2006/05/dreamhost_rails.png" alt="Dreamhost Rails setup" /></div>
<ul>
<li>FastCGI Support enabled</li>
<li>The user has shell access of the type <code>/bin/bash/</code> (configurable from the Manage Users page)</li>
<li>The web directory points to <code>[yourdomain.com]/current/public</code> (not just <code>[yourdomain.com]/public</code>, since we want to use Capistrano)</li>
<li>(The www option is up to you)</li>
</ul>
<li>SSH to [yourdomain.com] and remove the current directory (containing the public directory) Dreamhost has automatically created. (Capistrano needs to create this as a <a href="http://en.wikipedia.org/wiki/Symbolic_Link">symbolic link</a> later.):
<pre># On your Dreamhost server
[nimitz]$ pwd
/home/cape
[nimitz]$ cd myrailsapp.com/
[nimitz]$ ls
current
[nimitz]$ rm -r current/
[nimitz]$ ls
[nimitz]$</pre>
<ul>
<li>Start PuTTY, enter [yourdomain.com] as Host Name and click Open.</li>
<li>Login with the user you specified when creating the domain</li>
<li>Change to the directory of your Rails application (<code>cd  [yourdomain.com]</code>)</li>
<li>Remove the directories (<code>rm -r current</code>)</li>
</ul>
<li>Download <a href="http://topfunky.com/">Geoffrey Grosenbach&#8217;s</a> <a href="http://topfunky.net/svn/shovel/dreamhost/deploy.rb">Capistrano script</a>, add it to the /config/ directory of your Rails application, and edit it to reflect your setup:
<pre># In config/deploy.rb
set :user, 'cape'
set :application, 'myrailsapp.com'
set :repository, 'http://svn1.cvsdude.com/...'
set :svn_username, "casper"
set(:svn_password) { Capistrano::CLI.password_prompt }</pre>
<ul>
<li><code>:user</code> must match the user you specified when creating the domain</li>
<li><code>:application</code> must be the domain you created</li>
<li><code>:repository</code> must be the url of your Subversion repository for the application, from where Capistrano will grab the code to deploy.</li>
<li><code>:svn_username</code> only have to be present, if your subversion username is different from your Dreamhost shell username.</li>
<li><code>set(:svn_password) { Capistrano::CLI.password_prompt }</code> tells Capistrano to prompt you for your subversion password. This might not be nescessary, if your Dreamhost user is already in a trust relationship with the Subversion server.</li>
</ul>
<li>Edit <code>public/.htaccess</code> and change the line <code>RewriteRule ^(.*)$ dispatch.cgi [QSA,L]</code> to <code>RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]</code>. This tells Apache which file it should execute when a request comes in.</li>
<li><a name="shebang"></a>Edit <code>public/dispatch.fcgi</code> and change the first line from <code>#!c:/ruby/bin/ruby</code> (or something simularly Windowish) to <code>#!/usr/bin/env ruby</code>. This line is called a <em>shebang location</em> and tells Linux where to find the program that are able to execute this file, in our case; this is ruby.</li>
<li>Edit <code>config/enviroment.rb</code> and incomment the line: <code>ENV['RAILS_ENV'] ||= 'production'</code>. Dreamhost says they set this enviroment variable automatically the nice way when using FastCGI &#8211; in my experience, they don&#8217;t. This means you have to incomment the line every time you release, and outcomment it again the develop in the development environment &#8211; in my final <code>deploy.rb</code> I have a much cleaner solution to this problem, so stay tuned.</li>
<li>Open up a Command Window, move into the directory of your Rails Application and run the command <code>rake remote:exec ACTION=setup</code>. (You will need to type your password for the user you specified when creating the domain)</li>
<li>Run <code>rake deploy</code>. If you are really, really lucky, this will actually do the job for you, and you can browse to your application. If you are not, go on &#8230;</li>
</ol>
<p><strong>Finding out what&#8217;s wrong</strong><br />
I&#8217;m going to assume that the steps above sort of worked for you, such that Capistrano was actually able to setup the server and copy the files to the correct directory, but it probably failed by the end of the <code>rake deploy</code> command, because it didn&#8217;t have the permissions to restart the web server. So now when you go to [yourdomain.com] in your browser, you don&#8217;t get a &#8220;Page not found&#8221;, you get a &#8220;Rails application failed to start properly&#8221; after a looong wait.</p>
<p>Since the &#8220;Rails application failed to start&#8221; message is not very information, I am going to start out by giving you a few tips about how to diagnose your failing Rails application. You should be able to distinguish between to scenarios:</p>
<ol>
<li>Your Rails application is not able to run, probably because it can&#8217;t connect to the database or can&#8217;t locate some files</li>
<li>The application can run, but the FastCGI link doesn&#8217;t work, so pages cannot be served</li>
</ol>
<p>It&#8217;s easy to test for the first scenario; just SSH to the server, cd to the directory of your app (<code>cd /home/user/[yourdomain.com]/current/</code>), and run the command <code>ruby script/console production</code>. This attempts to start your Rails app in production mode, and any error messages will be right there on the screen for you.</p>
<p>The second scenario is in fact also pretty easy to test, at least under the assumption that Apache is able to redirect to &#8220;dispatch.fgi&#8221; (but it wasn&#8217;t, you probably wouldn&#8217;t get the  &#8220;Rails application failed to start properly&#8221; error). By running <code>ruby public/dispatch.fgi</code> you actually invoke the same file as the web server, which will often give you handy information.</p>
<p>Once you application is running, you can also get useful debugging information from the log files in the <code>logs</code> directory, but if your Rails app is actually writing to these, you probably have something that are pretty close to work.</p>
<p><strong>Fixing deploy.rb</strong><br />
As I have hinted, I had to make a couple of changes to Geoff&#8217;s &#8220;shovel&#8221; <code>deploy.rb</code> in order to make it run smoothly:</p>
<ol>
<li>To be able to restart the FastCGI-processes in the <code>:restart</code> task, I had to add <code>ruby</code> to the line that restarts, because the reaper-script that restarts is not executable on Dreamhost. So my <code>:restart</code> task now looks like this:
<pre># In config/deploy.rb
task :restart, :roles => :app do
  run "ruby #{current_path}/script/process/reaper --dispatcher=dispatch.fcgi"
end</pre>
</li>
<li>To make Apache able to actually execute <code>dispatch.fcgi</code> our <code>deploy.rb</code> also needs to run a command makes <code>dispatch.fcgi</code> executable. On Unix-based systems, any file can be marked as executable, and the OS will then read the <a href="#shebang">shebang location</a> when the file is invoked. By inserting the task below, <code>dispatch.fcgi</code> will be made executable each time you make a deployment. By naming the task <code>after_symlink</code>, it will be executed after the symbolic link has been moved to point to your new files &#8211; first by then, the <code>current_path</code> variable is available.
<pre># In config/deploy.rb
task :after_symlink, :roles => [:web, :app] do
  # Make dispatcher executable
  run "chmod a+x #{current_path}/public/dispatch.fcgi"
end</pre>
</li>
</ol>
<p><strong>Rails in the /vendor directory</strong><br />
It&#8217;s supposed to be <a href="http://weblog.rubyonrails.org/articles/2005/12/22/freezing-your-rails-when-you-deploy-shared">so easy</a> to use a different version of Rails than the one installed on your host. Just run <code>rake rails:freeze:gems</code> &#8211; or even better: Set <code>/vendor/rails</code> to point to <code>http://dev.rubyonrails.org/svn/rails/tags/rel_X-X-X/</code> (depending on your prefered version) using the <a href="http://svnbook.red-bean.com/en/1.0/ch07s03.html">svn:externals</a> feature of Subversion. However, strange things can happen to your application, once all the core files of Rails are suddenly supposed to be read from the <code>/vendor/rails</code> directory. I had to make three crucial changes to avoid various &#8220;required file not found&#8221; or &#8220;NoMethodError&#8221; messages after I &#8220;froze&#8221; Rails:</p>
<ol class="fluffy">
<li>Move the inclusion of files in <code>config/environenment.rb</code> down to the <em>bottom</em> of this file. For instance; I have <code>require 'taggable'</code> in my <code>environment.rb</code>, and before I &#8220;froze&#8221; Rails it I just had this line at the top without any problems, but after, it suddenly couldn&#8217;t find the taggable stuff, and it only worked when I moved that line down after the whole <code>Rails::Initializer.run do |config|</code> chunk.</li>
<li>Force <code>public/dispatch.fcgi</code> (the file that runs the show) to use the &#8220;frozen&#8221; version of Rails, by replacing the line <code>require 'fcgi_handler'</code> in <code>dispatch.fcgi</code> with this line:
<pre>require File.dirname(__FILE__) + "/../vendor/rails/railties/lib/fcgi_handler"</pre>
</li>
<li>Unfortunately, we also need to edit a file inside the Rails framework itself, putting in the absolute location of a required file instead of just the name of the file, as described in <a href="http://forum.textdrive.com/viewtopic.php?pid=87987#p87606">this post</a>. However, if you use svn:externals like I do, you can&#8217;t just alter a file in <code>vendor/rails</code>, since you don&#8217;t have any commit rights. Furthermore, the location of the line we need to add is specific to our setup on the host, so it would be baaad to hardcode it. That&#8217;s why I came up with a solution letting the deployment script <em>replace</em> this line on the server using the <code>current_path</code> variable available. You could do this with ruby, but I asked one of my hardcore Linux geek friends to write a one-liner that I could just run, and he chose to let Perl make the replace directly in the file for us. This also happens in the <code>after_symlink</code> task:
<pre># In config/deploy.rb
task :after_symlink, :roles => [:web, :app] do
  # Ensure Rails in the vendor dir is used by replacing a line in fcgi_handler.rb
  run "perl -i -pe \"s/require 'dispatcher'/require '#{current_path.gsub(/\//, '\\/')}\\/vendor\\/rails\\/railties\\/lib\\/dispatcher'/\" #{current_path}/vendor/rails/railties/lib/fcgi_handler.rb"
  ...
end</pre>
</ol>
<p><strong>Rails Engines</strong><br />
<a href="http://www.rails-engines.org/">Rails Engines</a> is a brilliant way of creating &#8220;super-plugins&#8221; that acts like small sub-applications inside your application, but where everything can be extended or overriden &#8211; even views! If you don&#8217;t use engines, this small section is irrelevant for you, but I&#8217;d recommend you taking a look a them &#8211; I love them.</p>
<p>There is really only one thing you need to be aware of when you deploy a Rails application to Dreamhost that uses engines and has Rails in the vendor directory, and that is to put this code at the very top of your <code>environment.rb</code>:</p>
<pre># In config/environment.rb
module Engines
  CONFIG = {:edge => true}
end</pre>
<p>One other thing, not really related to deployment: As I am writing this, the LoginEngine has a problem loading two files in its <code>init_engine.rb</code>, so if you get errors in this file, try replacing the two original require statements with this:</p>
<pre># In vendor/plugins/login_engine/init_engine.rb
require 'login_engine/authenticated_user'
require 'login_engine/authenticated_system'</pre>
<p><a name="solution"></a><br />
<strong>Wrapping it up: The complete solution</strong><br />
Today, I am able to run <code>rake deploy</code> and it actually works. My deployment script for Capistrano, based on <a href="http://topfunky.net/svn/shovel/dreamhost/deploy.rb">Geoff&#8217;s shovel</a>, can be downloaded <a href="/blog/files/deployment/deploy.rb">here</a>. Notice that this script, besides the tasks described above, also automatically replaces <code>#ENV['RAILS_ENV'] ||= 'production'</code> with <code>ENV['RAILS_ENV'] ||= 'production'</code> (incomments it) in <code>config/environment.rb</code> to force production environment on the Dreamhost server.</p>
<p>Here is a complete list of files I&#8217;ve uploaded for your reference:</p>
<ul>
<li><a href="/blog/files/deployment/contentsof.htaccess">.htaccess</a> (public/)</li>
<li><a href="/blog/files/deployment/deploy.rb">deploy.rb</a> (config/)</li>
<li><a href="/blog/files/deployment/dispatch.txt">dispatch.fcgi</a> (public/)</li>
<li><a href="/blog/files/deployment/environment.rb">environment.rb</a> (config/)</li>
</ul>
<p>I had to rename some of the files in order to let them be downloadable, but the link listed above has the correct name and the directory the file belongs to.</p>
<p>Please note: You can&#8217;t just dump these four files into your own Rails application and expect things to work. You have to carefully extract the pieces from each file you think you need in order to get your application up and running.</p>
<p>Good luck!</p>
<p><a name="ressources"></a><br />
<strong>Recommended ressources</strong></p>
<ul>
<li><a href="http://nubyonrails.com/pages/shovel_dreamhost">Capistrano Deployment on Dreamhost</a></li>
<li><a href="http://woss.name/2006/01/22/using-switchtower-with-ruby-on-rails-and-dreamhost/">Howto: Using Switchtower with Ruby on Rails and DreamHost</a></li>
<li><a href="http://wiki.dreamhost.com/index.php/Rails">Dreamhost Wiki: Ruby on Rails</a></li>
<li><a href="http://manuals.rubyonrails.com/read/chapter/97">Capistrano manual</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://casperfabricius.com/site/2006/05/21/rails-on-dreamhost/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
