<?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>{ :ivan =&#62; :hq } &#187; Programación</title>
	<atom:link href="http://ivanhq.net/category/programacion/feed/" rel="self" type="application/rss+xml" />
	<link>http://ivanhq.net</link>
	<description>Unix, tecnología y algunas cosas sobre mí</description>
	<lastBuildDate>Sat, 18 Feb 2012 01:48:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>A motion-jpeg stream with Ruby and Sinatra</title>
		<link>http://ivanhq.net/2011/11/30/a-motion-jpeg-stream-with-ruby-and-sinatra/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a-motion-jpeg-stream-with-ruby-and-sinatra</link>
		<comments>http://ivanhq.net/2011/11/30/a-motion-jpeg-stream-with-ruby-and-sinatra/#comments</comments>
		<pubDate>Wed, 30 Nov 2011 11:37:57 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=584</guid>
		<description><![CDATA[I&#8217;ve been trying to set up a Motion-JPEG streaming with ruby, for a webcam which uploads a picture per second to a server. I want new images to be served via streaming instead of making the browser call them every second via a javascript call. I found many different solutions, some of them including EventMachine, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been trying to set up a Motion-JPEG streaming with ruby, for a webcam which uploads a picture per second to a server. I want new images to be served via streaming instead of making the browser call them every second via a javascript call.</p>
<p>I found many different solutions, some of them including EventMachine, which now is not necessary thanks to the <a href="http://thechangelog.com/post/10872694552/sinatra-1-3-is-out-adds-streaming-extensions">new Sinatra 1.3 streaming feature</a>.<br />
The tricky part was related to the headers, the boundary, and the need to send the content type before each image.</p>
<p>For the test I first created a directory and stored some pictures inside</p>
<div class="codecolorer-container bash blackboard" 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;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>images<br />
<span style="color: #666666; font-style: italic;"># place some jpg pictures here</span></div></div>
<p>And the code. My little app looks like this:</p>
<div class="codecolorer-container ruby blackboard" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:500px;"><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#008000; font-style:italic;"># motion_stream.rb</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'sinatra'</span><br />
set <span style="color:#ff3333; font-weight:bold;">:server</span>, <span style="color:#ff3333; font-weight:bold;">:thin</span><br />
<br />
get <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>dir<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; boundary &nbsp; &nbsp; &nbsp;= <span style="color:#996600;">'some_shit'</span><br />
&nbsp; source_dir &nbsp; &nbsp;= <span style="color:#996600;">'/tmp/images'</span><br />
<br />
&nbsp; headers \<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;Cache-Control&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;no-cache, private&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;Pragma&quot;</span> &nbsp; &nbsp; &nbsp; &nbsp;<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;no-cache&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#996600;">&quot;Content-type&quot;</span> &nbsp;<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;multipart/x-mixed-replace; boundary=#{boundary}&quot;</span><br />
<br />
&nbsp; stream<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:keep_open</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>out<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">while</span> <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; &nbsp; file &nbsp; &nbsp; &nbsp; &nbsp;= random_file<span style="color:#006600; font-weight:bold;">&#40;</span>source_dir<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;"># see also latest_file() below</span><br />
&nbsp; &nbsp; &nbsp; content &nbsp; &nbsp; = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{source_dir}/#{file}&quot;</span>, <span style="color:#996600;">'rb'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span> f.<span style="color:#9900CC;">read</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; out <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;Content-type: image/jpeg<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span><br />
&nbsp; &nbsp; &nbsp; out <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> content<br />
&nbsp; &nbsp; &nbsp; out <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>--#{boundary}<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">sleep</span> <span style="color:#006666;">1</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;">## get a random image from a directory</span><br />
<span style="color:#008000; font-style:italic;">##</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span> random_file<span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; files = <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">entries</span><span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span> file <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; files <span style="color:#006600; font-weight:bold;">-</span>= <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'.'</span>, <span style="color:#996600;">'..'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; files<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>files.<span style="color:#9900CC;">size</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;">## ... or get the newest image</span><br />
<span style="color:#008000; font-style:italic;">## In this case I'm not taking the latest file </span><br />
<span style="color:#008000; font-style:italic;">## uploaded by the camera, but the previous one.</span><br />
<span style="color:#008000; font-style:italic;">## This is to avoid grabbing a currently uploading </span><br />
<span style="color:#008000; font-style:italic;">## file, which may be shown as corrupt or incomplete.</span><br />
<span style="color:#008000; font-style:italic;">##</span><br />
<span style="color:#9966CC; font-weight:bold;">def</span> latest_file<span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; files = <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">entries</span><span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span> file <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">sort</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>file2,file1<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">mtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">+</span>file1<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&lt;=&gt;</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">mtime</span><span style="color:#006600; font-weight:bold;">&#40;</span>dir<span style="color:#006600; font-weight:bold;">+</span>file2<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; files <span style="color:#006600; font-weight:bold;">-</span>= <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'.'</span>, <span style="color:#996600;">'..'</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; files<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>Then simply create a Gemfile including Sinatra and Thin, as WebRick is not evented and does not support this kind of stream.</p>
<div class="codecolorer-container bash blackboard" 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: #666666; font-style: italic;"># Gemfile</span><br />
<span style="color: #7a0874; font-weight: bold;">source</span> :rubygems<br />
<br />
gem <span style="color: #ff0000;">'sinatra'</span><br />
gem <span style="color: #ff0000;">'thin'</span></div></div>
<p>And that&#8217;s all. Run the app and you&#8217;re done.</p>
<div class="codecolorer-container bash blackboard" 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">ruby motion_stream.rb</div></div>
<p>Just visit <b>http://localhost:4567/</b> with your browser :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2011/11/30/a-motion-jpeg-stream-with-ruby-and-sinatra/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Facebook apps, auto-resize and scroll to top</title>
		<link>http://ivanhq.net/2011/07/04/facebook-apps-auto-resize-and-scroll-to-top/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=facebook-apps-auto-resize-and-scroll-to-top</link>
		<comments>http://ivanhq.net/2011/07/04/facebook-apps-auto-resize-and-scroll-to-top/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 20:47:21 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Facebook applications]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=567</guid>
		<description><![CDATA[Have you ever written a Facebook application? One of the most common problems for iframe apps is making canvas auto-resize. It&#8217;s solved this way: &#160; &#160; &#60;div id=&#34;fb-root&#34;&#62;&#60;/div&#62; &#160; &#160; &#60;script&#62; &#160; &#160; &#160; window.fbAsyncInit = function() { &#160; &#160; &#160; &#160; FB.init({appId: 'YOUR_APP_ID_HERE', status: true, cookie: true, xfbml: true}); &#160; &#160; &#160; &#160; FB.Canvas.setAutoResize(); [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever written a Facebook application?<br />
One of the most common problems for iframe apps is making canvas auto-resize. It&#8217;s solved this way:</p>
<div class="codecolorer-container html4strict blackboard" 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">&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">div</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;fb-root&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">div</span>&gt;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span>&gt;</span><br />
&nbsp; &nbsp; &nbsp; window.fbAsyncInit = function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; FB.init({appId: 'YOUR_APP_ID_HERE', status: true, cookie: true, xfbml: true});<br />
&nbsp; &nbsp; &nbsp; &nbsp; FB.Canvas.setAutoResize();<br />
&nbsp; &nbsp; &nbsp; };<br />
<br />
&nbsp; &nbsp; &nbsp; (function() {<br />
&nbsp; &nbsp; &nbsp; &nbsp; var e = document.createElement('script'); e.async = true;<br />
&nbsp; &nbsp; &nbsp; &nbsp; e.src = document.location.protocol +<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '//connect.facebook.net/en_US/all.js';<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; document.getElementById('fb-root').appendChild(e);<br />
&nbsp; &nbsp; &nbsp; }());<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></div></div>
<p>Place this snippet after the body tag, and set your application (at facebook developers config center) to be auto-resizable. And that&#8217;s it!</p>
<p>Other common problem is how to make window scroll up when you click on a link. Usually the page renders but leaves you at the same vertical position you were before clicking.<br />
If you are suffering this and you are using jquery, you can solve it this way:</p>
<div class="codecolorer-container html4strict blackboard" 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">&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">script</span> <span style="color: #000066;">type</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;text/javascript&quot;</span>&gt;</span> <br />
&nbsp; &nbsp; &nbsp; jQuery(document).ready(function($) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; scrollTo(0,0);<br />
&nbsp; &nbsp; &nbsp; &nbsp; FB.Canvas.setSize({width: 760, height:$('body').height()+20});<br />
&nbsp; &nbsp; &nbsp; });<br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; function scrollTo(x,y){<br />
&nbsp; &nbsp; &nbsp; &nbsp; $(&quot;body&quot;).append('<span style="color: #009900;">&lt;<span style="color: #000000; font-weight: bold;">iframe</span> <span style="color: #000066;">id</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;scrollTop&quot;</span> <span style="color: #000066;">style</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;border:none;width:1px;height:1px;position:absolute;top:-10000px;left:-100px;&quot;</span> <span style="color: #000066;">src</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;http://static.ak.facebook.com/xd_receiver_v0.4.php?r=1#%7B%22id%22%3A0%2C%22sc%22%3Anull%2C%22sf%22%3A%22%22%2C%22sr%22%3A2%2C%22h%22%3A%22iframeOuterServer%22%2C%22sid%22%3A%220.957%22%2C%22t%22%3A0%7D%5B0%2C%22iframeInnerClient%22%2C%22scrollTo%22%2C%7B%22x%22%3A'+x+'%2C%22y%22%3A'+y+'%7D%2Cfalse%5D&quot;</span> <span style="color: #000066;">onload</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;$(\'#scrollTop\').remove();&quot;</span>&gt;&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">iframe</span>&gt;</span>');<br />
&nbsp; &nbsp; &nbsp; }<br />
&nbsp; &nbsp; <span style="color: #009900;">&lt;<span style="color: #66cc66;">/</span><span style="color: #000000; font-weight: bold;">script</span>&gt;</span></div></div>
<p>Same as before, place this snippet after the body tag and you&#8217;re done.</p>
<p>I don&#8217;t remember where I got these snippets. Just wanted to share them because they&#8217;re really useful, and because I usually forget them and have to rescue backups of older apps heheh</p>
<p>Hope it helps!</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2011/07/04/facebook-apps-auto-resize-and-scroll-to-top/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Set up a full development server for a Ruby on Rails project</title>
		<link>http://ivanhq.net/2010/09/08/set-up-a-full-development-server-for-a-ruby-on-rails-project/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=set-up-a-full-development-server-for-a-ruby-on-rails-project</link>
		<comments>http://ivanhq.net/2010/09/08/set-up-a-full-development-server-for-a-ruby-on-rails-project/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 13:19:03 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Debian]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=474</guid>
		<description><![CDATA[Those who know me also know that one thing I&#8217;m specially concerned about is the importance of writing good documentation on everything you do. Specially for technical projects. Maybe it is not important for coders or designers, but for a sysadmin I think it should be definilety mandatory. If you get cool things working together [...]]]></description>
			<content:encoded><![CDATA[<p>Those who know me also know that one thing I&#8217;m specially concerned about is the importance of writing good documentation on everything you do. Specially for technical projects. Maybe it is not important for coders or designers, but for a sysadmin I think it should be definilety mandatory. If you get cool things working together but you don&#8217;t write any documentation, you won&#8217;t be able to play that music again.</p>
<p>Also, I am working in Ruby on Rails development since about 2 years ago. One of the things I have to do usually is to set up servers for hosting projects. And sometimes I have to set up a server for project development and tracking. These are the steps you can follow to set up a Ruby on Rails based server for development tracking.</p>
<p><b>1. Get a server</b></p>
<p>There are plenty of choices around the internet, some of them come completelly installed and prepared for deploying your app. They usually work the same way traditional LAMP hostings used to do, but using ssh key authentication instead of FTP sessions&#8230; some of them have also  web based backend panels for deploying, migrating and managing your app gems. </p>
<p>I prefer to set up an empty GNU/Linux vanilla server, so that I can host everything I need, my way, no worries if PHP, Ruby or whatever. I can set up a relay mailserver, netfilter routing, traffic shaping, services for monitoring and differential backups that I can periodically rsync to my office local server. This is the way a sysadmin thinks, something that coders not always understand.</p>
<p>If you want to set up a development server I recomment you to take a look at most basic <a href="http://linode.com">Linode VPS</a>. Their control panel will let you run and destroy any Linux distro, setup and resize partitions, add failover addresses, disk space, processor and memory. And of course you&#8217;ll have full SSH root access. So I find it very useful and flexible for my needs.</p>
<p>Some considerations:</p>
<ul>
<li>You&#8217;ll have to <b>set up a DNS name for the server IP</b>, i.e: <b>http://devel.somedomain.net</b></li>
<li>You&#8217;ll need root access on the server. I&#8217;ll suppose you are working on a local computer, remotely logged via SSH to your server</li>
<li>I usually build my servers using Debian (<i>Lenny</i> for now), but a basic knowledge of any other distro package system will let you adapt my guide to your preferred system</li>
<li>I&#8217;ll suppose you&#8217;ve set up a specific environment for running your app on the development server (I usually call it <i>beta</i>)</li>
</ul>
<p><b>2. Install screen</b></p>
<p>You may partially lose your work if for any reason your local computer hangs during the process. So it&#8217;s recommendable to install and use screen for working on a detachable console terminal. This way, if your computer shuts down, you&#8217;ll be able to boot again, ssh into your server and recover your screen session.</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> <span style="color: #c20cb9; font-weight: bold;">screen</span></div></div>
<p>You&#8217;ll maybe want to set up your screen sessions to look nicer than withe on black, and give you some additional information of the remote system. I use a copy of the screenrc configuration file from my friend <a href="http://userlinux.net">r0sk</a>, it&#8217;s simple and nice and works sweet.</p>
<div class="codecolorer-container bash blackboard" 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;">wget</span> <span style="color: #660033;">-c</span> http:<span style="color: #000000; font-weight: bold;">//</span>ivanhq.net<span style="color: #000000; font-weight: bold;">/</span>stuff<span style="color: #000000; font-weight: bold;">/</span>_screenrc<br />
<span style="color: #c20cb9; font-weight: bold;">mv</span> _screenrc ~<span style="color: #000000; font-weight: bold;">/</span>.screenrc</div></div>
<p>Enter screen</p>
<div class="codecolorer-container bash blackboard" 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;">screen</span></div></div>
<p><b>3. Base system</b></p>
<p>You&#8217;ll need an unprivileged user to host your web apps. I usually create a <i>web</i> user</p>
<div class="codecolorer-container bash blackboard" 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;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<br />
groupadd service<br />
useradd <span style="color: #660033;">-d</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">bash</span> <span style="color: #660033;">-g</span> service web<br />
<span style="color: #c20cb9; font-weight: bold;">chown</span> <span style="color: #660033;">-R</span> web:service <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span><br />
<span style="color: #c20cb9; font-weight: bold;">passwd</span> web &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># type your preferred password here</span></div></div>
<p>Add <i>contrib</i> and <i>non-free</i> repositories to your Apt sources file (<b>vim /etc/apt/sources.list</b>)</p>
<div class="codecolorer-container bash blackboard" 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">deb http:<span style="color: #000000; font-weight: bold;">//</span>ftp.us.debian.org<span style="color: #000000; font-weight: bold;">/</span>debian lenny main contrib non-free<br />
deb-src http:<span style="color: #000000; font-weight: bold;">//</span>ftp.us.debian.org<span style="color: #000000; font-weight: bold;">/</span>debian lenny main contrib non-free</div></div>
<p>Update your sources and then your system</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get update</span><br />
<span style="color: #c20cb9; font-weight: bold;">apt-get upgrade</span></div></div>
<p>Edit your SSH server config file to disallow root login and enable SSH key authentication (<b>vim /etc/ssh/sshd_config</b>)</p>
<div class="codecolorer-container bash blackboard" 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: #666666; font-style: italic;"># change next line, swap &quot;yes&quot; for &quot;no&quot;</span><br />
PermitRootLogin no<br />
&nbsp;<br />
<span style="color: #666666; font-style: italic;"># uncomment next line</span><br />
AuthorizedKeysFile &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">%</span>h<span style="color: #000000; font-weight: bold;">/</span>.ssh<span style="color: #000000; font-weight: bold;">/</span>authorized_keys</div></div>
<p>Restart your SSH service</p>
<div class="codecolorer-container bash blackboard" 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: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>init.d<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">ssh</span> restart</div></div>
<p>Install build-essentials for compiling and installing the environment dependencies</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> build-essential</div></div>
<p>Install Postfix for using as MTA relay server, or MySQL Debian packages will install Exim (which I don&#8217;t really like)</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> postfix<br />
<br />
<span style="color: #666666; font-style: italic;"># select: internet site</span><br />
<span style="color: #666666; font-style: italic;"># MTA's outgoing domain name: somedomain.net</span></div></div>
<p><b>4. Backports</b></p>
<p>Because of some software versions being old and deprecated on the APT sources, and some other not being present, an alternative repository can be set up for installing newer versions. The backports repository.</p>
<div class="codecolorer-container bash blackboard" 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;">wget</span> <span style="color: #660033;">-O</span> - http:<span style="color: #000000; font-weight: bold;">//</span>backports.org<span style="color: #000000; font-weight: bold;">/</span>debian<span style="color: #000000; font-weight: bold;">/</span>archive.key <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">apt-key add</span> -</div></div>
<p>Edit your APT sources file (<b>vim /etc/apt/sources.list</b>)</p>
<div class="codecolorer-container bash blackboard" 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">deb http:<span style="color: #000000; font-weight: bold;">//</span>www.backports.org<span style="color: #000000; font-weight: bold;">/</span>debian lenny-backports main contrib non-free</div></div>
<p>Update your system again</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get update</span></div></div>
<p><b>5. MySQL</b></p>
<p>Install <b>mysql</b> service, and its ruby bindings package</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> mysql-server mysql-client libmysqlclient15-dev libmysql-ruby</div></div>
<p>Create a database for your project (<b>mysql -uroot -p</b>)</p>
<div class="codecolorer-container bash blackboard" 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">mysql<span style="color: #000000; font-weight: bold;">&gt;</span> CREATE DATABASE yourapp_beta;<br />
mysql<span style="color: #000000; font-weight: bold;">&gt;</span> GRANT ALL PRIVILEGES ON yourapp_beta.<span style="color: #000000; font-weight: bold;">*</span> TO yourapp_username<span style="color: #000000; font-weight: bold;">@</span>localhost IDENTIFIED BY <span style="color: #ff0000;">'your_superhacker_password123'</span>;</div></div>
<p><b>6. Ruby, Rubygems and Rails</b></p>
<p>Install the Ruby stuff, I prefer to use backports at this point to ensure latest versions.</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get</span> <span style="color: #660033;">-t</span> lenny-backports <span style="color: #c20cb9; font-weight: bold;">install</span> ruby1.8-dev ruby1.8 ri1.8 rdoc1.8 irb1.8 libreadline-ruby1.8 libruby1.8 libopenssl-ruby</div></div>
<p>Add unversioned links for the newly created binaries</p>
<div class="codecolorer-container bash blackboard" 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;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ruby1.8 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ruby<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ri1.8 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ri<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>rdoc1.8 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>rdoc<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>irb1.8 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>irb<br />
<span style="color: #c20cb9; font-weight: bold;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>gem <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>gem</div></div>
<p>Install Rubygems from source, so you can update it directly whenever you want. Otherwise the system will update it for you, only when new packages for your distro are available.</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>src<br />
<span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">-c</span> http:<span style="color: #000000; font-weight: bold;">//</span>production.cf.rubygems.org<span style="color: #000000; font-weight: bold;">/</span>rubygems<span style="color: #000000; font-weight: bold;">/</span>rubygems-1.3.7.tgz<br />
<span style="color: #c20cb9; font-weight: bold;">tar</span> zxvfp rubygems-1.3.7.tgz<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> rubygems-1.3.7<br />
ruby setup.rb</div></div>
<p>Link <i>gem</i> binary to an unversioned name</p>
<div class="codecolorer-container bash blackboard" 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;">ln</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>gem1.8 <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>gem</div></div>
<p>Update rubygems (not really needed, but just in case)</p>
<div class="codecolorer-container bash blackboard" 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">gem update<br />
gem update <span style="color: #660033;">--system</span></div></div>
<p>Install Rails</p>
<div class="codecolorer-container bash blackboard" 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">gem <span style="color: #c20cb9; font-weight: bold;">install</span> rails</div></div>
<p><b>7. Image processing</b></p>
<p>Youll surelly want a plugin for cropping and thumbnailing images, maybe <i>attachment_fu</i> or <i>paperclip</i>. They both can work with Imagemagick.</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> imagemagick</div></div>
<p><b>8. Apache</b></p>
<p>There are different web server layouts for hosting your application. Some people likes Nginx+Mongrel, some other prefer Apache+Passenger, others prefer Nginx+Passenger&#8230; I love Apache. Maybe because its syntax simplicity, its flexibility or maybe simply because as a sysadmin I&#8217;ve been working for years with it.</p>
<p>Install Apache</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> apache2.2-common apache2-mpm-prefork apache2-prefork-dev libssl-dev</div></div>
<p>Rename default virtualhost</p>
<div class="codecolorer-container bash blackboard" 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">a2dissite default<br />
<span style="color: #c20cb9; font-weight: bold;">mv</span> <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>sites-available<span style="color: #000000; font-weight: bold;">/</span>default <span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>sites-available<span style="color: #000000; font-weight: bold;">/</span>devel_somedomain_net</div></div>
<p>Edit that virtualhost (<b>vim /etc/apache2/sites-available/devel_somedomain_net</b>)and configure it with the minimum options to work. I&#8217;m adding a basic HTTP authentication so only people you give the password can see your project (it&#8217;s a development server heheh).</p>
<div class="codecolorer-container bash blackboard" 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: #000000; font-weight: bold;">&lt;</span>VirtualHost <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">80</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ServerName devel.somedomain.net<br />
&nbsp; &nbsp; &nbsp; &nbsp; RailsEnv beta<br />
&nbsp; &nbsp; &nbsp; &nbsp; DocumentRoot <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>devel.somedomain.net<span style="color: #000000; font-weight: bold;">/</span>current<span style="color: #000000; font-weight: bold;">/</span>public<br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; CustomLog <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>devel_somedomain_net<span style="color: #000000; font-weight: bold;">/</span>access.log combined<br />
&nbsp; &nbsp; &nbsp; &nbsp; ErrorLog <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>devel_somedomain_net<span style="color: #000000; font-weight: bold;">/</span>error.log<br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>Directory <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>devel_somedomain_net<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AuthType Basic<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AuthName <span style="color: #ff0000;">&quot;Members Only&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AuthUserFile <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>.htpasswd_devel_somedomain_net<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;</span>limit GET PUT POST<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; require valid-user<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>limit<span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">&lt;/</span>Directory<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<span style="color: #000000; font-weight: bold;">&lt;/</span>VirtualHost<span style="color: #000000; font-weight: bold;">&gt;</span></div></div>
<p>Enable your new virtualhost</p>
<div class="codecolorer-container bash blackboard" 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">a2ensite devel_somedomain_net</div></div>
<p>As the unprivileged user running the service, create the application directory and the HTTP Auth passwords file</p>
<div class="codecolorer-container bash blackboard" 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;">su</span> - web<br />
<span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>devel.somedomain.net<br />
&nbsp;<br />
htpasswd <span style="color: #660033;">-c</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>.htpasswd_devel_somedomain_net username1<br />
htpasswd <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>.htpasswd_devel_somedomain_net username2<br />
....<br />
<br />
<span style="color: #7a0874; font-weight: bold;">exit</span></div></div>
<p>Create the apache log directory for your app</p>
<div class="codecolorer-container bash blackboard" 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;">mkdir</span> <span style="color: #660033;">-p</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>devel_somedomain_net</div></div>
<p>Install Passenger</p>
<div class="codecolorer-container bash blackboard" 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">gem <span style="color: #c20cb9; font-weight: bold;">install</span> passenger<br />
passenger-install-apache2-module</div></div>
<p>Create a file for loading passenger module into Apache (<b>vim /etc/apache2/mods-available/passenger.load</b>). Be careful with versions on the names as they may have changed.</p>
<div class="codecolorer-container bash blackboard" 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">LoadModule passenger_module <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>passenger-2.2.15<span style="color: #000000; font-weight: bold;">/</span>ext<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>mod_passenger.so<br />
PassengerRoot <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>ruby<span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span><span style="color: #000000;">1.8</span><span style="color: #000000; font-weight: bold;">/</span>gems<span style="color: #000000; font-weight: bold;">/</span>passenger-2.2.15<br />
PassengerRuby <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>ruby1.8</div></div>
<p>Enable passenger module</p>
<div class="codecolorer-container bash blackboard" 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">a2enmod passenger</div></div>
<p>Change the user and group executing Apache service to match your unprivileged user (<b>vim /etc/apache2/envvars</b>)</p>
<div class="codecolorer-container bash blackboard" 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: #666666; font-style: italic;">#export APACHE_RUN_USER=www-data</span><br />
<span style="color: #666666; font-style: italic;">#export APACHE_RUN_GROUP=www-data</span><br />
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">APACHE_RUN_USER</span>=web<br />
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">APACHE_RUN_GROUP</span>=service</div></div>
<p>Restart Apache</p>
<div class="codecolorer-container bash blackboard" 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: #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 restart</div></div>
<p><b>9. Git and Gitosis</b></p>
<p>If you don&#8217;t want to pay a Github account and you don&#8217;t want your source to be visible to everyone, you&#8217;ll want to host your own Git server. There are different choices for that, but I like Gitosis because it&#8217;s simple and I can manage it from my command line, only editing a config file.</p>
<p>Install Git</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get</span> <span style="color: #660033;">-t</span> lenny-backports <span style="color: #c20cb9; font-weight: bold;">install</span> git-arch</div></div>
<p>Gitosis is written in Python, so you need to install python&#8217;s setup-tools in order to install Gitosis</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> python-setuptools</div></div>
<p>Clone and install Gitosis</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>src<br />
<span style="color: #c20cb9; font-weight: bold;">git clone</span> git:<span style="color: #000000; font-weight: bold;">//</span>eagain.net<span style="color: #000000; font-weight: bold;">/</span>gitosis.git<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> gitosis<br />
python setup.py <span style="color: #c20cb9; font-weight: bold;">install</span></div></div>
<p>Create a new unprivileged user for hosting Gitosis and its repositories. It does not need a password (so it can&#8217;t log in) but it needs a shell as all management occours using an SSH session.</p>
<div class="codecolorer-container bash blackboard" 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">adduser \<br />
<span style="color: #660033;">--system</span> \<br />
<span style="color: #660033;">--shell</span> <span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">sh</span> \<br />
<span style="color: #660033;">--gecos</span> <span style="color: #ff0000;">'git version control'</span> \<br />
<span style="color: #660033;">--group</span> \<br />
<span style="color: #660033;">--disabled-password</span> \<br />
<span style="color: #660033;">--home</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">git</span> \<br />
<span style="color: #c20cb9; font-weight: bold;">git</span><br />
&nbsp;<br />
usermod <span style="color: #660033;">-g</span> service <span style="color: #c20cb9; font-weight: bold;">git</span></div></div>
<p>Upload your ssh public key to the server, leave it in /tmp/ and call it <b>user@host.pub</b> being <i>user@host</i> the final string specified into the file itself (<i>ivan@mbp-local</i>, or something similar)</p>
<p>Initialize Gitosis using the SSH key you just uploaded, which will be the Gitosis admin</p>
<div class="codecolorer-container bash blackboard" 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;">su</span> - <span style="color: #c20cb9; font-weight: bold;">git</span><br />
gitosis-init <span style="color: #000000; font-weight: bold;">&lt;</span> <span style="color: #000000; font-weight: bold;">/</span>tmp<span style="color: #000000; font-weight: bold;">/</span>ivan\<span style="color: #000000; font-weight: bold;">@</span>ibelmonte-mbp.local.pub</div></div>
<p><b>In your local computer</b> clone the Gitosis repository so you can manage it from now on</p>
<div class="codecolorer-container bash blackboard" 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;">git clone</span> <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>devel.somedomain.net:gitosis-admin.git</div></div>
<p>Enter the </i>gitosis-admin</i> directory and check the contents. It has to show a filename called <i>gitosis.conf</i> and a directory called <i>keydir</i>.</p>
<p><b>10. Add a repository for your app</b></p>
<p>Edit the Gitosis config (<b>vim gitosis.conf</b>) and add a new group, formed with one user (or more, separated with spaces), and its repository</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">&#91;</span>group your_app_name<span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
members = user1<span style="color: #000000; font-weight: bold;">@</span>host1 user2<span style="color: #000000; font-weight: bold;">@</span>host2 ...<br />
writable = your_repo_name</div></div>
<p>Make sure to put user&#8217;s keyfiles into the <i>keydir</i> directory, following the previously mentioned format. Upload your changes.</p>
<div class="codecolorer-container bash blackboard" 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;">git add</span> .<br />
<span style="color: #c20cb9; font-weight: bold;">git commit</span> <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Added user2 to your_app group&quot;</span><br />
<span style="color: #c20cb9; font-weight: bold;">git push</span></div></div>
<p><b>In your local computer</b> you can now create an application and add its files to the repo</p>
<div class="codecolorer-container bash blackboard" 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">rails your_app<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> your_app<br />
<span style="color: #c20cb9; font-weight: bold;">git init</span><br />
<span style="color: #c20cb9; font-weight: bold;">git remote</span> add origin <span style="color: #c20cb9; font-weight: bold;">git</span><span style="color: #000000; font-weight: bold;">@</span>devel.somedomain.net:your_app.git<br />
<span style="color: #c20cb9; font-weight: bold;">git add</span> .<br />
<span style="color: #c20cb9; font-weight: bold;">git commit</span> <span style="color: #660033;">-a</span> <span style="color: #660033;">-m</span> <span style="color: #ff0000;">&quot;Initial import&quot;</span><br />
<span style="color: #c20cb9; font-weight: bold;">git push</span> origin master:refs<span style="color: #000000; font-weight: bold;">/</span>heads<span style="color: #000000; font-weight: bold;">/</span>master</div></div>
<p><b>11. Capistrano</b></p>
<p>You&#8217;ll want to deploy your software to your newly configured server. Capistrano is the best choice I know, since it creates versioned directories to let you roll back and forth, remotely run tasks on the hosted version of your app, place a custom &#8220;under maintenance&#8221; page, etc&#8230;</p>
<p>Install Capistrano</p>
<div class="codecolorer-container bash blackboard" 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">gem <span style="color: #c20cb9; font-weight: bold;">install</span> capistrano</div></div>
<p>Capify your application</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>path<span style="color: #000000; font-weight: bold;">/</span>to<span style="color: #000000; font-weight: bold;">/</span>your<span style="color: #000000; font-weight: bold;">/</span>app<br />
capify .</div></div>
<p>Create a recipe (<b>vim config/deploy.rb</b>)</p>
<div class="codecolorer-container ruby blackboard" 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:#008000; font-style:italic;"># set a target name, so you can also use it to deploy to a production server</span><br />
<br />
<span style="color:#008000; font-style:italic;"># set :targetname, 'www'</span><br />
set <span style="color:#ff3333; font-weight:bold;">:targetname</span>, <span style="color:#996600;">'devel'</span><br />
&nbsp;<br />
<span style="color:#9966CC; font-weight:bold;">if</span> targetname == <span style="color:#996600;">'devel'</span><br />
&nbsp; set <span style="color:#ff3333; font-weight:bold;">:rails_env</span>, <span style="color:#996600;">'beta'</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp;<br />
set <span style="color:#ff3333; font-weight:bold;">:application</span>, <span style="color:#996600;">&quot;#{targetname}.somedomain.net&quot;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:deploy_to</span>, <span style="color:#996600;">&quot;/home/web/sites/#{application}&quot;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:user</span>, <span style="color:#996600;">&quot;web&quot;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:runner</span>, <span style="color:#996600;">&quot;web&quot;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:repository</span>, <span style="color:#996600;">&quot;git@devel.somedomain.net:your_app.git&quot;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:deploy_via</span>, <span style="color:#ff3333; font-weight:bold;">:remote_cache</span><br />
set <span style="color:#ff3333; font-weight:bold;">:copy_exclude</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;.git&quot;</span>, <span style="color:#996600;">&quot;.gitignore&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
set <span style="color:#ff3333; font-weight:bold;">:scm</span>, <span style="color:#ff3333; font-weight:bold;">:git</span><br />
set <span style="color:#ff3333; font-weight:bold;">:use_sudo</span>, <span style="color:#0000FF; font-weight:bold;">false</span><br />
&nbsp;<br />
<span style="color:#008000; font-style:italic;"># Master branch of course. If not, change</span><br />
<span style="color:#008000; font-style:italic;">#</span><br />
<span style="color:#008000; font-style:italic;"># set :branch, master</span><br />
&nbsp;<br />
ssh_options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:forward_agent</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp;<br />
role <span style="color:#ff3333; font-weight:bold;">:app</span>, <span style="color:#996600;">&quot;#{targetname}.somedomain.net&quot;</span><br />
role <span style="color:#ff3333; font-weight:bold;">:web</span>, <span style="color:#996600;">&quot;#{targetname}.somedomain.net&quot;</span><br />
role <span style="color:#ff3333; font-weight:bold;">:db</span>, &nbsp;<span style="color:#996600;">&quot;#{targetname}.somedomain.net&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:primary</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp;<br />
namespace <span style="color:#ff3333; font-weight:bold;">:deploy</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; desc <span style="color:#996600;">&quot;Restarting passenger with restart.txt&quot;</span><br />
&nbsp; task <span style="color:#ff3333; font-weight:bold;">:restart</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;">:app</span>, <span style="color:#ff3333; font-weight:bold;">:except</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:no_release</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; run <span style="color:#996600;">&quot;touch #{current_path}/tmp/restart.txt&quot;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:start</span>, <span style="color:#ff3333; font-weight:bold;">:stop</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; desc <span style="color:#996600;">&quot;#{t} task is a no-op with mod_rails&quot;</span><br />
&nbsp; &nbsp; task t, <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;">:app</span> <span style="color:#9966CC; font-weight:bold;">do</span> ; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p><b>12. SSH keys</b></p>
<p>In order to deploy your app without typing any password, you&#8217;ll have to set up a SSH key authentication between you and the unprivileged user of the server (<i>web</i> user).</p>
<p>Copy the content of your local ssh keyfile (commonly ~/.ssh/<i>id_rsa.pub</i>) and paste at the end of <b>/home/web/.ssh/authorized_keys</b> on the server. You&#8217;ll want to repeat this process for each developer so they can also deploy without typing a password.</p>
<p>You&#8217;ll also need to generate a SSH key for your <i>web</i> user on the server, and add it as a member of the repo in gitosis. Otherwise you won&#8217;t be able to deploy your app, because the server won&#8217;t let itself access to the repo for fetching.</p>
<p><b>13. Redmine</b></p>
<p>Redmine is one of those powerful tools that make your life easier when working with other developers, designers, webmasters and CEO&#8217;s&#8230; it helps you to keep tracking of issues, bugs, timings, files and documents, wikis and it also lets you graphically browse your repositories. If you&#8217;ve never tested it, now it&#8217;s your time.</p>
<p><b>NOTE:</b> you&#8217;ll need to create a new entry on your DNS server. Set up a CNAME called <i>redmine</i> pointing to <i>devel.somedomain.net</i></p>
<p>Redmine needs mod_rewrite support on Apache</p>
<div class="codecolorer-container bash blackboard" 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">a2enmod rewrite</div></div>
<p>You&#8217;ll need subversion to checkout the source code of Redmine</p>
<div class="codecolorer-container bash blackboard" 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;">apt-get install</span> subversion</div></div>
<p>Su to your unprivileged user</p>
<div class="codecolorer-container bash blackboard" 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;">su</span> - web</div></div>
<p>Checkout the code</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">cd</span> sites<br />
<span style="color: #c20cb9; font-weight: bold;">svn co</span> http:<span style="color: #000000; font-weight: bold;">//</span>redmine.rubyforge.org<span style="color: #000000; font-weight: bold;">/</span>svn<span style="color: #000000; font-weight: bold;">/</span>tags<span style="color: #000000; font-weight: bold;">/</span>1.0.1<span style="color: #000000; font-weight: bold;">/</span> redmine.somedomain.net<br />
<span style="color: #7a0874; font-weight: bold;">cd</span> redmine.somedomain.net</div></div>
<p>Create a database for redmine (<b>mysql -uroot -p</b>)</p>
<div class="codecolorer-container bash blackboard" 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">mysql<span style="color: #000000; font-weight: bold;">&gt;</span> CREATE DATABASE redmine CHARACTER SET utf8;<br />
mysql<span style="color: #000000; font-weight: bold;">&gt;</span> GRANT ALL PRIVILEGES ON redmine.<span style="color: #000000; font-weight: bold;">*</span> TO redmine<span style="color: #000000; font-weight: bold;">@</span>localhost IDENTIFIED BY <span style="color: #ff0000;">'redmine123'</span>;</div></div>
<p>Edit Redmine&#8217;s database configuration file (<b>vim config/database.yml</b>)</p>
<div class="codecolorer-container ruby blackboard" 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">production:<br />
&nbsp; adapter: mysql<br />
&nbsp; database: redmine<br />
&nbsp; host: localhost<br />
&nbsp; username: redmine<br />
&nbsp; password: redmine123<br />
&nbsp; encoding: utf8<br />
&nbsp; socket: <span style="color:#006600; font-weight:bold;">/</span>var<span style="color:#006600; font-weight:bold;">/</span>run<span style="color:#006600; font-weight:bold;">/</span>mysqld<span style="color:#006600; font-weight:bold;">/</span>mysqld.<span style="color:#9900CC;">sock</span></div></div>
<p>Place a secret key for Redmine cookies on its environment file, inside the <i>Initializer</i> block (<b>vim config/environment.rb</b>)</p>
<div class="codecolorer-container ruby blackboard" 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;">session</span> = <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:key</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;_redmine_somedomain_com_session&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:secret</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;578359e95c3f2sj9enw10amkd81508ff&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span></div></div>
<p>Migrate the database</p>
<div class="codecolorer-container bash blackboard" 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;">env</span> <span style="color: #007800;">RAILS_ENV</span>=production rake db:migrate</div></div>
<p>Edit the SMTP configuration for Redmine to be able to send notification emails (<b>vim config/email.yml</b>)</p>
<div class="codecolorer-container ruby blackboard" 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">production:<br />
&nbsp; delivery_method: <span style="color:#ff3333; font-weight:bold;">:smtp</span><br />
&nbsp; smtp_settings:<br />
&nbsp; &nbsp; address: <span style="color:#996600;">&quot;smtp.somedomain.net&quot;</span><br />
&nbsp; &nbsp; port: <span style="color:#996600;">'25'</span><br />
&nbsp; &nbsp; domain: <span style="color:#996600;">&quot;somedomain.net&quot;</span><br />
&nbsp; &nbsp; authentication: <span style="color:#ff3333; font-weight:bold;">:login</span><br />
&nbsp; &nbsp; user_name: <span style="color:#996600;">&quot;your_username&quot;</span><br />
&nbsp; &nbsp; password: <span style="color:#996600;">&quot;your_password&quot;</span></div></div>
<p>If you want to relay over Gmail or your domain&#8217;s email is hosted on Google apps, you&#8217;ll need to install a tls authentication plugin</p>
<div class="codecolorer-container bash blackboard" 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">ruby script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> git:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>collectiveidea<span style="color: #000000; font-weight: bold;">/</span>action_mailer_optional_tls.git</div></div>
<p>Use this config for use with Gmail / Google apps</p>
<div class="codecolorer-container ruby blackboard" 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">production:<br />
&nbsp; delivery_method: <span style="color:#ff3333; font-weight:bold;">:smtp</span><br />
&nbsp; smtp_settings:<br />
&nbsp; &nbsp; tls: <span style="color:#0000FF; font-weight:bold;">true</span><br />
&nbsp; &nbsp; address: <span style="color:#996600;">&quot;smtp.gmail.com&quot;</span><br />
&nbsp; &nbsp; port: <span style="color:#996600;">'587'</span><br />
&nbsp; &nbsp; domain: <span style="color:#996600;">&quot;gmail.com&quot;</span> &nbsp; <span style="color:#008000; font-style:italic;"># use &quot;somedomain.net&quot; in case of Google Apps</span><br />
&nbsp; &nbsp; authentication: <span style="color:#ff3333; font-weight:bold;">:plain</span><br />
&nbsp; &nbsp; user_name: <span style="color:#996600;">&quot;your_username&quot;</span><br />
&nbsp; &nbsp; password: <span style="color:#996600;">&quot;your_password&quot;</span></div></div>
<p>Exit su, and become root again</p>
<div class="codecolorer-container bash blackboard" 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: #7a0874; font-weight: bold;">exit</span></div></div>
<p>Create a new Apache virtualhost (<b>vim /etc/apache2/sites-available/redmine_somedomain_net</b>)</p>
<div class="codecolorer-container bash blackboard" 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: #000000; font-weight: bold;">&lt;</span>VirtualHost <span style="color: #000000; font-weight: bold;">*</span>:<span style="color: #000000;">80</span><span style="color: #000000; font-weight: bold;">&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; ServerName redmine.somedomain.net<br />
&nbsp; &nbsp; &nbsp; &nbsp; RailsEnv production<br />
&nbsp; &nbsp; &nbsp; &nbsp; DocumentRoot <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>web<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span>redmine.somedomain.net<span style="color: #000000; font-weight: bold;">/</span>public<br />
&nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; CustomLog <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>redmine_somedomain_net<span style="color: #000000; font-weight: bold;">/</span>access.log combined<br />
&nbsp; &nbsp; &nbsp; &nbsp; ErrorLog <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>redmine_somedomain_net<span style="color: #000000; font-weight: bold;">/</span>error.log<br />
<span style="color: #000000; font-weight: bold;">&lt;/</span>VirtualHost<span style="color: #000000; font-weight: bold;">&gt;</span></div></div>
<p>Create an Apache log directory for redmine</p>
<div class="codecolorer-container bash blackboard" 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;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>log<span style="color: #000000; font-weight: bold;">/</span>apache2<span style="color: #000000; font-weight: bold;">/</span>redmine_somedomain_net<span style="color: #000000; font-weight: bold;">/</span></div></div>
<p>Enable your new virtualhost and restart Apache</p>
<div class="codecolorer-container bash blackboard" 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">a2ensite redmine.somedomain.net<br />
<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 restart</div></div>
<p><b>14. Start writing Ruby on Rails</b></p>
<p>Here comes the funny part. Enjoy! ;-)</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2010/09/08/set-up-a-full-development-server-for-a-ruby-on-rails-project/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tip: recover to_xml serialized latin chars</title>
		<link>http://ivanhq.net/2010/03/24/tip-recover-to_xml-serialized-latin-chars/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tip-recover-to_xml-serialized-latin-chars</link>
		<comments>http://ivanhq.net/2010/03/24/tip-recover-to_xml-serialized-latin-chars/#comments</comments>
		<pubDate>Wed, 24 Mar 2010 01:21:54 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=371</guid>
		<description><![CDATA[I am generating an XML file for dumping some data from one application to another. Yes, I know it&#8217;s nicer to build a RESTful API, but it&#8217;s for a very custom scenario and the shorter way is to write an XML based interface. So I simply export some contents: def show_some_content &#160; @content = Content.find&#40;:all&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>I am generating an XML file for dumping some data from one application to another. Yes, I know it&#8217;s nicer to build a RESTful API, but it&#8217;s for a very custom scenario and the shorter way is to write an XML based interface. So I simply export some contents:</p>
<div class="codecolorer-container ruby blackboard" 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;">def</span> show_some_content<br />
&nbsp; <span style="color:#0066ff; font-weight:bold;">@content</span> = Content.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<br />
&nbsp; respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span><span style="color:#CC0066; font-weight:bold;">format</span><span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></div>
<p>For my view:</p>
<div class="codecolorer-container ruby blackboard" 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:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@content</span>.<span style="color:#9900CC;">to_xml</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></div></div>
<p>The problem then is the resulting XML has not only escaped the HTML entities, but also latin characters (ie accents and tildes). After googling for an hour I&#8217;ve found some people blaming <b><i>to_xs</i></b> method (HTML escaped version of <b><i>to_s</i></b>, as its definition says) used for XML serialization.</p>
<p>Well, from the other app I need to parse this XML and get the original text. How the hell do I get latin chars unescaped again?</p>
<div class="codecolorer-container ruby blackboard" 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:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'cgi'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'iconv'</span><br />
<br />
encoded_text = <span style="color:#996600;">&quot;ram&amp;#243;n&quot;</span><br />
<span style="color:#008000; font-style:italic;"># some fucking encoded text coming from the XML</span><br />
<br />
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{Iconv.iconv('UTF-8', 'ISO-8859-1', CGI.unescapeHTML(encoded_text)).to_s}&quot;</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;ramón&quot;</span></div></div>
<p>That&#8217;s it :-)</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2010/03/24/tip-recover-to_xml-serialized-latin-chars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim code folding with ruby on rails</title>
		<link>http://ivanhq.net/2009/12/03/vim-code-folding-with-ruby-on-rails/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=vim-code-folding-with-ruby-on-rails</link>
		<comments>http://ivanhq.net/2009/12/03/vim-code-folding-with-ruby-on-rails/#comments</comments>
		<pubDate>Thu, 03 Dec 2009 12:33:12 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=334</guid>
		<description><![CDATA[I love vim for editing everything, no matter if it&#8217;s code, config files, a note or a to-do list. I use it with a lot of plugins and config snips for doing things I need as file browsing, file searching, window splitting, tabbing etc&#8230; and I was trying to find a good plugin for folding [...]]]></description>
			<content:encoded><![CDATA[<p>I love vim for editing everything, no matter if it&#8217;s code, config files, a note or a to-do list. I use it with a lot of plugins and config snips for doing things I need as file browsing, file searching, window splitting, tabbing etc&#8230; and I was trying to find a good plugin for folding code. After finding <a href="http://eigenclass.org/hiki/simplefold">Simplefold</a> and not being able to make it work, i found a <a href="http://stackoverflow.com/questions/849084/what-fold-should-i-use-in-vim">config snippet Stackoverflow</a> which works like a charm.</p>
<p>Once more I have to say: I&#8217;M LOVING <a href="http://vim.org">VIM</a>!!</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/12/03/vim-code-folding-with-ruby-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Massive emailer</title>
		<link>http://ivanhq.net/2009/11/20/massive-emailer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=massive-emailer</link>
		<comments>http://ivanhq.net/2009/11/20/massive-emailer/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 13:04:10 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=320</guid>
		<description><![CDATA[Yesterday I did a talk at Xing offices in Barcelona. It was about some tips on how to send emails massively from a Ruby on Rails application without being tagged as a spammer by Hotmail, Gmail or Yahoo. I&#8217;m not a dedicated expert on this, but I&#8217;ve been learning these things while developing last internet [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I did a talk at Xing offices in Barcelona. It was about some tips on how to send emails massively from a Ruby on Rails application without being tagged as a spammer by Hotmail, Gmail or Yahoo. I&#8217;m not a dedicated expert on this, but I&#8217;ve been learning these things while developing last internet site, and I thought it may be also interesting for other developers.<br />
Here are the slides (in english) of the presentation, formerly named  &#8220;<b>Massive emailing with Linux, Postfix and Ruby on Rails</b>&#8220;.</p>
<div style="width:490px;text-align:center" id="__ss_2544347"><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=massiveemailer-091120062912-phpapp02&#038;stripped_title=massive-emailing-with-linux-postfix-and-ruby-on-rails" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=massiveemailer-091120062912-phpapp02&#038;stripped_title=massive-emailing-with-linux-postfix-and-ruby-on-rails" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object></div>
<p><a href="http://www.ivanhq.net/stuff/massive_emailer.pdf">Here is the PDF</a> for downloading.</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/11/20/massive-emailer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rubyonrails.org en parking!</title>
		<link>http://ivanhq.net/2009/04/23/rubyonrailsorg-en-parking/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rubyonrailsorg-en-parking</link>
		<comments>http://ivanhq.net/2009/04/23/rubyonrailsorg-en-parking/#comments</comments>
		<pubDate>Thu, 23 Apr 2009 16:03:38 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=254</guid>
		<description><![CDATA[DIOS!! esta es de las cosas más fuertes que he visto en internet en los últimos años&#8230; El dominio de Ruby On Rails (rubyonrails.org) está en parking!! He mirado el registro del whois, y veo que el dominio ha caducado. Desde hoy mismo (23 de Abril 2009, día de Sant Jordi) pertenece a unos registradores [...]]]></description>
			<content:encoded><![CDATA[<p>DIOS!! esta es de las cosas más fuertes que he visto en internet en los últimos años&#8230; El dominio de <b>Ruby On Rails</b> (<a href="http://rubyonrails.org">rubyonrails.org</a>) está en parking!!</p>
<p>He mirado el registro del whois, y veo que el dominio ha caducado. Desde hoy mismo (23 de Abril 2009, día de Sant Jordi) pertenece a unos registradores masivos, de estos que te secuestran el dominio y luego te piden $15.000 por el.<br />
Y desde luego la culpa no es de los bulk registers, sino del propietario anterior del dominio. Yo siempre me preocupo de renovar mis dominios antes de que caduquen.<br />
Y es que en realidad el hecho de que se lo hayan quitado significa, no sólo que no se ha preocupado de renovarlo, sino que también se le ha pasado el periodo de redención (1 o 2 semanas, ahora no estoy seguro).</p>
<p>Bueno ahora la gran pregunta es dónde encontrar la documentación de la API, algo que uso a diario, y que ahora desde <a href="http://www.gotapi.com">Gotapi</a> no está disponible.</p>
<p>Qué es lo que ha pasado??? y ahora que????</p>
<p><b>EDIT:</b> son las 20:31 y ya está funcionando again. No sé qué es lo que ha pasado, pero en 1 minuto se me ha venido el mundo encima. Se da uno cuenta de lo frágiles que somos, y lo delgada que es la cuerda sobre la que caminamos&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/04/23/rubyonrailsorg-en-parking/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remote pair programming</title>
		<link>http://ivanhq.net/2009/03/24/remote-pair-programming/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=remote-pair-programming</link>
		<comments>http://ivanhq.net/2009/03/24/remote-pair-programming/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 01:53:31 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=221</guid>
		<description><![CDATA[Pair programming es una técnica en la que dos programadores trabajan con una misma consola, sobre el mismo código. Normalmente uno hace la función de driver y el otro la de observer. El objetivo es evidente: crear un mejor código, a la vez que conseguir que ambos programadores lo conozcan con el mismo nivel de [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://en.wikipedia.org/wiki/Pair_programming">Pair programming</a> es una técnica en la que dos programadores trabajan con una misma consola, sobre el mismo código. Normalmente uno hace la función de <i>driver</i> y el otro la de <i>observer</i>. El objetivo es evidente: crear un mejor código, a la vez que conseguir que ambos programadores lo conozcan con el mismo nivel de profundidad.</p>
<p>Hoy tenía un problema con el proyecto en el que estoy trabajando, y pedí a Mauro que me echase un cable a ver si entre los dos conseguíamos solucionarlo. Él estaba en su casa, y yo en la mía. Los ingredientes para cocinar un pair programming <b>realmente fluído</b> en remoto:</p>
<ul>
<li><b>Port forwarding:</b> un puerto para el acceso remoto por <b>SSH</b> y otro para el acceso al <b>servidor de aplicaciones</b> (acceso web)</li>
<li><b>screen:</b> Usando una versión ligeramente modificada del <a href="http://www.userlinux.net/1470_archivo_screenrc">screenrc de r0sk</a>. Usamos tres consolas: <b>[0]</b> log del servidor, <b>[1]</b> vim con el código, <b>[2]</b> una bash para hacer accesos de mysql u otras cosas que necesitemos</li>
<li><b>vim:</b> con los controles mapeados para trabajar con tabs, y el plugin de FuzzyFinderTextMate para buscar y abrir archivos&#8230; así se puede hacer todo en una sola consola</li>
<li><b>Skype:</b> Para hablar todo el rato durante la sesión de programación</li>
</ul>
<p>Los programadores <i>maceros</i> que usan TextMate suelen hacer el pair programming usando VNC, pero aunque no lo he probado pongo las dos manos en el fuego a que tiene que ser una cagada. La pareja <b>screen+vim</b> es brutal por lo lightweight y lo flexible, y consume muy poquito ancho de banda con lo que la comunicación del conjunto (ssh + skype) es perfecta.</p>
<p>La experiencia ha sido GENIAL, y hemos resuelto el problema en aproximadamente 1 hora. Es como trabajar en <a href="http://en.wikipedia.org/wiki/Pair_programming">pair programming</a> en local, tocando el mismo código y comentando todo el rato. Ha sido una pasada, y lo recomiendo a todos los programadores que trabajen separados físicamente del resto del equipo.</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/03/24/remote-pair-programming/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Remove email confirmation on restful_authentication</title>
		<link>http://ivanhq.net/2009/03/17/remove-email-confirmation-on-restful_authentication/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=remove-email-confirmation-on-restful_authentication</link>
		<comments>http://ivanhq.net/2009/03/17/remove-email-confirmation-on-restful_authentication/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 17:56:19 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://ivanhq.net/?p=215</guid>
		<description><![CDATA[SPANISH: Al considerar este artículo de interés común y dado que no he encontrado la explicación en ningún otro sitio, voy a redactarlo en inglés por si puede servir a alguien en un futuro. Si hay algo que no se entienda bien, no dudéis preguntármelo. I&#8217;m working on an online app about auctions. A lot [...]]]></description>
			<content:encoded><![CDATA[<p><b>SPANISH:</b> Al considerar este artículo de interés común y dado que no he encontrado la explicación en ningún otro sitio, voy a redactarlo en inglés por si puede servir a alguien en un futuro. Si hay algo que no se entienda bien, no dudéis <a href="mailto:ivan (at) ivanhq.net">preguntármelo</a>.</p>
<p>I&#8217;m working on an online app about auctions. A lot of the users coming to register don&#8217;t complete the email confirmation process, although I advise it in a red huge font at the login form. Most of the time I&#8217;m getting emils of users saying they registered but can&#8217;t login. When I look into the database, they didn&#8217;t activate their accounts.</p>
<p>Well, finally our CEO&#8217;s decided to remove the activation process. And this is when I&#8217;ve been googling for hours without luck, nobody explains the way to do it. Well no problem, it hasn&#8217;t been difficult at all. This is the way: a user is active if its activation_code in the database is Null.</p>
<ul>
<li>Edit <b>models/user.rb</b> and remove this filter
<pre>
before_create :make_activation_code
</pre>
</li>
<li>In the same <b>models/user.rb</b> file, remove the <b>activate</b> method (we&#8217;re not activating any more user)</li>
<li>In the same <b>models/user.rb</b> file, remove the <b>make_activation_code</b> method (it&#8217;s almost at the end of the file).</li>
</li>
<li>Now edit <b>controllers/users_controller.rb</b>,  remove completelly the <b>activate</b> method</li>
<li>In the same <b>controller/users_controller.rb</b> file, in the <b>create</b> mehod, set the <i>activated_at</i> time before saving the user
<pre>
@user = User.new(params[:user])
@user.activated_at = Time.now.utc  # <--- add this line
    if @user.save
    [...]
</pre>
</li>
<li>Edit <b>models/user_mailer.rb</b> and completelly remove the <b>activation</b> method</li>
<li>Remove the file <b>views/user_mailer/activation.html.rb</b></li>
<li>Edit the file <b>views/user_mailer/signup_notification.html.erb</b> and set the message as you like (variables are coming from <b>models/user_mailer.rb</b>)</li>
<li>Restart your app and test</li>
</ul>
<p>I'm sure there are better ways, and I'm not the best coder in the world, but this way works for me. Maybe it will help someone one day...</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/03/17/remove-email-confirmation-on-restful_authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Adjudicado!</title>
		<link>http://ivanhq.net/2009/01/30/adjudicado/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=adjudicado</link>
		<comments>http://ivanhq.net/2009/01/30/adjudicado/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 19:51:26 +0000</pubDate>
		<dc:creator>ivan</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[proyectos]]></category>

		<guid isPermaLink="false">http://ivanhq.net/2009/01/30/adjudicado/</guid>
		<description><![CDATA[Y por fin vio la luz&#8230;. Desde la vuelta de vacaciones de verano he blogeado menos, pero los que me conocen bien saben que he estado trabajando en el desarrollo de un software en Ruby on Rails. Llevo desarrollando este proyecto desde septiembre de 2008, y aunque el grueso se desarrolló antes de fin de [...]]]></description>
			<content:encoded><![CDATA[<p>Y por fin vio la luz&#8230;.<br />
Desde la vuelta de vacaciones de verano he <i>blogeado</i> menos, pero los que me conocen bien saben que he estado trabajando en el desarrollo de un software en Ruby on Rails. Llevo desarrollando este proyecto desde septiembre de 2008, y aunque el grueso se desarrolló antes de fin de año, no fue hasta la semana pasada que se produjo el lanzamiento oficial del site.</p>
<p>Se trata de <a href="http://www.subastasde.com">Subastasde</a>, un site dedicado a ofrecer información (tracking en realidad) de pisos y casas en subasta procedentes de embargos judiciales. Algunos ejemplos de lo que se puede encontrar:</p>
<ul>
<li><a href="http://www.subastasde.com/pisos">Subastas pisos</a></li>
<li><a href="http://www.subastasde.com/subastas/pisos/en/barcelona/8">Subastas de pisos en Barcelona</a></li>
<li><a href="http://www.subastasde.com/subastas/pisos/en/madrid/28">Subastas de pisos en Madrid</a></li>
<li>Y muuuuchos más pisos, apartamentos y casas que provienen de subastas y embargos judiciales (que de esto va la cosa)</li>
</ul>
<p>El site no ofrece la posibilidad de pujar online, sino que se enfoca a un público profesional (<i>subasteros</i> básicamente), al que ofrece el seguimiento completo de los inmuebles que salen a subasta procedentes de los bancos. Después de la subasta si nadie lo ha comprado, el inmueble queda en estado de cesión durante un plazo corto de tiempo, que al expirar queda adjudicado a la entidad financiera. Entonces el banco tiene que venderlo a través de un API al modo de las inmobiliarias habituales.</p>
<p>En realidad no pretendo explicar aquí todo el detalle del proceso legal que sufren estos inmuebles. Lo que me interesa comentar es que este proyecto me ha dado la oportunidad de trabajar con una tecnología que era completamente nueva para mí.</p>
<p>Estoy orgulloso de poder decir que TODO el site es obra mía. Evidentemente he programado lo que los CEO&#8217;s me pedían, las ideas no han sido mías. Pero sí he programado toda la aplicación desde 0. He montado las bases de datos, he desarrollado los modelos y sus relaciones, los controladores, las vistas (compatibles IE6 y FFox a base de ostias), he aprendido Ajax (prototype y scriptaculous), javascript, he montado los servidores de desarrollo y de producción, con servicios que hasta ahora no había tocado&#8230; llevo un mes peleándome con los XML y otras técnicas SEO (I hate SEO!!), he aprendido <a href="http://subversion.tigris.org">Subversion</a> y finalmente he migrado a <a href="http://www.git-scm.com">Git</a>. He tenido mi primer contacto con un sistema de tracking (usamos <a href="http://www.redmine.org">redmine</a>)&#8230; y en definitiva puedo decir que mi vida como sysadmin poco a poco ha dado un giro radical desde hace un tiempo, una especie de metamorfosis o <i>digievolución</i>, para convertirme en coder de rails.<br />
A todo esto, no puedo dejar de agradecer enormemente a mi amigo Mauro el tiempo y la paciencia que ha dedicado a ayudarme, cada vez que yo no me aclaraba con las API&#8217;s, cuando no tenía claro como debía hacer alguna cosa, o simplemente cuando caía en un agujero y no sabía como salir adelante. Gracias mussol :-)</p>
<p>Y en general todo esto me ha dado una ilusión nueva, me recuerda a mis inicios como administrador de sistemas, empapándome de documentación nueva cada día y peleándome con cada cosa que aprendía. Vuelvo a pasar las noches casi sin dormir, y siento que he recuperado la ilusión en un reto nuevo. Vuelvo a comprar libros, a leer listas de correo, a preocuparme por las versiones&#8230;<br />
Y sé que hay muchísimos programadores mejores que yo, pero de eso se trata no? al fin y al cabo lo mismo pasa en sistemas.</p>
<p>Bien, así que a partir de ahora supongo que postearé más cosas relacionadas con Rails que con sistemas, y supongo que también iré informando de la evolución del proyecto, que dicho sea de paso tiene muy muy buena pinta.<br />
Y ya sabéis, si queréis compraros un piso a la mitad de su precio de tasación, pasaos por <a href="http://www.subastasde.com">Subastasde</a>, porque cada día se incorporan nuevos inmuebles y algunos son verdaderos chollos.</p>
<p>Adjudicado! :-D</p>
]]></content:encoded>
			<wfw:commentRss>http://ivanhq.net/2009/01/30/adjudicado/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

