<?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>Alfa Jango Blog &#187; Rails</title>
	<atom:link href="http://www.alfajango.com/blog/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.alfajango.com/blog</link>
	<description>Engineering, Software, and Entrepreneurship</description>
	<lastBuildDate>Thu, 09 Sep 2010 17:52:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Caching, Zipping, and (Amazon CloudFront) CDN For A Rails App</title>
		<link>http://www.alfajango.com/blog/caching-zipping-and-cdn-for-a-rails-app/</link>
		<comments>http://www.alfajango.com/blog/caching-zipping-and-cdn-for-a-rails-app/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 21:09:47 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Amazon CloudFront]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<category><![CDATA[assets]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.alfajango.com/blog/?p=447</guid>
		<description><![CDATA[In this article, we're going to speed up our Rails application by up to 75%, simply by optimizing our Rails asset host. We're going to serve our components (stylesheets, javascripts, images, etc.) from a combination of our app's server and Amazon CloudFront (Option A, recommended), or entirely from CloudFront (Option B - easier). ]]></description>
			<content:encoded><![CDATA[<div class="note">
<p>
<em>This is Article #4 of a 4-part series. For a good primer, check out the first two articles listed below. For the reasoning and analysis behind the &#8220;Recommended&#8221; option in this article, check out Part 3, <a href="how-to-combine-gzip-plus-cdn-for-fastest-page-loads/">How to Combine GZip + CDN for Fastest Page Loads</a>. Otherwise, jump right in!</em>
</p>
<ul>
	<li><a href="is-your-site-too-slow-the-importance-of-page-load-speed/">The Importance of Page Load Speed</a></li>
	<li><a href="improve-page-load-speed-by-improving-component-load-speed/">Improve Page Load Speed (by 80%) by Improving Component Load Speed</a></li>
	<li><a href="how-to-combine-gzip-plus-cdn-for-fastest-page-loads/">How to Combine GZip + CDN for Fastest Page Loads</a></li>
	<li><strong>Caching, Zipping, and (Amazon CloudFront) CDN For A Rails App</strong>
<ul>
        <li>Prerequisites
        <ol>
          <li>Cached stylesheets and javascripts</li>
          <li>Creating an Amazon AWS Account</li>
        </ol></li>
	<li>Setup S3 Buckets</li>
	<li>Setup CloudFront Distributions</li>
	<li>Create CNAME records (optional)</li>
	<li>Install Rails S3 Synch Plugin
        <ol>
          <li>Installing AWS-S3 Gem</li>
          <li>Configure S3 Synch Plugin</li>
          <li>Add S3 Synch to Deployment</li>
        </ol></li>
	<li>Option A: Compressible Assets from App Server, Images from CloudFront (recommended)
        <ol>
          <li>Configure Rails Asset Host</li>
          <li>Create A-name Record</li>
          <li>Configure Apache</li>
        </ol></li>
	<li>Option B: Serve Everything from CloudFront (easier, but not recommended)
        <ol>
          <li>Configure Rails Asset Host</li>
          <li>Pre-compile Cached Stylesheet and Javascript File</li>
        </ol></li>
        <li>Conclusion</li>
</ul>
</li>
</ul>
</div>
<h2></h2>
<p>
In this article, we&#8217;re going to speed up our Rails application by up to 75%, simply by optimizing our Rails asset host. We&#8217;re going to serve our components (stylesheets, javascripts, images, etc.) from a combination of our app&#8217;s server and Amazon CloudFront (Option A, recommended), or entirely from CloudFront (Option B &#8211; easier). 
</p><p>
The best option for you may depend on your specific needs, but I&#8217;ll cover both processes below. For a an in-depth analysis of why Option A is recommended over Option B, see the last article in this series, <a href="how-to-combine-gzip-plus-cdn-for-fastest-page-loads/">How to Combine GZip + CDN for Fastest Page Loads</a>.
</p>
<h2>Prerequisites</h2>
<h3>Cached Stylesheets and Javascripts</h3>
<p>
Another way to reduce page load time is to combine all of your components into as few files as possible. In other words, combine all of your stylesheets into a single css file, and likewise with your javascripts. Remember from the last article, that each request takes 50-150ms, not including the response and download time. If you have 10 separate javascripts, this equates to 0.5-1.5 seconds just to request the files (not to mention all the time to download them). If you can combine all of the files into one, that means you need just one request to get the same amount of data.
</p>
<p>
Luckily in Rails, this is easy, simply add <code class="codecolorer rails default"><span class="rails"><span style="color:#ff3333; font-weight:bold;">:cache</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'cached-file-name'</span></span></code> to your <code class="codecolorer rails default"><span class="rails"><span style="color:#5A0A0A; font-weight:bold;">stylesheet_link_tag</span></span></code> and <code class="codecolorer rails default"><span class="rails"><span style="color:#5A0A0A; font-weight:bold;">javascript_include_tag</span></span></code> in your application layout. For example:
</p>
<p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">stylesheet_link_tag</span> <span style="color:#996600;">'reset'</span>, <span style="color:#996600;">'application'</span>, <span style="color:#ff3333; font-weight:bold;">:cache</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'all-app-stylesheets'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">javascript_include_tag</span> <span style="color:#996600;">'jquery'</span>, <span style="color:#996600;">'jquery-ui'</span>, <span style="color:#996600;">'application'</span>, <span style="color:#ff3333; font-weight:bold;">:cache</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'all-app-javascripts'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></div></div>

</p>
<p>
Now, as long as the following line is set to true in your environment.rb, or more likely in production.rb, Rails will either load your combined files in the layout, or create and load them if they don&#8217;t already exist.
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">config.<span style="color:#9900CC;">action_controller</span>.<span style="color:#9900CC;">perform_caching</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = <span style="color:#0000FF; font-weight:bold;">true</span></div></div>

</p>
<p>
<strong>Simply packing all stylesheets and javascripts into one file each reduced page load time of one of our production applications from 10.1 to 8.3 seconds (an 18% reduction in load time alone).</strong>
</p>
<h3>Creating an Amazon AWS Account</h3>
<p>
If you do not yet have an Amazon AWS account, you will need to create that and enable S3 and CloudFront services. See <a href="http://www.hongkiat.com/blog/amazon-s3-the-beginners-guide/">this writeup on creating and setting up an Amazon S3 account</a>. for helpful instructions.
</p>
<h2>Setup S3 Buckets</h2>
<p>
Once you&#8217;ve signed up for your Amazon AWS account and activated S3 and CloudFront, you&#8217;ll want to setup 4 S3 buckets for your application, using Amazons S3 management console.
</p><p>
We&#8217;re going to setup 4 buckets and CDN distributions because some old browsers still have an artificial limitation that only allow 2 concurrent connections to each domain, meaning our components will take longer to download from Amazon if they can only be downloaded 2 at a time. By creating 4 different domains pointing to 4 different buckets/distributions, we&#8217;re allowing our components to download up to 8 at a time from those browsers that still enforce this limitation.
</p>
<p>
<img src="http://www.alfajango.com/blog/wp-content/uploads/2010/06/amazon-s3-bucket-creation-e1276805768507.jpg" alt="" title="amazon-s3-bucket-creation" width="600" height="307" class="alignnone size-full wp-image-583" />
</p>
<div class="in-depth">
When naming your S3 buckets, avoid using periods if you would like the option of accessing your components directly from S3 over HTTPS. Amazon has a trusted SSL wildcard certificate for *.s3.amazonaws.com. 
<br /><br />
If you name your bucket <em>cdn0.yourapp.com</em>, then your components will have the URL <em>https://cdn0.yourapp.com.s3.amazonaws.com/stylesheet.css</em>. This will give you a warning message saying the connection is not trusted, because the browser treats your bucket name as subdomains (and in this case, <em>com.s3.amazonaws.com</em> would be trusted, but subdomains of that, <em>cdn0.yourapp</em> and <em>yourapp</em> will not).
</div>
<h2>Setup CloudFront Distributions</h2>
<p>
Once your S3 buckets are created, click over to the CloudFront tab and create one distribution for each S3 bucket as shown. You can type any comment to help you quickly identify each distribution.
</p>
<p>
<img src="http://www.alfajango.com/blog/wp-content/uploads/2010/06/amazon-cloudfront-distribution-creation-e1276805828838.jpg" alt="" title="amazon-cloudfront-distribution-creation" width="600" height="390" class="alignnone size-full wp-image-584" />
</p>
<h2>Create CNAME Records (optional)</h2>
<p>
Once you&#8217;ve created your 4 CloudFront distributions, you may create a CNAME record for each distribution. This allows you to serve files from CloudFront using your own asset subdomains, like <em>cdn0.yourapp.com</em>, instead of <em>raNDomString1234.cloudfront.net</em>. We&#8217;ll use the following format of <code class="codecolorer ruby default"><span class="ruby">cdn<span style="color:#006600; font-weight:bold;">%</span>d.<span style="color:#9900CC;">yourapp</span>.<span style="color:#9900CC;">com</span></span></code>, where <code class="codecolorer ruby default"><span class="ruby"><span style="color:#006600; font-weight:bold;">%</span>d</span></code> stands for digits 0-3:
</p><p>

<div class="codecolorer-container apache twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="apache codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cdn0.yourapp.com<br />
cdn1.yourapp.com<br />
cdn2.yourapp.com<br />
cdn3.yourapp.com</div></div>

</p><p>
<img src="http://www.alfajango.com/blog/wp-content/uploads/2010/06/amazon-cloudfront-cname-configuration.png" alt="" title="amazon-cloudfront-cname-configuration" width="334" height="557" class="alignnone size-full wp-image-580" />
</p>
<h2>Install Rails S3 Synch Plugin</h2>
<p>
This plugin adds some Capistrano recipes to synch our application&#8217;s <code class="codecolorer text default"><span class="text">public</span></code> directory with our four S3 buckets automatically every time we deploy our app. See <a href="http://spattendesign.com/2007/11/6/synching-your-amazon-s3-asset-host-using-capistrano">Spatten Design&#8217;s documentation</a> for more information. I&#8217;ve made some updates to their original plugin to properly set the Cache-control and Expires headers for our assets on S3, as well as to properly set the Content-encoding header for Gzipped assets.
</p>
<p class="note">Update: I&#8217;ve updated the S3 Synch Plugin further; it can now handle unique S3 buckets for different Rails environments (e.g. one set of buckets for production and another for staging). Be sure to update your synch_s3_asset_host.yml file as shown below.</p>
<p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">.<span style="color:#006600; font-weight:bold;">/</span>script<span style="color:#006600; font-weight:bold;">/</span>plugin install git:<span style="color:#006600; font-weight:bold;">//</span>github.<span style="color:#9900CC;">com</span><span style="color:#006600; font-weight:bold;">/</span>JangoSteve<span style="color:#006600; font-weight:bold;">/</span>synch_s3_asset_host.<span style="color:#9900CC;">git</span></div></div>

</p>
<h3>Installing AWS-S3 Gem</h3>
<p>The synch_s3_asset_host plugin requires the AWS-S3 gem, so add the following to your <code class="codecolorer ruby default"><span class="ruby">environment.<span style="color:#9900CC;">rb</span></span></code>:</p>
<p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">config.<span style="color:#9900CC;">gem</span> <span style="color:#996600;">&quot;aws-s3&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:lib</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;aws/s3&quot;</span></div></div>

</p><p>
&#8230;and then run the following from the terminal to install the S3 Synch plugin&#8217;s gem dependency:
</p><p>

<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> rake gems:<span style="color: #c20cb9; font-weight: bold;">install</span></div></div>

</p>
<h3>Configure S3 Synch Plugin</h3>
<p>
Create a <code class="codecolorer text default"><span class="text">config/synch_s3_asset_host.yml</span></code> file like this:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">AWS_ACCESS_KEY_ID: <span style="color:#996600;">'YOURKEYHERE'</span><br />
AWS_SECRET_ACCESS_KEY: <span style="color:#996600;">'YourSecretAccessKeyHere'</span><br />
production:<br />
&nbsp; asset_host_name: <span style="color:#996600;">&quot;yourapp-com-cdn%d&quot;</span> <span style="color:#008000; font-style:italic;"># This is whatever you named your S3 buckets, using %d in place of the numbers 0-3</span><br />
<span style="color:#008000; font-style:italic;"># dry_run: false # Set to true if you want to test the asset_host uploading without doing anything on Amazon S3</span></div></div>

</p>
<p class="note">Update: The &#8220;production&#8221; part in the file above has been added for my latest update of the S3 Asset Synch Plugin.</p>
<h3>Add S3 Synch to Deployment</h3>
<p>
Now, in your Capistrano <code class="codecolorer text default"><span class="text">deploy.rb</span></code> script, add the following line to the <code class="codecolorer ruby default"><span class="ruby"><span style="color:#ff3333; font-weight:bold;">:deploy</span></span></code> namespace:
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">namespace <span style="color:#ff3333; font-weight:bold;">:deploy</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; ...<br />
&nbsp; <span style="color:#9900CC;">before</span> <span style="color:#996600;">&quot;deploy:symlink&quot;</span>, <span style="color:#996600;">&quot;s3_asset_host:synch_public&quot;</span><br />
&nbsp; ...<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
&#8230;and then add the <code class="codecolorer ruby default"><span class="ruby"><span style="color:#ff3333; font-weight:bold;">:asset_host_syncher</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span></span></code> flag to the <code class="codecolorer ruby default"><span class="ruby"><span style="color:#ff3333; font-weight:bold;">:web</span></span></code> role:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
<span style="color:#9900CC;">role</span> <span style="color:#ff3333; font-weight:bold;">:web</span>, <span style="color:#996600;">&quot;yourapp.com&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:asset_host_syncher</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><br />
...</div></div>

</p>
<h2>Option A: Compressible Assets from App Server, Images from CloudFront (recommended)</h2>
<p>
For more detail about why this method is recommended, <a href="how-to-combine-gzip-plus-cdn-for-fastest-page-loads/">see the last article in this series</a>.
</p>
<h3>Configure Rails Asset Host</h3>
<p>
Use the following configuration in your <code class="codecolorer text default"><span class="text">production.rb</span></code> file to configure the way Rails writes the URLs for asset_tags:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># Enable serving of images, stylesheets, and javascripts from an asset server</span><br />
<span style="color:#008000; font-style:italic;"># config.action_controller.asset_host = &quot;http://assets.example.com&quot;</span><br />
<span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">ActionController::Base</span></span>.<span style="color:#9900CC;">asset_host</span> = <span style="color:#CC00FF; font-weight:bold;">Proc</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>source, request<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># the following will route to Amazon S3 + CloudFront if /images asset (setup with CNAMEs as domains cdn0-cdn3)</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># &nbsp; and will route to cdn for anything else (js, css, html), which routes to RMSR's own server so that files can be gzipped and served</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> source.<span style="color:#9900CC;">starts_with</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/images'</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">unless</span> request.<span style="color:#9900CC;">ssl</span>? <span style="color:#008000; font-style:italic;"># CloudFront does not support HTTPS, but S3 does</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;http://cdn#{source.hash % 4}.yourapp.com&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#008000; font-style:italic;"># For SSL we want the certificate to match the hosting domain for cloudfront</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;https://yourcloudfrontdist0.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist1.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist2.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist3.cloudfront.net&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>source.<span style="color:#9900CC;">hash</span> <span style="color:#006600; font-weight:bold;">%</span> 4<span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># use the cahed and zipped subdomain for assets that can be zipped (i.e. non-binary filetypes)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># =&gt; text/html text/css application/x-javascript application/javascript</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}cache.yourapp.com&quot;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div></div>

</p>
<div class="note">
If you did not configure custom CNAME records earlier, your Rails asset_host configuration would be a bit simpler:
<br /><br />

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">ActionController::Base</span></span>.<span style="color:#9900CC;">asset_host</span> = <span style="color:#CC00FF; font-weight:bold;">Proc</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>source, request<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">if</span> source.<span style="color:#9900CC;">starts_with</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/images'</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist0.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist1.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist2.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist3.cloudfront.net&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>source.<span style="color:#9900CC;">hash</span> <span style="color:#006600; font-weight:bold;">%</span> 4<span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">else</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># use the cahed and zipped subdomain for assets that can be zipped (i.e. non-binary filetypes)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># =&gt; text/html text/css application/x-javascript application/javascript</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}cache.yourapp.com&quot;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div></div>

</div>
<div class="in-depth">
Notice the <code class="codecolorer rails default"><span class="rails">source.<span style="color:#9900CC;">hash</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006666;">4</span></span></code> code above. This ensures that the same component is always served from the same subdomain to take full advantage of client-side caching for that component, rather than randomly selecting from which subdomain to serve each component on each page load.
<br /><br />
For more information on configuring Rails&#8217;s asset_host, <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html">see the documentation for <code class="codecolorer ruby default"><span class="ruby">Base.<span style="color:#9900CC;">asset_host</span></span></code></a>
</div>
<h3>Create A-name Record</h3>
<p>We will also need to create an A-name record for the <i>cache.yourapp.com</i> subdomain, which points to your application server&#8217;s IP address.</p>
<h3>Configure Apache</h3>
<p>
Now we need to configure Apache to accept incoming requests to our &#8220;cache&#8221; subdomain, setting the appropriate far-future Expires and Cache-control headers. We also need to tell Apache to automatically compress and serve any compressible filetype on the fly. Add this to your site&#8217;s Apache <code class="codecolorer text default"><span class="text">conf</span></code> file:
</p><p>

<div class="codecolorer-container apache twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="apache codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;"># gzip html, css, and js</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">AddOutputFilterByType</span> DEFLATE text/html text/css application/x-javascript application/javascript<br />
<br />
&nbsp; &nbsp;&lt;<span style="color: #000000; font-weight:bold;">virtualhost</span> *:80&gt;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">ServerName</span> cache.yourapp.com<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">DocumentRoot</span> /path/to/yourapp/public<br />
&nbsp; &nbsp; &nbsp; &lt;<span style="color: #000000; font-weight:bold;">filesmatch</span> <span style="color: #7f007f;">&quot;.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$&quot;</span>&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">ExpiresActive</span> <span style="color: #0000ff;">On</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">ExpiresDefault</span> <span style="color: #7f007f;">&quot;access plus 1 year&quot;</span><br />
&nbsp; &nbsp; &nbsp; &lt;/<span style="color: #000000; font-weight:bold;">filesmatch</span>&gt;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">FileETag</span> <span style="color: #0000ff;">none</span><br />
&nbsp; &nbsp;&lt;/<span style="color: #000000; font-weight:bold;">virtualhost</span>&gt;<br />
...</div></div>

</p>
<div class="in-depth">
Also note here that we turned off the ETag functionality for this subdomain. ETags (&#8220;entity tags&#8221;) are suppose to be a more flexible mechanism to query and invalidate cached assets, rather than using the last-modified_date of the file. <a href="http://developer.yahoo.com/performance/rules.html#etags">See Yahoo&#8217;s ETag description</a> for more info.
<br /><br />
However, the ETag&#8217;s uniqueness depends not just on the file, but usually on the server it&#8217;s being served from as well. This means if you have your assets copied to several asset domains on different servers, a file downloaded and cached from one server, and then the next page tries to pull the asset from another asset domain, the file&#8217;s ETag will not match the ETag of the cached file, so it will re-download the file instead of serving it from cache.
<br /><br />
Furthermore, Rails does a very good job of appending the last-modified-date to the asset file names (using the asset_tag helpers), which effectively serves, caches, and invalidates the assets for you as necessary. So, we&#8217;re much better off just turning ETags off for our Rails app.
</div>
<p>
Now we need to make sure the appropriate Apache modules are enabled and restart Apache.
</p><p>

<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">sudo</span> a2enmod deflate<br />
<span style="color: #c20cb9; font-weight: bold;">sudo</span> a2enmod expires<br />
<span style="color: #c20cb9; font-weight: bold;">sudo</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span>apache2 force-reload</div></div>

</p>
<h2>Option B: Serve Everything from CloudFront (easier, but not recommended)</h2>
<p>
For more detail about why this is not recommended, <a href="how-to-combine-gzip-plus-cdn-for-fastest-page-loads/">see the last article in this series</a>. Basically, though, it&#8217;s because it requires you to make one of the following compromises:
</p>
<ul>
<li>a) Serve all files uncompressed, resulting in file sizes up to 4x bigger than necessary.</li>
<li>b) Serve Gzipped assets from CloudFront without first detecting whether or not the visitor&#8217;s browser support Gzip encoding.</li>
</ul>
<p>
That being said, if this is acceptable for you, this method is simpler to set up and configure.
</p>
<h3>Configure Rails Asset Host</h3>
<p>Add the following to your <code class="codecolorer text default"><span class="text">production.rb</span></code>:</p>
<p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">ActionController::Base</span></span>.<span style="color:#9900CC;">asset_host</span> = <span style="color:#CC00FF; font-weight:bold;">Proc</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>source, request<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; <span style="color:#008000; font-style:italic;"># Enable serving of images, stylesheets, and javascripts from an asset server</span><br />
&nbsp; <span style="color:#008000; font-style:italic;"># config.action_controller.asset_host = &quot;http://assets.example.com&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">unless</span> request.<span style="color:#9900CC;">ssl</span>? <span style="color:#008000; font-style:italic;"># CloudFront does not support HTTPS, but S3 does</span><br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;http://cdn#{source.hash % 4}.yourapp.com&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">else</span> <span style="color:#008000; font-style:italic;"># For SSL we want the certificate to match the hosting domain for cloudfront</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;https://yourcloudfrontdist0.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist1.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist2.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color:#996600;">&quot;https://yourcloudfrontdist3.cloudfront.net&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>source.<span style="color:#9900CC;">hash</span> <span style="color:#006600; font-weight:bold;">%</span> 4<span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>

</p>
<div class="note">
Again, if you did not configure custom CNAME records earlier, your Rails asset_host will be a bit simpler:
<br /><br />

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">ActionController::Base</span></span>.<span style="color:#9900CC;">asset_host</span> = <span style="color:#CC00FF; font-weight:bold;">Proc</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>source, request<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist0.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist1.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist2.cloudfront.net&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;#{request.protocol}yourcloudfrontdist3.cloudfront.net&quot;</span> <span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span>source.<span style="color:#9900CC;">hash</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006666;">4</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div></div>

</div>
<h3>Pre-compile Cached Stylesheet and Javascript File</h3>
<p>
If you&#8217;re serving every component from CloudFront, you will need to pre-compile your stylesheets and javascripts on every deploy. Otherwise, Rails will try to compile and save the files to your application server, but try to serve them from S3 (where they won&#8217;t exist).
</p><p>
To solve this, we&#8217;ll add some Capistrano scripts to our <code class="codecolorer text default"><span class="text">deploy.rb</span></code> to compile our files for us before the synch_s3_asset_host plugin copies our <code class="codecolorer text default"><span class="text">public</span></code> directory over to our S3 buckets. But this means, we&#8217;d have to copy the list of asset files to be compiled into our Capistrano script, as well as having them listed in our <code class="codecolorer text default"><span class="text">application.html.erb</span></code> layout. To DRY things up a little, we&#8217;re going to create some project-wide constants:
</p><p>
<code class="codecolorer text default"><span class="text">lib/assets_for_cache.rb</span></code>
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">module</span> AssetsForCache<br />
&nbsp; &nbsp;JAVASCRIPT_FILES = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'jquery'</span>, <span style="color:#996600;">'jquery-ui'</span>, <span style="color:#996600;">'application'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp;STYLESHEET_FILES = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'reset'</span>, <span style="color:#996600;">'application'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp;JAVASCRIPT_CACHE_FILE = <span style="color:#996600;">'all-app-javascripts'</span><br />
&nbsp; &nbsp;STYLESHEET_CACHE_FILE = <span style="color:#996600;">'all-app-stylesheets'</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
And then replace your <code class="codecolorer ruby default"><span class="ruby">javascript_include_tag</span></code> and <code class="codecolorer text default"><span class="text">stylesheet_link_tag</span></code> in your application layout with the following:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">javascript_include_tag</span> <span style="color:#6666ff; font-weight:bold;">AssetsForCache::JAVASCRIPT_FILES</span>, <span style="color:#ff3333; font-weight:bold;">:cache</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">AssetsForCache::JAVASCRIPT_CACHE_FILE</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">stylesheet_link_tag</span> <span style="color:#6666ff; font-weight:bold;">AssetsForCache::STYLESHEET_FILES</span>, <span style="color:#ff3333; font-weight:bold;">:cache</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#6666ff; font-weight:bold;">AssetsForCache::STYLESHEET_CACHE_FILE</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></div></div>

</p><p>
Add this to your deploy.rb script:
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;height:300px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">namespace <span style="color:#ff3333; font-weight:bold;">:assets</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp;<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/../lib/assets_for_cache.rb'</span><br />
&nbsp; &nbsp;set <span style="color:#ff3333; font-weight:bold;">:stylesheets</span>, <span style="color:#6666ff; font-weight:bold;">AssetsForCache::STYLESHEET_FILES</span><br />
&nbsp; &nbsp;set <span style="color:#ff3333; font-weight:bold;">:javascripts</span>, <span style="color:#6666ff; font-weight:bold;">AssetsForCache::JAVASCRIPT_FILES</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;task <span style="color:#ff3333; font-weight:bold;">:package_cached_assets</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; package_stylesheets<br />
&nbsp; &nbsp; &nbsp; package_javascripts<br />
&nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;task <span style="color:#ff3333; font-weight:bold;">:package_stylesheets</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:web</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp;sudo <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>rm <span style="color:#006600; font-weight:bold;">-</span>f <span style="color:#008000; font-style:italic;">#{release_path}/public/stylesheets/#{AssetsForCache::STYLESHEET_CACHE_FILE}.css}</span><br />
&nbsp; &nbsp; &nbsp;stylesheets.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>stylesheet<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;run <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>cat <span style="color:#008000; font-style:italic;">#{release_path}/public/stylesheets/#{stylesheet}.css &gt;&gt; \</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;">#{release_path}/public/stylesheets/#{AssetsForCache::STYLESHEET_CACHE_FILE}.css}</span><br />
&nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp;run <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>gzip <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#008000; font-style:italic;">#{release_path}/public/stylesheets/#{AssetsForCache::STYLESHEET_CACHE_FILE}.css &gt; #{release_path}/public/stylesheets/#{AssetsForCache::STYLESHEET_CACHE_FILE}.css.gz}</span><br />
&nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp;task <span style="color:#ff3333; font-weight:bold;">:package_javascripts</span>, <span style="color:#ff3333; font-weight:bold;">:roles</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:web</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp;sudo <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>rm <span style="color:#006600; font-weight:bold;">-</span>f <span style="color:#008000; font-style:italic;">#{release_path}/public/javascripts/#{AssetsForCache::JAVASCRIPT_CACHE_FILE}.js}</span><br />
&nbsp; &nbsp; &nbsp;javascripts.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>javascript<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;run <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>cat <span style="color:#008000; font-style:italic;">#{release_path}/public/javascripts/#{javascript}.js &gt;&gt; \</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#008000; font-style:italic;">#{release_path}/public/javascripts/#{AssetsForCache::JAVASCRIPT_CACHE_FILE}.js}</span><br />
&nbsp; &nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; &nbsp;run <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>gzip <span style="color:#006600; font-weight:bold;">-</span>c <span style="color:#008000; font-style:italic;">#{release_path}/public/javascripts/#{AssetsForCache::JAVASCRIPT_CACHE_FILE}.js &gt; #{release_path}/public/javascripts/#{AssetsForCache::JAVASCRIPT_CACHE_FILE}.js.gz}</span><br />
&nbsp; &nbsp;<span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
&#8230;and then add this to the <code class="codecolorer ruby default"><span class="ruby"><span style="color:#ff3333; font-weight:bold;">:deploy</span></span></code> namespace in your <code class="codecolorer text default"><span class="text">deploy.rb</span></code> file, before calling the s3_asset_host sync script:
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">namespace <span style="color:#ff3333; font-weight:bold;">:deploy</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; ...<br />
&nbsp; <span style="color:#9900CC;">before</span> <span style="color:#996600;">&quot;deploy:symlink&quot;</span>, <span style="color:#996600;">&quot;assets:package_cached_assets&quot;</span><br />
&nbsp; before <span style="color:#996600;">&quot;deploy:symlink&quot;</span>, <span style="color:#996600;">&quot;s3_asset_host:synch_public&quot;</span><br />
&nbsp; ...<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p>
<h2>Conclusion</h2>
<p>
Now simply save your project and deploy it! The first deploy will take quite a while, as your entire /public directory will be copied to all 4 buckets on Amazon S3, one at a time. But after that, it&#8217;s a painless process. 
</p>
<div class="in-depth">
If you have any files or directories in your public folder that are not assets to be copied to S3 (like a WordPress blog or whatever), you can add them to the <code class="codecolorer text default"><span class="text">--exclude</span></code> list in the synch_s3_asset_host plugin on line 186 of <code class="codecolorer text default"><span class="text">vendor/plugins/synch_s3_asset_host/recipes/synch_s3_asset_host.rb</span></code>
</div>
<p>
Whether you chose the &#8220;recommended&#8221; or the &#8220;easier&#8221; option, you should immediately notice a significant increase in the performance of your Rails app. Thanks for sticking with me through this 4-part series! Please let me know if you have any thoughts, questions, or feedback in the comments.
</p>]]></content:encoded>
			<wfw:commentRss>http://www.alfajango.com/blog/caching-zipping-and-cdn-for-a-rails-app/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Make Sure Your Rails Application is Actually Caching (and not just pretending)</title>
		<link>http://www.alfajango.com/blog/make-sure-your-rails-application-is-actually-caching-and-not-just-pretending/</link>
		<comments>http://www.alfajango.com/blog/make-sure-your-rails-application-is-actually-caching-and-not-just-pretending/#comments</comments>
		<pubDate>Thu, 11 Mar 2010 17:58:00 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[Phusion Passenger]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[caching]]></category>
		<category><![CDATA[mod_rails]]></category>
		<category><![CDATA[passenger]]></category>

		<guid isPermaLink="false">http://www.alfajango.com/blog/?p=177</guid>
		<description><![CDATA[We recently worked on a Rails application that had page and action caching set up, only to find that it was not actually working. It occurred to me that many Rails/Passenger/Apache applications may have caching set up in a way that it appears to be caching, when it is not actually caching.]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://www.alfajango.com/blog/wp-content/uploads/2010/03/rails-cache-broken.jpg"><img class="alignright size-full wp-image-181" title="rails-cache-broken" src="http://www.alfajango.com/blog/wp-content/uploads/2010/03/rails-cache-broken.jpg" alt="" width="300" height="312" /></a>We recently worked on a Rails application that had page and action caching set up, only to find that it was not actually working. It occurred to me that many Rails/Passenger/Apache applications may have caching set up in a way that it appears to be caching, when it is not actually caching. Searching through the interwebs for various Passenger/Apache configurations, such as <a href="http://wiki.github.com/browsermedia/browsercms/page-caching-with-phusion-passenger">this snippet on Github</a> or <a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/dde48ec055f6519f">this discussion on Google Groups</a>, I found that many did not work with the most recent version of <a href="http://modrails.com/">Phusion Passenger</a>. What&#8217;s more, these configurations give the appearance that they <em>are</em> working.
</p><p>
For an introduction to caching with Rails, check out this post: <a href="http://guides.rubyonrails.org/caching_with_rails.html">Caching With Rails: An Overview</a>
</p>
<h2>The Appearance That Caching Works</h2>
<p>
Here is what I mean by giving the appearance that caching is working:
</p><p>
<ol>
	<li>you add <code class="codecolorer rails default"><span class="rails">caches_page <span style="color:#ff3333; font-weight:bold;">:index</span></span></code> to your controller, for example</li>
	<li>configure and restart your server</li>
	<li>load the index page</li>
	<li>check your rails cache directory on your server, and see the index.html</li>
	<li>it works! (hint: this step is wrong, you&#8217;re not quite there yet)</li>
</ol>
</p><p>
Just because Rails is generating your cached page does not mean that your server is subsequently serving the cached <code class="codecolorer text default"><span class="text">.html</span></code> file instead of sending the request to Rails again.
</p>
<h2>Ensure It&#8217;s Serving the Cached Page</h2>
<p>
To make sure it&#8217;s subsequently serving the cached page, the easiest method is to look at the created date on the cached file on your server, for instance:
</p>
<span id="more-177"></span>
<p>

<div class="codecolorer-container bash twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> myapp<span style="color: #000000; font-weight: bold;">/</span>public<span style="color: #000000; font-weight: bold;">/</span>cache</div></div>

</p><p>
You will get an output similar to this:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-rw-r--r-- 1 deploy deploy 10930 2010-03-09 17:49 index.html</div></div>

</p><p>
Now wait a minute, and then reload the page in your browser. Once again type <code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #660033;">-l</span> myapp<span style="color: #000000; font-weight: bold;">/</span>public<span style="color: #000000; font-weight: bold;">/</span>cache</span></code>, and make sure that the file still shows the same created date/time. If it instead shows this:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">-rw-r--r-- 1 deploy deploy 10930 2010-03-09 17:50 index.html</div></div>

</p><p>
&#8230;then you have a problem. Your server is sending every request back to Rails, where Rails is then re-generating the cached page.
</p><p>
<em><strong>Alternative 1</strong>: You can also use Apache&#8217;s <code class="codecolorer apache default"><span class="apache"><span style="color: #00007f;">RewriteLog</span></span></code> to watch what is being served. Just add this to your site&#8217;s <code class="codecolorer text default"><span class="text">.conf</span></code> file and then <code class="codecolorer bash default"><span class="bash"><span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">-f</span></span></code> the rewrite_log:</em>
</p><p>

<div class="codecolorer-container apache twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="apache codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:<span style="color: #ff0000;">80</span>&gt;<br />
&nbsp; ...<br />
&nbsp; <span style="color: #adadad; font-style: italic;"># Comment out to disable rewrite debugging</span><br />
&nbsp; <span style="color: #00007f;">RewriteLog</span> /path/to/myapp/current/log/rewrite_log<br />
&nbsp; <span style="color: #00007f;">RewriteLogLevel</span> 9<br />
&nbsp; ...<br />
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</div></div>

</p><p>
<em><strong>Alternative 2:</strong> You can also use the <code class="codecolorer bash default"><span class="bash">top</span></code> command to watch your running processes and make sure the rails process doesn&#8217;t rise to the top while reloading your page. This is obviously not very scientific, though, and won&#8217;t work if you have any external traffic on the site.</em>
<h2>The Solution: Proper Server Configuration</h2>
The problem here is that your server is not properly configured to intercept calls to cached pages. This could take a bit of Googling and debugging, but the important thing here is that we&#8217;ve identified the problem and how to tell when it&#8217;s fixed. For completion&#8217;s sake, I&#8217;ll go ahead and show the proper configuration we&#8217;ve determined for Passenger 2.2.8:
</p><p>

<div class="codecolorer-container apache twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="apache codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:80&gt;<br />
&nbsp; ...<br />
&nbsp; RailsAllowModRewrite <span style="color: #0000ff;">on</span><br />
&nbsp; <span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span><br />
&nbsp; <span style="color: #adadad; font-style: italic;">#apache should serve cached pages</span><br />
&nbsp; <span style="color: #00007f;">RewriteRule</span> ^/$ /cache/index.html [QSA]<br />
&nbsp; <span style="color: #00007f;">RewriteRule</span> ^([^.]+)$ /cache/$1.html [QSA]<br />
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</div></div>

</p>
<div class="in-depth">
UPDATE: Christoffer Sawicki has <a href="http://termos.vemod.net/page-caching-with-rails-and-passenger">a set of rewrite rules</a> that I like much better than what I originally posted here. These rules explicitly check to make sure the cached file exists and that the current request is a GET request (instead of a POST, PUT, or DELETE), without relying on Rails magic. In short, use these instead:
<p>

<div class="codecolorer-container apache twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="apache codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span> *:80&gt;<br />
&nbsp; ...<br />
&nbsp; RailsAllowModRewrite <span style="color: #0000ff;">On</span> &nbsp;<br />
&nbsp; <span style="color: #00007f;">RewriteEngine</span> <span style="color: #0000ff;">On</span><br />
<br />
&nbsp; <span style="color: #00007f;">RewriteCond</span> %{THE_REQUEST} ^(GET|HEAD)<br />
&nbsp; <span style="color: #00007f;">RewriteCond</span> %{REQUEST_URI} ^/([^.]+)$<br />
&nbsp; <span style="color: #00007f;">RewriteCond</span> %{DOCUMENT_ROOT}/cache/%1.html -f<br />
&nbsp; <span style="color: #00007f;">RewriteRule</span> ^/[^.]+$ /cache/%1.html [QSA,L]<br />
<br />
&nbsp; <span style="color: #00007f;">RewriteCond</span> %{THE_REQUEST} ^(GET|HEAD)<br />
&nbsp; <span style="color: #00007f;">RewriteCond</span> %{DOCUMENT_ROOT}/cache/index.html -f<br />
&nbsp; <span style="color: #00007f;">RewriteRule</span> ^/$ /cache/index.html [QSA,L]<br />
&lt;/<span style="color: #000000; font-weight:bold;">VirtualHost</span>&gt;</div></div>

</p>
</div>
<p>
Happy caching! For more tips for getting the best performance out of your server, check out <a href="http://www.alfajango.com/blog/performance-tuning-for-phusion-passenger-an-introduction/">Performance Tuning for Phusion Passenger (An Introduction)</a>, and <a href="http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin/">How to Monitor Your Rails/Passenger App with Munin</a>.
</p>
<h2><em>Update: Proper Nginx Configuration</em></h2>
<p>
For extra completeness, thank you to <em>atambo</em> on <a href="http://news.ycombinator.com/item?id=1185473">Hacker News</a> for pointing me to <a href="http://brainspl.at/nginx.conf.txt">this proper configuration for Rails caching on Nginx</a>. You can read the comments for an explanation.
</p>]]></content:encoded>
			<wfw:commentRss>http://www.alfajango.com/blog/make-sure-your-rails-application-is-actually-caching-and-not-just-pretending/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Include Your Rails App Layout in Your Wordpress Theme (or any PHP application)</title>
		<link>http://www.alfajango.com/blog/how-to-include-your-rails-app-layout-in-your-wordpress-theme-or-any-php-application/</link>
		<comments>http://www.alfajango.com/blog/how-to-include-your-rails-app-layout-in-your-wordpress-theme-or-any-php-application/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 22:31:48 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[integration]]></category>

		<guid isPermaLink="false">http://www.alfajango.com/blog/?p=68</guid>
		<description><![CDATA[Here's the problem: You have a Ruby on Rails application and its Wordpress blog. For the sake of consistency and branding, you'd like to use the same layout in your Wordpress blog as you do for your Rails app. Perhaps your blog is one of the main links or tabs in your application's header.]]></description>
			<content:encoded><![CDATA[<p>
<strong>Here&#8217;s the problem:</strong> You have a <a href="http://rubyonrails.org/">Ruby on Rails</a> application and its <a href="http://wordpress.org/">Wordpress</a> blog. For the sake of consistency and branding, you&#8217;d like to use the same layout in your Wordpress blog as you do for your Rails app. Perhaps your blog is one of the main links or tabs in your application&#8217;s header.
</p><p>
<img class="size-full wp-image-133 alignnone" title="rails-wordpress-link" src="http://www.alfajango.com/blog/wp-content/uploads/2010/02/rails-wordpress-link.jpg" alt="" width="500" height="233" />
</p><p>
<strong>Why this doesn&#8217;t work:</strong> You proceed with creating a custom theme for your Wordpress blog that looks exactly like your Rails application. Then over the next couple years, you begin to realize how tedious this solution is. You have to copy over your CSS stylesheets from your Rails app, your Javascript files (if your standard layout contains any Javascript elements, like a Twitter widget in the footer or whatever), and your layout images and assets. Then, every time you change or update the layout of your Rails app, you have to copy the changes in your custom Wordpress theme. And you cannot just copy the changes, because if you have any Ruby/Rails functionality in the layout, you have to translate them into PHP functionality in your Wordpress layouts.
</p><p>
And then there&#8217;s the impossible stuff&#8230; if anything in your Rails app layout loads information from the database in your Rails app, then you cannot have those elements in your Wordpress layout, unless you do something like create an XML or JSON feed in your Rails app and then import it in your Wordpress layout. But this is quite tedious still if you want to change any of it!
</p><p>
There&#8217;s an easier way.
</p>
<h3>Include Your Rails Layout Directly In Your Wordpress Layout</h3>
<p>
The solution I found turns out to be quite simple. The basic idea is to create a <code class="codecolorer rails default"><span class="rails"><span style="color:#ff3333; font-weight:bold;">:partial</span></span></code> in your Rails app layout, make it publicly accessible via your <code class="codecolorer text default"><span class="text">config/routes.rb</span></code>, have it generate and simply return the appropriate html using your controller method, and then import that html (and CSS) in your Wordpress layout.
</p>
<span id="more-68"></span>
<p>
For this to really work well, you&#8217;ll want to make sure that you make your Rails app cache the partials to be imported into your Wordpress layout, so that a lot of traffic on your blog doesn&#8217;t cause your Rails app server to explode.
</p>
<h3>1. Break Your Rails Layout into Partials</h3>
<p>
The first step is to break as much of your <code class="codecolorer text default"><span class="text">app/views/layouts/application.html.erb</span></code> into partials as possible/desired. At the very least, this means a header and a footer partial. Typically, you would not include the stuff in the <code class="codecolorer html4strict default"><span class="html4strict"><span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/head.html"><span style="color: #000000; font-weight: bold;">head</span></a>&gt;</span></span></code> part of the layout, because your Wordpress will likely require additional stylesheets and a different set of javascripts (not to mention you&#8217;ll want to make your meta information specific for your blog pages).
</p><p>
A simple Rails layout using this method would look something like this:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'&gt;<br />
&lt;html&gt;<br />
&nbsp; &lt;head&gt;<br />
&nbsp; &nbsp; ...<br />
&nbsp; &lt;/head&gt;<br />
&nbsp; &lt;body&gt;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'static/header'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &lt;div id=&quot;content&quot;&gt;<br />
&nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &lt;/div&gt;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'static/footer'</span><span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'static/widgets'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &lt;/body&gt;<br />
&lt;/html&gt;</div></div>

</p><p>
I&#8217;ve also included a widgets partial to show that this can be done with static javascript widgets as well.
</p><p>
Note that your layout and partials can have any and all Ruby/Rails code in them that you want. Since your Wordpress theme is importing this stuff from your Rails application, the Rails app will run as usual and just return the end result, which is HTML, so your Wordpress will have no problem interpreting it.
</p><p>
A simple <code class="codecolorer text default"><span class="text">app/views/static/_header.html.erb</span></code> partial may look something like this:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;div id=&quot;header&quot;&gt;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#5A0A0A; font-weight:bold;">image_tag</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;layout/my_logo.png&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>, root_path, <span style="color:#ff3333; font-weight:bold;">:alt</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;My Rails App&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;banner_logo&quot;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &lt;div id=&quot;menu&quot;&gt;<br />
&nbsp; &nbsp; &lt;ul&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">&quot;Products&quot;</span>, products_path, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span> <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">path</span> == products_path<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &lt;/li&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">&quot;Blog&quot;</span>, blog_path, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@blog</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &lt;/li&gt;<br />
&nbsp; &nbsp; &nbsp; &lt;li&gt;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#5A0A0A; font-weight:bold;">link_to</span> <span style="color:#996600;">&quot;Contact&quot;</span>, contact_path, :<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span> <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">path</span> == contact_path<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span><br />
&nbsp; &nbsp; &nbsp; &lt;/li&gt;<br />
&nbsp; &nbsp; &lt;/ul&gt;<br />
&nbsp; &lt;/div&gt;<br />
&lt;/div&gt;</div></div>

</p><p>
Notice that the normal links in the header are &#8220;active&#8221; simply if the current URL matches the link path, but the &#8220;Blog&#8221; link is active if the <code class="codecolorer ruby default"><span class="ruby"><span style="color:#0066ff; font-weight:bold;">@blog</span></span></code> variable is set and true. This is because, as you will see in the next section, the URL for the header when it is called from your blog won&#8217;t be the blog URL.
</p>
<h3>2. Make Your Layout Partials Publicly Accessible</h3>
<p>
The next step is to make your layout partials publicly accessible. I.e. make it so that you can access your layout partials from the browser using a direct URL, like http://mysite.com/static/header. The actual URL you use doesn&#8217;t really matter, because users won&#8217;t ever need to see or use it.
</p><p>
The way we do this is to explicitly set a path for each layout partial in our <code class="codecolorer text default"><span class="text">config/routes.rb</span></code> and then create a controller method for each that renders the HTML generated by the partial.
</p><p>
A path in your routes for your header partial might look like this:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">ActionController::Routing</span></span>::Routes.<span style="color:#9900CC;">draw</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>map<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; ...<br />
&nbsp; <span style="color:#9900CC;">map</span>.<span style="color:#9900CC;">header_partial</span> <span style="color:#996600;">'static/my_blog_header'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">'static'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">'blog_header_partial'</span><br />
&nbsp; ...<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
Then in the <code class="codecolorer text default"><span class="text">app/controllers/static_controller.rb</span></code>, your corresponding action would look like this:
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> blog_header_partial<br />
&nbsp; <span style="color:#0066ff; font-weight:bold;">@blog</span> = <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; <span style="color:#5A0A0A; font-weight:bold;">render</span> <span style="color:#ff3333; font-weight:bold;">:partial</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;">'static/header'</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
Now, hopefully you see why, in the header partial, we couldn&#8217;t just say that the blog menu item is <code class="codecolorer rails default"><span class="rails">:<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span> <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">path</span> == blog_path<span style="color:#006600; font-weight:bold;">&#41;</span></span></code>. The path that the header partial will be seeing when the Wordpress layout requests it will be the path you defined in your <code class="codecolorer text default"><span class="text">routes.rb</span></code>, in this case <code class="codecolorer text default"><span class="text">&quot;static/header&quot;</span></code>. This is why we instead say <code class="codecolorer rails default"><span class="rails">:<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@blog</span><span style="color:#006600; font-weight:bold;">&#41;</span></span></code> and then set <code class="codecolorer ruby default"><span class="ruby"><span style="color:#0066ff; font-weight:bold;">@blog</span> = <span style="color:#0000FF; font-weight:bold;">true</span></span></code> in the controller action.
</p>
<h3>Include the Rails Partials In the Wordpress Layout</h3>
<p>
Here&#8217;s the real trick. In order to include the Rails partials in your Wordpress layout, you might be inclined to use on of these PHP functions: <a href="http://php.net/manual/en/function.include.php"><code class="codecolorer php default"><span class="php"><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></a> or <a href="http://www.php.net/manual/en/function.require.php"><code class="codecolorer php default"><span class="php"><span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></a>. This won&#8217;t work though for two reasons.
</p><p>
1) <a href="http://php.net/manual/en/function.include.php"><code class="codecolorer php default"><span class="php"><span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></a> and <a href="http://www.php.net/manual/en/function.require.php"><code class="codecolorer php default"><span class="php"><span style="color: #b1b100;">require</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></a> both read <code class="codecolorer text default"><span class="text">.php</span></code> files. However, your publicly-accessible layout partials are going to return straight HTML.
</p><p>
2) By default, neither method allows absolute URLs due to security precautions. You can change your PHP setup to allow this, but again, this is a security issue. Not to mention, for our purposes, you still would have to deal with reason 1 above.
</p><p>
Instead, we can use PHP&#8217;s function to retreive HTML code, <a href="http://us.php.net/manual/en/function.file-get-contents.php"><code class="codecolorer php default"><span class="php"><a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></span></code></a>.
</p><p>
In your wp-content/themes/my_theme/header.php file, you would then include this line:
</p><p>

<div class="codecolorer-container php twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
&lt;body&gt;<br />
&nbsp; <span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #000088;">$a</span> <span style="color: #339933;">=</span> <a href="http://www.php.net/file_get_contents"><span style="color: #990000;">file_get_contents</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;http://myrailsapp.com/static/my_blog_header&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$a</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><br />
...</div></div>

</p>
<h3>Import the Rails CSS Stylesheet for Wordpress</h3>
<p>
Of course, you&#8217;ll also want to import the base stylesheet that styles your layout HTML for your Wordpress theme. You can do this a few different ways. The easiest is to just include it in your <code class="codecolorer text default"><span class="text">header.php</span></code> file in the <code class="codecolorer text default"><span class="text">&lt;head&gt;</span></code> area like any other stylesheet, just using the absolute URL to the CSS file.
</p><p>

<div class="codecolorer-container html4strict twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="html4strict codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://myrailsapp.com/stylesheets/style.css&quot;</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/css&quot;</span> <span style="color: #000066;">media</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;screen&quot;</span> <span style="color: #66cc66;">/</span>&gt;</span><br />
<span style="color: #009900;">&lt;<a href="http://december.com/html/4/element/link.html"><span style="color: #000000; font-weight: bold;">link</span></a> <span style="color: #000066;">rel</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;stylesheet&quot;</span> <span style="color: #000066;">href</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;&lt;?php bloginfo('stylesheet_url'); ?&gt;</span></span>&quot; type=&quot;text/css&quot; media=&quot;screen&quot; /&gt;<br />
...</div></div>

</p><p>
Notice that we include the Rails app stylesheet before the blog stylesheet. This is so that it&#8217;s easy to override any of the styles we need to specifically in the blog stylesheet.
</p><p>
An alternative way we can do this is using the CSS <code class="codecolorer css default"><span class="css"><span style="color: #a1a100;">@import</span></span></code> method.
</p>
<h3>Cache the Layout Partials On Your Rails Server</h3>
The astute programmer in you may have noticed by now that this turns a single request on your blog into multiple additional requests on your Rails app server (one additional request per partial that&#8217;s imported in your Wordpress layout, e.g. header, footer, etc.). We can&#8217;t have that!
<p>
Luckily this is easy to fix with <a href="http://railsenvy.com/2007/2/28/rails-caching-tutorial#pagination">Rails&#8217;s built-in page-caching</a>.
</p><p>
In your <code class="codecolorer text default"><span class="text">app/controllers/static_controller.rb</span></code> file, include the following.
</p><p>

<div class="codecolorer-container rails twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="rails codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> StaticController <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApplicationController<br />
&nbsp; caches_page <span style="color:#ff3333; font-weight:bold;">:index</span>, <span style="color:#ff3333; font-weight:bold;">:blog_header_partial</span>, <span style="color:#ff3333; font-weight:bold;">:blog_header_footer</span>, <span style="color:#ff3333; font-weight:bold;">:blog_widgets</span><br />
&nbsp; ...<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>

</p><p>
And make sure that caching is turned on in your production app, in <code class="codecolorer text default"><span class="text">config/environments/production.rb</span></code>:
</p><p>

<div class="codecolorer-container ruby twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">...<br />
<span style="color:#9900CC;">config</span>.<span style="color:#9900CC;">action_controller</span>.<span style="color:#9900CC;">perform_caching</span> = <span style="color:#0000FF; font-weight:bold;">true</span><br />
config.<span style="color:#9900CC;">action_view</span>.<span style="color:#9900CC;">cache_template_loading</span> = <span style="color:#0000FF; font-weight:bold;">true</span><br />
...</div></div>

</p>
<h3>And/Or Cache Your Wordpress Pages (recommended)</h3>
<p>
Of course, if you <a href="http://wordpress.org/extend/plugins/wp-super-cache/installation/">install and setup caching in your Wordpress installation</a> (highly recommended), then the complete layout files will be cached and never even need to make calls to your Rails application after the cached pages are generated the first time. This is even faster for your Wordpress blog, because it&#8217;ll load faster now that it doesn&#8217;t have to import portions of the layout from an external URL every time a page is loaded.
</p><p>
Note that when you do this, you&#8217;ll need to expire/delete the cached Wordpress files anytime you update the layout in your Rails app.
</p>
<h3>Done!</h3>
<p>
Now you have a great looking Wordpress blog that looks like you&#8217;re never leaving your Rails application. And best of all, you don&#8217;t have to tediously duplicate efforts every time you update your Rails app layout! How&#8217;s that for <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> design?
</p>]]></content:encoded>
			<wfw:commentRss>http://www.alfajango.com/blog/how-to-include-your-rails-app-layout-in-your-wordpress-theme-or-any-php-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Monitor Your Rails/Passenger App with Munin</title>
		<link>http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin/</link>
		<comments>http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 15:35:23 +0000</pubDate>
		<dc:creator>steve</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[monitoring]]></category>
		<category><![CDATA[Munin]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.alfajango.com/blog/?p=65</guid>
		<description><![CDATA[Munin is a great tool to monitor resources on your server, showing graphs over time, so that you can analyze resource trends to find what's killing your server before it causes major problems. It is also very configurable and can be made to profile and graph just about anything via plugins. And with a couple tricks, you can get it to monitor your Phusion Passenger application with ease.]]></description>
			<content:encoded><![CDATA[<div id="attachment_70" class="wp-caption alignleft" style="width: 310px"><a href="http://www.alfajango.com/blog/wp-content/uploads/2010/02/Picture-10.png"><img class="size-medium wp-image-70 " title="Munin Passenger Plugin Graphs" src="http://www.alfajango.com/blog/wp-content/uploads/2010/02/Picture-10-300x189.png" alt="" width="300" height="189" /></a><p class="wp-caption-text"> </p></div><p>
<a href="http://munin.projects.linpro.no/">Munin</a> is a great tool to monitor resources on your server, showing graphs over time, so that you can analyze resource trends to find what&#8217;s killing your server before it causes major problems. It is also very configurable and can be made to profile and graph just about anything via plugins. And with a couple tricks, you can get it to monitor your <a href="http://www.modrails.com/">Phusion Passenger</a> application with ease.
</p><p>
If you already have Munin installed and working, and just want to know how to get the Passenger Plugins working, you can skip directly to Install <a href="http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin#install-munin-passenger-plugins">Munin Passenger Plugins</a>, <a href="http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin#configure-munin-for-passenger-stats">Configure Munin for Passenger Stats</a>, and be sure to read the <a href="http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin#gotcha">Gotcha</a>.
</p>
<span id="more-65"></span>
<h3>Install Munin and Munin-node</h3>
<p>
The first step is to install Munin. If you have your server running Ubuntu, this is pretty easy. One you&#8217;ve SSH&#8217;d into your server, enter:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo apt-get install munin munin-node -y</div></div>

</p><p>
If you&#8217;re running another flavor of Linux, see the <a href="http://munin.projects.linpro.no/wiki/LinuxInstallation">Munin&#8217;s Linux install instructions</a>. For Mac OSX, see <a href="http://munin.projects.linpro.no/wiki/DarwinInstallation">Mac install instructions</a>.
<a name="install-munin-passenger-plugins"></a>
</p>
<h3>Install Munin Passenger Plugins</h3>
<p>
The next step is to install the Passenger plugins. The first is passenger_status:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">wget http://gist.github.com/20319.txt<br />
sudo mv 20319.txt /usr/share/munin/plugins/passenger_status<br />
sudo chmod a+x /usr/share/munin/plugins/passenger_status<br />
sudo ln -s /usr/share/munin/plugins/passenger_status /etc/munin/plugins/passenger_status</div></div>

</p><p>
The second plugin is passenger_memory_stats:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">wget http://gist.github.com/21391.txt<br />
sudo mv 21391.txt /usr/share/munin/plugins/passenger_memory_stats<br />
sudo chmod a+x /usr/share/munin/plugins/passenger_memory_stats<br />
sudo ln -s /usr/share/munin/plugins/passenger_memory_stats /etc/munin/plugins/passenger_memory_stats</div></div>

</p><p>
No go ahead and restart Munin-node (this is the process that runs Munin at regular intervals):
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo /etc/init.d/munin-node restart</div></div>

<h3>Configure Munin</h3>
Now here are where those couple of tricks come in to get Munin playing nicely with your Rails application. First we want to tell Munin where to store the html and graph images that you can access through the browser.
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo nano /etc/munin/munin.conf</div></div>

</p><p>
And change the following lines:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">htmldir /path/to/your/rails/shared/directory/munin<br />
[yoursite.com]</div></div>

</p><p>
Note that the htmldir can really be any directory, but make sure it&#8217;s persistent (i.e. if you&#8217;re using Capistrano to keep revisions of your app on the server, make sure the munin directory is in the shared directory outside of your rails app root directory).
</p><p>
Also note that the <code class="codecolorer text default"><span class="text">[yoursite.com]</span></code> part is only a descriptive name, so it really doesn&#8217;t matter what you call it. If you have a more complex application that runs from multiple directories or multiple servers, you can group Munin stats, and in this case, you actually have to put some thought into this line. But that&#8217;s outside the scope of this article, so you can read up on <a href="http://munin.projects.linpro.no/wiki/munin.conf">customizing Munin Master</a> on your own time if you&#8217;d like.
</p><p>
Now if you haven&#8217;t already, you need to actually create that directory you just told Munin about:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cd /path/to/your/rails/shared/directory<br />
mkdir -p munin<br />
sudo chown munin:munin munin</div></div>

<a name="configure-munin-for-passenger-stats"></a>
</p>
<h3>Configure Munin For Passenger Stats</h3>
<p>
And finally, you need to allow the munin user to run the <code class="codecolorer text default"><span class="text">passenger-status</span></code> and <code class="codecolorer text default"><span class="text">passenger-memory-stats</span></code> commands without a password, since they both require sudo powers to run properly.
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo visudo</div></div>

</p><p>
And at the bottom of the file add:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">munin   ALL=(ALL) NOPASSWD:/usr/bin/passenger-status, /usr/bin/passenger-memory-stats</div></div>

<a name="gotcha"></a>
</p>
<h3>Gotcha</h3>
<p>
At this point, Munin is suppose to start doing it&#8217;s stuff and all is happy in the ruby-munin marriage. For me, however, this was not the case. After combing the Munin error logs and digging through the Munin documentation and code more than I care to admit, I realized that Munin-node needs to preface the passenger stat commands with <code class="codecolorer text default"><span class="text">ruby</span></code>. So, here&#8217;s how we fix that:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo nano /etc/munin/plugin-conf.d/munin-node</div></div>

</p><p>
And then add this to the bottom of that file:
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">[passenger_*]<br />
user munin<br />
command ruby %c</div></div>

</p>
<h3>Final Munin Restart</h3>
<p>
Now we&#8217;ll give Munin-node one more restart and we&#8217;re in business.
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sudo /etc/init.d/munin-node restart</div></div>

</p><p>
After waiting a few minutes, you should start to see .html files and graphs and whatnot in the <code class="codecolorer text default"><span class="text">/path/to/your/rails/shared/directory/munin</span></code> directory. If not, you want to check out the Munin-node error logs to see what&#8217;s going on. On Ubuntu, this is found at <code class="codecolorer text default"><span class="text">/var/log/munin/munin-node.log</span></code>.
</p>
<h3>View Munin From Your Browser</h3>
<p>
So now, Munin is running, but what good is it if you can&#8217;t view the pretty output? Typically the best way to do this is through a sub-domain. If you have yoursite.com, let&#8217;s set up Munin to be viewable from munin.yoursite.com. All you need to do is point to the <code class="codecolorer text default"><span class="text">/path/to/your/rails/shared/directory/munin</span></code> directory for munin.yoursite.com in your site&#8217;s server conf file. For example, if you&#8217;re on Apache, you&#8217;d just do this in your <code class="codecolorer text default"><span class="text">sites-available/yoursite.conf</span></code>
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&lt;VirtualHost *:80&gt;<br />
ServerName munin.yoursite.com<br />
DocumentRoot /path/to/your/rails/shared/directory/munin<br />
&lt;/VirtualHost&gt;</div></div>

</p><p>
And make sure you have the proper A-name record setup for munin.yoursite.com with your NameServers.
</p><p>
Once domain propogation magic happens, you should now be able to see this when you navigate to munin.yoursite.com
</p><div id="attachment_75" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.alfajango.com/blog/wp-content/uploads/2010/02/Picture-12.png"><img class="size-medium wp-image-75" title="Munin main page" src="http://www.alfajango.com/blog/wp-content/uploads/2010/02/Picture-12-300x75.png" alt="" width="300" height="75" /></a><p class="wp-caption-text">Munin main page</p></div><p>
The Passenger stats will be in the &#8220;App&#8221; section.
</p><p>
Have fun now monitoring your Passenger Rails application with passenger usage trending. Remember to use your newfound power for good.
</p>
<h4><em>(irqstats patch)</em></h4>
<p>
If you find that the irqstats graph doesn&#8217;t work, you may need to <a href="http://munin.projects.linpro.no/attachment/ticket/598/munin_plugin_irqstats.patch">patch the irqstats plugin</a>. Basically you just need to <code class="codecolorer text default"><span class="text">sudo nano /etc/munin/plugins/irqstats</span></code> and change
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">if ($irq =~ /^\d+$/) {</div></div>

</p><p>
to
</p><p>

<div class="codecolorer-container text twitlight" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"># numeric values or something like NMI/RES/CAL are accepted<br />
if (($irq =~ /^\d+$/) || ($irq =~/^[A-Z]{3}$/)) {</div></div>

</p>]]></content:encoded>
			<wfw:commentRss>http://www.alfajango.com/blog/how-to-monitor-your-railspassenger-app-with-munin/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
