<?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>rel=me &#187; Deployment</title>
	<atom:link href="http://rel.me/c/deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://rel.me</link>
	<description>programming, objective-c, cocoa, iphone, c</description>
	<lastBuildDate>Mon, 02 Aug 2010 20:09:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>capitate &#8211; Capistrano plugins, recipes and templates</title>
		<link>http://rel.me/2008/05/08/capitate-capistrano-plugins-recipes-and-templates/</link>
		<comments>http://rel.me/2008/05/08/capitate-capistrano-plugins-recipes-and-templates/#comments</comments>
		<pubDate>Thu, 08 May 2008 19:28:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[capitate]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[recipes]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">/2008/05/13/capitate-capistrano-plugins-recipes-and-templates</guid>
		<description><![CDATA[Deployment is a hard problem. A working environment might rely on a bunch of configuration to be in sync across init scripts, conf files, install paths, environment variables, all in different types of codebases involving ruby, C, java and all with their own breed of dependency management. Imagine getting your database yaml in sync with [...]]]></description>
			<content:encoded><![CDATA[<p>Deployment is a hard problem. A working environment might rely on a bunch of configuration to be in sync across init scripts, conf files, install paths, environment variables, all in different types of codebases involving ruby, C, java and all with their own breed of dependency management. Imagine getting your database yaml in sync with your sphinx.conf and your nginx virtual host configuration pointing to your ports set up in mongrel or thin, and everything should be under something like monit which is checking ports and pid files in case something blows chunks along the way, and not to mention making sure all your logs go somewhere sane and configured to use syslog or logrotate. And trying to remember common setup tasks for the system itself, like setting up the database, setting grants, adding user(s), even building and installing packages from scratch. My brain can&#8217;t handle all that.</p>
<p>So I setup a project, called <a href="http://capitate.rubyforge.org/">capitate</a> which provides 3 things (and you can take or leave any of them at will): Plugins, Recipes and Templates.</p>
<h3>Plugins</h3>
<p>Capistrano has a plugin architecture. For example, the capitate prompt plugin gives you a beefier password prompt:</p>
<p>This will prompt for a password, ask you to re-type to verify, up to 3 times and will not be lazy initialized.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">set <span class="re3">:db_pass</span>, prompt.<span class="me1">password</span><span class="br0">&#40;</span><span class="st0">&quot;DB password: &quot;</span>, <span class="re3">:verify</span> <span class="sy0">=&gt;</span> <span class="kw2">true</span>, 
  <span class="re3">:max_attempts</span> <span class="sy0">=&gt;</span> <span class="nu0">3</span>, <span class="re3">:lazy</span> <span class="sy0">=&gt;</span> <span class="kw2">false</span><span class="br0">&#41;</span></pre></div></div>

<p>
This one prompts for a password and verifies it against an md5 hash and prompt happens when variable is first accessed.
</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">set <span class="re3">:db_pass</span>, prompt.<span class="me1">password</span><span class="br0">&#40;</span><span class="st0">&quot;DB password: &quot;</span>, <span class="re3">:verify</span> <span class="sy0">=&gt;</span> <span class="kw2">false</span>, 
  <span class="re3">:check_hash</span> <span class="sy0">=&gt;</span> <span class="st0">&quot;3e5e1c82fbed35282cf53608b80503a7&quot;</span><span class="br0">&#41;</span></pre></div></div>

<p>
More plugins are at: <a href="http://github.com/gabriel/capitate/tree/master/lib/capitate/plugins">lib/capitate/plugins</a>
</p>
<p>Adding plugins into capistrano is done by <code>Capistrano.plugin [namespace] [module]</code>. For example,</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span class="kw1">module</span> <span class="re2">Capitate::Plugins::Prompt</span>
  <span class="kw1">def</span> password<span class="br0">&#40;</span>label, options = <span class="br0">&#123;</span><span class="br0">&#125;</span><span class="br0">&#41;</span>
    ...
  <span class="kw1">end</span>
<span class="kw1">end</span>
Capistrano.<span class="me1">plugin</span> <span class="re3">:prompt</span>, <span class="re2">Capitate::Plugins::Prompt</span></pre></div></div>

<h3>Templates</h3>
<p>Most of the configuration files in capitate are erb templates, which allows you to dry up and share your configuration across templates. Here are some examples of templates we use: </p>
<ul>
<li><a href="http://github.com/gabriel/capitate/tree/master/lib/templates/nginx/nginx_vhost_generic.conf.erb">Nginx vhost config</a></li>
<li><a href="http://github.com/gabriel/capitate/tree/master/lib/templates/merb/merb.initd.centos.erb">Merb init script</a></li>
<li><a href="http://github.com/gabriel/capitate/tree/d7572bd50d1099e061bcbdec3d4d985c9acf434a/lib/templates/sphinx/sphinx.conf.erb">An example sphinx config with main/delta indexing</a></li>
<li><a href="http://github.com/gabriel/capitate/tree/master/lib/templates/mysql/my.cnf.innodb_1024.erb">Mysql cnf</a> for dedicated machine (1024 mb)</li>
</ul>
<p>Your templates maybe vary, but you get the idea.</p>
<h3>Recipes</h3>
<p>Recipes combine your templates, configuration and plugins into something more useful.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">set <span class="re3">:application</span>, <span class="st0">&quot;capitate&quot;</span>
&nbsp;
<span class="co1"># Merb config</span>
set <span class="re3">:merb_nodes</span>, <span class="nu0">5</span>
set <span class="re3">:merb_port</span>, <span class="nu0">9000</span>
set <span class="re3">:merb_pid_dir</span>, <span class="st0">&quot;#{shared_path}/pids&quot;</span>
set <span class="re3">:merb_pid_path</span>, <span class="st0">&quot;#{fetch(:merb_pid_dir)}/merb.pid&quot;</span>
&nbsp;
<span class="co1"># Nginx config</span>
set <span class="re3">:nginx_upstream_size</span>, fetch<span class="br0">&#40;</span><span class="re3">:merb_nodes</span><span class="br0">&#41;</span>
set <span class="re3">:nginx_upstream_port</span>, fetch<span class="br0">&#40;</span><span class="re3">:merb_port</span><span class="br0">&#41;</span>
set <span class="re3">:nginx_pid_path</span>, <span class="st0">&quot;/var/run/nginx.pid&quot;</span>
&nbsp;
task <span class="re3">:setup</span> <span class="kw1">do</span>
  merb.<span class="me1">centos</span>.<span class="me1">setup</span>
  merb.<span class="me1">monit</span>.<span class="me1">setup</span>
  nginx.<span class="me1">host</span>.<span class="me1">setup</span>  
<span class="kw1">end</span></pre></div></div>

<p>The setup task would generate <code>/etc/init.d/merb_capitate</code> init script, <code>/etc/monit/merb_capitate.monitrc</code>, and <code>/etc/nginx/vhosts/capitate.conf</code> files all with matching ports and pid files.</p>
<h3>To use it</h3>
<p>Throw this in your Capfile</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span class="kw3">require</span> <span class="st0">'capitate'</span>  
<span class="kw3">require</span> <span class="st0">'capitate/recipes'</span>
set <span class="re3">:project_root</span>, <span class="kw4">File</span>.<span class="me1">dirname</span><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span></pre></div></div>

<h3>Documenting recipes</h3>
<p>Part of creating recipes is documenting them, you can view capitate&#8217;s recipe documentation at:<br />
<a href="http://capitate.rubyforge.org/recipes/index.html">http://capitate.rubyforge.org/recipes/index.html</a></p>
<h3>Contribute</h3>
<p>Capitate is located at <a href="http://github.com/gabriel/capitate/tree/master">github</a>.</p>
<p>Deployment and configuration varies a lot, so your mileage will vary, but capitate can be a resource for storing all different types of recipes and templates, so feel free to fork and pull request. Forking is the new friending.</p>
]]></content:encoded>
			<wfw:commentRss>http://rel.me/2008/05/08/capitate-capistrano-plugins-recipes-and-templates/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>nginx conf with alternate cache dir</title>
		<link>http://rel.me/2008/01/07/nginx-conf-with-alternate-cache-dir/</link>
		<comments>http://rel.me/2008/01/07/nginx-conf-with-alternate-cache-dir/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 07:25:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">/2008/01/07/nginx-conf-with-alternate-cache-dir</guid>
		<description><![CDATA[Its a good idea to use an alternate cache directory in rails (in your environment.rb): config.action_controller.page_cache_directory = RAILS_ROOT + &#34;/public/cache/&#34; This makes it easier to sweep. To setup nginx to pick up from a rails alternate cache directory like public/cache, I used: if ($http_user_agent ~* &#34;(iPhone&#124;iPod)&#34;) { rewrite ^/$ /iphone break; proxy_pass http://mongrel-pt; break; } [...]]]></description>
			<content:encoded><![CDATA[<p>Its a good idea to use an alternate cache directory in rails (in your environment.rb):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">config.<span class="me1">action_controller</span>.<span class="me1">page_cache_directory</span> = RAILS_ROOT <span class="sy0">+</span> <span class="st0">&quot;/public/cache/&quot;</span></pre></div></div>

<p>This makes it easier to sweep. To setup nginx to pick up from a rails alternate cache directory like public/cache, I used:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">if ($http_user_agent ~* &quot;(iPhone|iPod)&quot;) {
  rewrite ^/$ /iphone break;
  proxy_pass http://mongrel-pt;
  break;
}
&nbsp;
if (-f $request_filename) {
  break;
}
&nbsp;
if (-f $document_root/cache/$uri/index.html) {
  rewrite (.*) /cache/$1/index.html break;
}
&nbsp;
if (-f $document_root/cache/$uri.html) {
  rewrite (.*) /cache/$1.html break;
}
&nbsp;
if (-f $document_root/cache/$uri) {
  rewrite (.*) /cache/$1 break;
}
&nbsp;
if (!-f $request_filename) {
  proxy_pass http://mongrel-pt;
  break;
}</pre></div></div>

<p>It was a little tricky to figure out to use the $uri variable. The first rewrite is used for iphone requests so it doesn&#8217;t get the non-iphone cached page.</p>
]]></content:encoded>
			<wfw:commentRss>http://rel.me/2008/01/07/nginx-conf-with-alternate-cache-dir/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>nginx</title>
		<link>http://rel.me/2007/09/03/nginx/</link>
		<comments>http://rel.me/2007/09/03/nginx/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 04:56:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[mongrel_cluster]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">/2007/09/03/nginx</guid>
		<description><![CDATA[I switched from apache + mod_proxy_balancer to nginx, which on my lame VPS is saving me around 14 precious MB of memory. There are so many reasons to use nginx. Ezra recommends the monit + nginx + mongrel_cluster stack, and my friend/co-worker has a great conf to start with. It took me about 5 minutes [...]]]></description>
			<content:encoded><![CDATA[<p>I switched from apache + mod_proxy_balancer to nginx, which on my lame VPS is saving me around 14 precious MB of memory. There are so many reasons to use nginx. <a href="http://engineyard.com/">Ezra</a> recommends the monit + nginx + mongrel_cluster stack, and my friend/co-worker <a href="http://www.fucema.net/2007/8/28/rails-on-mongrel-cluster-nginx">has a great conf</a> to start with. It took me about 5 minutes to setup, even with multiple hosts.</p>
<p>My <a href="/nginx_conf.txt">nginx.conf</a> and <a href="/nginx_init.txt">init script</a>.</p>
<p>Nginx is hyper optimized&#8230;</p>
<table class="CodeRay">
<tr>
<td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }">
<pre>1<tt>
</tt>2<tt>
</tt>3<tt>
</tt>4<tt>
</tt></pre>
</td>
<td class="code">
<pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }">./ngx_http_upstream.c:        if (h-&gt;value.len == 2) {<tt>
</tt>./ngx_http_upstream.c:            if (c0 == 'n' &amp;&amp; c1 == 'o') {<tt>
</tt>./ngx_http_upstream.c:        } else if (h-&gt;value.len == 3) {<tt>
</tt>./ngx_http_upstream.c:            if (c0 == 'y' &amp;&amp; c1 == 'e' &amp;&amp; c2 == 's') {</pre>
</td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://rel.me/2007/09/03/nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
