<?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 Kuznetsov &#187; Web/Tech</title>
	<atom:link href="http://www.ivankuznetsov.com/category/webtech/feed" rel="self" type="application/rss+xml" />
	<link>http://www.ivankuznetsov.com</link>
	<description>Entrepreneur, Ruby on Rails and Ubuntu fanatic, consultant</description>
	<lastBuildDate>Fri, 01 Jul 2011 22:03:56 +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>Notes from Gothenburg &#8211; Nordic Ruby 2011 conference</title>
		<link>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html#comments</comments>
		<pubDate>Tue, 21 Jun 2011 22:00:52 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=334</guid>
		<description><![CDATA[Here are my notes from Nordic Ruby conference in Göteborg, Sweden. I&#8217;d like to say big thanks to the organisers of the conference (especially CJ @cjkihlbom) &#8211; everything went really smooth, even though there&#8217;s been 150 people attending this year compared to 90 last year. Some points that I&#8217;d really like to highlight are: a [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/nordicruby.png"><img class="alignleft size-full wp-image-335" title="nordicruby" src="http://www.ivankuznetsov.com/wp-content/uploads/nordicruby.png" alt="" width="254" height="135" /></a>Here are my notes from <a href="http://nordicruby.org/" target="_blank">Nordic Ruby</a> conference in Göteborg, Sweden.</p>
<p>I&#8217;d like to say big thanks to the organisers of the conference (especially CJ <a href="https://twitter.com/#%21/cjkihlbom" target="_blank">@cjkihlbom</a>) &#8211; everything went really smooth, even though there&#8217;s been 150 people attending this year compared to 90 last year.<br />
Some points that I&#8217;d really like to highlight are:</p>
<ul>
<li>a lot of time to meet people and discuss: 30 minutes talks followed by  30 minutes breaks, no q&amp;a &#8211; those who had questions had an  opportunity to talk to the speakers during the breaks</li>
<li>venue was  great (of course, the boat <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  &#8211; there was enough space for everyone to  move around, but at the same time it was compact enough not to get lost also everyone had an opportunity to have lunch and dinner together</li>
<li>&#8220;job board&#8221; a huge white board where anyone can post information about  open positions in their companies &#8211; it got filled withing firts few  hours &#8211; job market is really hot</li>
<li>lightning talks that any participant can give &#8211; 5 minute talks in the end of the day &#8211; it was really great</li>
<li>real coffee <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  espresso, latte, cappuccino, americano &#8211; you name it &#8211; professional baristas were at your service</li>
<li><a href="http://runconfapp.com/races/226e14f45b6303b98e48bab49af60683" target="_blank">5K Nordic Ruby run</a> organised on the second day&#8217;s morning</li>
</ul>
<h2><span id="more-334"></span>Day 0</h2>
<p>The conference started with a party on <a href="http://en.wikipedia.org/wiki/G%C3%B6theborg_%28ship%29" target="_blank">Göthenborg ship</a>. It was a great way to get to know the speakers and participants in an informal setting.</p>
<h2>Day 1</h2>
<p><strong>&#8220;GitHub Flavored Ruby&#8221; was by Tom Preston-Werner (@mojombo) from GitHub.</strong></p>
<p>Tom had a hard task of waking up the auidence after yesterday&#8217;s pre-conference party, and he succeeded in this task. Tom explained what is a <a href="http://tom.preston-werner.com/2010/08/23/readme-driven-development.html" target="_blank">README driven development</a> that he and some of his colleagues in GitHub are using &#8211; a golden mean between waterfall and cowboy coding.<br />
Start a new project with writing a README file, where basic design principles and conventions will be described, and don&#8217;t forget to update it as the architecture changes.</p>
<p>Another interesting topic was <a href="http://tomdoc.org/" target="_blank">TomDoc</a> &#8211; code level documentation &#8211; a better alternative than RDoc/Yard, designed for hackers/humans, not for machines to read.</p>
<p>Modularisation was yet another subject &#8211; Tom explained how at GitHub they try to split the code into independent modules to reduce complexity of the system.<br />
Grit is a good example of that &#8211; a module for Ruby-Git interaction was written even before the rails code for GitHub.</p>
<p>Other examples of modles created in GitHub (and open-sourced) are: resque, jekyll, proxymachine and chimney, albino, gollum, bart, camo, failbot, giraffe, nodeload (in node.js), ernie (in erlang), stratocaster (for event feed), ghromosome (which is apparently not used anymore, but worth mentioning just because of the fun name).</p>
<p>And naturally for versioning of the components Tom proposes to use <a href="http://semver.org/" target="_blank">Semantic versioning</a>.</p>
<p>A few notes from the after-talk discussion with Tom and others:<br />
- Github uses git powered deploys &#8211; instead of copying the new release from git and then changing symlink to current release, they use single directory and do direct git updates &#8211; rollbacks are also easy to do using git fucntionality<br />
- it&#8217;s possible to deploy Github from Campfire by giving deploy command to a robot<br />
- to avoid downtime &#8211; build_cache is executed on a local machine before deploy and pushed to the servers during deploy<br />
- GitHub is still running on Rails 2.3, Tom&#8217;s estimate for migration to Rails 3 is ~2 weeks of &#8220;stop commits and migrate&#8221; (the estimate seems to be pretty consistent &#8211; I&#8217;ve been talking to several people about it)<br />
- experience from a fairly large web-app developers: MySQL to Postgres migration took 3 weeks</p>
<p><strong>&#8220;API Design Matters&#8221; was by Anthony Eden (@aeden) from DNSimple</strong></p>
<p>Central points from Anthony&#8217;s presentation:<br />
- APIs outlive their implementation (&#8220;Think about the children&#8221; when designing APIs <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
- Design APIs so that they are easy to extend<br />
- 5 Cs: consistent, clear, convenient, concise and complete<br />
- The best API is no API<br />
- If you&#8217;re a software developer &#8211; you are and API designer<br />
- And use semantic versioning that Tom was talking about</p>
<p>Reading recommendations:<br />
- Jasmine Blanchette &#8220;<a href="http://chaos.troll.no/~shausman/api-design/api-design.pdf" target="_blank">The little manual of API design</a>&#8221;<br />
- Joshua Bloch &#8220;<a href="http://www.youtube.com/watch?v=aAb7hSCtvGw, " target="_blank">How to design a good API and why it matters</a>&#8221;</p>
<p><strong>&#8220;Bridging the gap &#8211; Using JavaScript in Rails to write DRY rich client applications&#8221; by Thorben Schröder (@walski), KOPFMaschine</strong></p>
<p>An interesting talk about using Java Script from Ruby code and the other way around.<br />
Implementing validations on the client side reduces amount of round-trips and speeds up user interaction, but since smart people can hack JavaScript and bypass client-side validations, also server side validations are necessary. To avoid writing validations twice use The Ruby Racer,  CommonJS and CommonJS models to DRY your code and write validations only once and use them from both Ruby and JS code. Pretty smart, huh?</p>
<p><strong>&#8220;Limited Red Society&#8221; by Joseph Wilk (@josephwilk)</strong></p>
<p>Slides: <a href="http://www.slideshare.net/josephwilk/the-limited-red-society-8367200" target="_blank">http://www.slideshare.net/josephwilk/the-limited-red-society-8367200</a></p>
<p>Kanban is limiting number of tasks the team has in progress at any given moment. Joseph described in his talk how to apply this methodology to testing.</p>
<p>It&#8217;s important to have metrics for your testing and it&#8217;s important to visualize them. How much time do you spend in &#8220;red&#8221; when your tests are failing, which modules in your code are changed most often, are they the same that usually fail tests, are there any oscillating test cases that pass then fail then pass again?</p>
<p>One thing to be noted &#8211; some metrics have limited lifespan &#8211; measure what you&#8217;re interested in and then throw them away.</p>
<p>Reading recommendations:<br />
&#8220;<a href="http://www.amazon.co.uk/Refactoring-Ruby-William-C-Wake/dp/0321545044" target="_blank">Refactoring in Ruby</a>&#8221;<br />
&#8220;<a href="http://www.amazon.co.uk/Refactoring-Ruby-Addison-Wesley-Professional/dp/0321603508" target="_blank">Refactoring. Ruby Edition</a>&#8221; Kent Beck</p>
<p><strong>&#8220;</strong><strong>Must It Always Be About Sex?</strong><strong>&#8221; by Joshua Wehner (@jaw6)</strong></p>
<p>Links from the talk: <a href="http://pinboard.in/u:jaw6/t:nr2011/" target="_blank">http://pinboard.in/u:jaw6/t:nr2011/</a></p>
<p>Minorities and women are under-represented in our community. Black man is more likely to be hit by lightning than become a computer science professor.<br />
75% of women engineers leave profession because they are not socially accepted in the working culture. In the beginning of computer era programming was mostly a job for women.<br />
Do you think that your application is mobile friendly if you have iPhone optimised version? Think again &#8211; the most popular phone with a web browser is Nokia 1100 &#8211; more than 250 million phones sold to date,<br />
and that kind of devices are the only way how most people in Africa or India access the Internet.</p>
<p>What do we need to do to change current situation?</p>
<p>Just today I came across an article on the same subject: <a href="http://www.blackweb20.com/2011/06/10/two-11-year-old-entrepreneurs-learned-the-hard-way-what-it%E2%80%99s-like-to-be-a-minority-in-tech-during-startup-weekend/" target="_blank">Two 11-year-old entrepreneurs learned the hard way what it’s like to be a minority in tech during Startup Weekend</a></p>
<p><strong>&#8220;Infinite data &#8211; finite solutions&#8221; by Randall Thomas (@daksis) from Engine Yard</strong></p>
<p>Quick dive into Bayesian statistics. That is the technology that helps  to filter out spam from your inbox: &#8220;Keeps spam at Bayes&#8221; <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Bayes + DAG (Directed Acyclic Graph) = BBN (Bayesian Belief Network)</p>
<p>Probably the most scientific talk of the conference and two great demos: reconstruction of Bach&#8217;s first invention using BBN (amazing stuff) and analysing whiskey properties</p>
<p>Book to read: &#8220;<a href="http://fisher.stat.wmich.edu/joe/Stat666/book/book.pdf" target="_blank">Robust Nonparametric Statistical Methods</a>&#8221;<br />
Site to check: <a href="http://yudkowsky.net/rational/bayes" target="_blank">Eliezer Yudkowsky</a><br />
Tool to check: <a href="http://www.cs.waikato.ac.nz/ml/weka/" target="_blank">Weka</a> &#8211; analysis tool &#8211; live example how to analyze properites of whiskey.</p>
<p>A great collection of links on Bayesian Networks:  <a href="https://gist.github.com/1031597">https://gist.github.com/1031597</a></p>
<p><strong>&#8220;Taking Back Education&#8221; by Joe O&#8217;Brien (@objo)<br />
</strong></p>
<p>Education. We are in the top 5 to 2% of the developers by just being here &#8211; attending the conference.<br />
Why education system sucks? There&#8217;s a clear need for apprenticeship institute.</p>
<p>Harward Business Review research indicated that team IQ depends on diversity, not on IQ of individual members.<br />
Adding a women to the team cnsistently improves team performance (good reference for Diversity problems talk by Joshua)</p>
<p><strong>In the end of the first day there was a series of &#8220;lightning talks&#8221;.</strong></p>
<p>* Anthony Eden (@aeden) proposed to use DNS protocol for resolving dependencies. Definitely idea worth <a href="https://gist.github.com/1031494" target="_blank">studying</a>.<br />
* Twitter will be native on all iOS devices &#8211; think about it, and what do you want to do with it.<br />
* Stephen Sykes &#8211; obfuscated code for fun and ruby quiz &#8211; really, really fun &#8211; see the slides here: <a href="http://www.stephensykes.com/obfu_lightening.pdf" target="_blank">http://www.stephensykes.com/obfu_lightening.pdf</a><br />
* Emily Bach (backconsulting.com) shared her experiences in teaching TDD<br />
* Theo from Burt talked about his experiences and lessons learned from scaling:<br />
- build two of everything from the start &#8211; will help with horizontal scaling later<br />
- fail fast (Göthenburg ship made it to China and back to Sweden and sank a hundred meters from the home harbour, Vaasa is a lot better example &#8211; it sank right after it was deployed <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
- queues<br />
* Tom from GitHub talked about Hubot &#8211; a Campfire robot they wrote in node.js and keep developing just for fun &#8211; absolutely amazing stuff, every team should do that<br />
* David from Streamio (one of the sponsors of Nordic Ruby) did a &#8220;shameless self-promotion&#8221; of his company<br />
* Alex who has been doing a great job filming the conference talked about making a movie &#8211; what it takes<br />
* Antony Sastre &#8211; talked about photography &#8211; really inspiring, Antony was a web developer, then left the field and was doing photography for living for two years, now came back to web development<br />
* Nikolai (@nikolayb) Is this a bad idea? Deploying always to production on a site with millions of page views per day, one branch always &#8211; test code on a live service? Somehow it works&#8230;<br />
* Paul Wilson (@paulanthonywils) talked about Agile Delivery Network &#8211; doing better government IT, and here&#8217;s a bunch of links from his talk: https://gist.github.com/1035392<br />
* Paul Campbell (@paulk) talked about whenever.js and made it public on GitHub in the end of his talk http://whatever-js.heroku.com/#1, https://github.com/paulca/whenever.js</p>
<p>Day one ended with a BBQ dinner at the River Cafe.</p>
<h2>Day 2</h2>
<p>Paul Campbell who ended Day 1 with his lightning talk also started Day 2 with a autobiographical talk &#8220;In search of me fein&#8221; (myself in Irish).</p>
<p>7 days in my life, zombie movies and finding inspiration<br />
Technologist, developers, live in a bubble &#8211; we have no problems finding jobs, we can travel, we can choose where we live and work. It&#8217;s not like that outsie of our industry.</p>
<p><strong>&#8220;Actors on stage&#8221; by Elise Huard (@elise_huard)</strong></p>
<p>Slides: <a href="http://www.slideshare.net/ehuard/ruby-hollywood-nordic" target="_blank">http://www.slideshare.net/ehuard/ruby-hollywood-nordic</a></p>
<p>We have multiple cores in our processors now &#8211; how do we benefit from it?<br />
MRI is the only Ruby where parallel threads are executed time-scliced in one real thread.</p>
<p><a href="http://www.unlimitednovelty.com/2011/05/introducing-celluloid-concurrent-object.html" target="_blank">Cellucloid</a> &#8211; a concurrent object framework for Ruby.</p>
<p>Languages that implement actors: Erlang, Scala (Actors are in standard library), Closure (Actors called Agents)</p>
<p>Mats hates threads <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
Should there still be a better cuncurrency primitives in MRI? shall we create a branch of Ruby to implement it?</p>
<p><strong>&#8220;Beyond Ruby&#8221; by Jakob Mattson from Burt (@jakobmattsson)<br />
</strong></p>
<p>Slides: <a href="http://jakobmattsson.tumblr.com/post/6664704401/beyond-ruby" target="_blank">http://jakobmattsson.tumblr.com/post/6664704401/beyond-ruby</a></p>
<p>Bold statement: Ruby is not a dynamic language. Not everyting in Ruby is an object, despite what many books claim.<br />
E.g. dot (.) or &#8220;or&#8221; (||) operators cannot be redefined. Or operator doesn&#8217;t evaluate second argument if the first one is true.<br />
Ruby is not as moldable as it could be.<br />
It would be cool to implement calling by name &#8211; passing expression along with the context to the callee and letting it decide whether to evaluate it or not.<br />
<a href="http://www.iolanguage.com/" target="_blank"> Io language</a> is probably 80% there. A new language needs to be invented. And coding it would not be that difficult &#8211; because if it is<br />
truly dynamic, then most of it can be implemented in itself.</p>
<p><strong>&#8220;Fewer constraints&#8221; by Ryan Smith (@ryandotsmith) from Heroku</strong></p>
<p>Slides: <a href="http://dl.dropbox.com/u/1579953/concurrency_deck_with_notes.pdf" target="_blank">http://dl.dropbox.com/u/1579953/concurrency_deck_with_notes.pdf</a></p>
<p>Continuing the theme that Elise started this morning. How to improve performance of your application by parallelizing.<br />
Amdahl&#8217;s law &#8211; adding processors gives only marginal speed-up. &#8220;Even though we have 10 workers<br />
available to us, we are only seeing a speedup factor of 5.2, with 20 workers it get only to 6.9&#8243;.</p>
<p>Real life example &#8211; improving queue performance. Using Fuzzy FIFO instead of traditional queues FIFO implementation.<br />
Example with using spinlock in PostgreSQL to implement it. See queue_classic on github.</p>
<p><strong>&#8220;Mountain Dew and My Trail of Tears&#8221; by Aaron Patterson (@tenderlove) from AT&amp;T Interactive</strong></p>
<p>Aaron discussed in depth how to work with legacy code.</p>
<p>- use &#8220;ruby -w&#8221; to see the warnings in your code, warnings can be used by developers to inform about upcoming deprecations<br />
- Liskov substitution principle (LSP)<br />
- Single responsibility principple<br />
- Method extraction<br />
- Object#extend<br />
- Code seams<br />
- sleep sort: <a href="http://dis.4chan.org/read/prog/1295544154" target="_blank">http://dis.4chan.org/read/prog/1295544154</a> <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Recommended reading: <a href="http://www.amazon.co.uk/Working-Effectively-Legacy-Robert-Martin/dp/0131177052" target="_blank">Working effectibely with legacy code</a></p>
<p><strong>&#8220;Legacy&#8221; by Chad Fowler (@chadfowler)</strong></p>
<p>Chad started with playing a recording of Beethoven &#8211; this is legacy. Miro is legacy. Gaudi is legacy too, and the only reason to visit Barcelona.</p>
<p>Legacy is good.</p>
<p>Nobody will remember your work when you die. There are still systems in use written 25 years ago &#8211; why don&#8217;t we write that kind of code anymore?<br />
Average lifespan of a business software is 5 years (figure is probably made up)</p>
<p>Recommended reading:</p>
<p>Michael Feathers &#8220;<a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2007/03/your_code_its_a.html" target="_blank">Your Code.. it&#8217;s Alive..</a>&#8221;<br />
Richard P. Gabriel &#8220;<a href="http://www.dreamsongs.com/Files/DesignBeyondHumanAbilitiesSimp.pdf" target="_blank">Design Beyond Human Abilities</a>&#8221;</p>
<p>What kind of software lasts &#8211; either small (cell-size) or systems consisting of cell-sized software (like UNIX).</p>
<p>Force heterogenity &#8211; languages, OSes, frameworks &#8211; will change over time. If it&#8217;s hard to force heterogenity &#8211; do it all the time.</p>
<p><strong>&#8220;Must.Try.Harder&#8221; by Keavy McMinn (@keavy)</strong></p>
<p>An absolutely fascinating and inspirational talk from a woman who decided to train for an IronMan from pretty much zero.<br />
She did it. A rare inspirational example of how to go outside your comfort zone and achieve a goal that looked impossible.</p>
<p>&nbsp;</p>
<p>Other conference notes:</p>
<p>Fredrik Rubensson: <a href="http://www.highlevelbits.com/2011/06/nordic-ruby.html" target="_blank">http://www.highlevelbits.com/2011/06/nordic-ruby.html</a><br />
Andreas Ronge / Jayway:  <a href="http://blog.jayway.com/2011/06/19/notes-and-thoughts-from-a-great-conference/" target="_blank">http://blog.jayway.com/2011/06/19/notes-and-thoughts-from-a-great-conference/</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F06%2Fnotes-from-gothenburg-nordic-ruby-2011-conference.html&amp;title=Notes%20from%20Gothenburg%20%26%238211%3B%20Nordic%20Ruby%202011%20conference" id="wpa2a_2"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/06/notes-from-gothenburg-nordic-ruby-2011-conference.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>vim is the best editor, also for RoR development</title>
		<link>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html#comments</comments>
		<pubDate>Wed, 15 Jun 2011 15:35:15 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=329</guid>
		<description><![CDATA[vim is a natural choice when you&#8217;re starting a new programming project (if you&#8217;re emacs or textmate adept &#8211; you can stop reading now If you&#8217;re starting a Ruby on Rails project there are a couple of scripts/configurations you might want to install to make development with vim an even more pleasant experience. 1. Rails.vim [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.vim.org/"><a href="http://www.ivankuznetsov.com/wp-content/uploads/Screenshot.png"><img class="alignleft size-full wp-image-330" title="Rails and vim " src="http://www.ivankuznetsov.com/wp-content/uploads/Screenshot.png" alt="" width="300" height="176" /></a>vim</a> is a natural choice when you&#8217;re starting a new programming project (if you&#8217;re emacs or textmate adept &#8211; you can stop reading now <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  If you&#8217;re starting a Ruby on Rails project there are a couple of scripts/configurations you might want to install to make development with vim an even more pleasant experience.</p>
<p>1. <a href="https://github.com/tpope/vim-rails" target="_blank">Rails.vim</a> by <a href="http://tpo.pe/" target="_blank">Tim Pope</a></p>
<p>To install just copy autoload/rails.vim, plugin/rails.vim, and doc/rails.txt to corresponding directories in ~/.vim</p>
<p><a href="http://www.vim.org/scripts/script.php?script_id=1567" target="_blank">Vim scripts section</a> has a full description of the functionality. Some highlights:</p>
<ul>
<li>Easy navigation between models, controllers and views with :Rmodel, :Rview, :Rcontroller commands</li>
<li>Syntax highlighting</li>
<li>CTRL-X CTRL-U for autocompletion</li>
<li>:Rtree for project tree (see item 2)</li>
</ul>
<p>2. <a href="http://www.vim.org/scripts/script.php?script_id=1658" target="_blank">NERD Tree</a> by <a href="http://got-ravings.blogspot.com/" target="_blank">Marty Grenfell</a></p>
<p>Another must-have. Provides you with an easy way to navigate your project tree. Rails.vim nicely integrates with this one.</p>
<p>3. Colour schemas</p>
<p>If you want to save your eyes &#8211; use dark background when developing. Personally I prefer one of the standard vim themes &#8211; Desert , but <a href="http://www.vim.org/scripts/script.php?script_id=368" target="_blank">Ocean Deep</a> is also very good.</p>
<p>Copy theme file to ~/.vim/colors and then use</p>
<pre>:colorscheme oceandeep
</pre>
<p>command to apply it.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2011%2F06%2Fvim-is-the-best-editor-also-for-ror-development.html&amp;title=vim%20is%20the%20best%20editor%2C%20also%20for%20RoR%20development" id="wpa2a_4"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2011/06/vim-is-the-best-editor-also-for-ror-development.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Increasing Ruby interpreter performance by adjusting garbage collector settings</title>
		<link>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html</link>
		<comments>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html#comments</comments>
		<pubDate>Sun, 10 Oct 2010 23:10:12 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=305</guid>
		<description><![CDATA[According to Evan Weaver from Twitter it is possible for a typical production Rails app on Ruby 1.8 to recover 20% to 40% of user CPU by simply adjusting Ruby garbage collector settings. In August I set out on a quest to verify that statement on HeiaHeia servers. Results have really exceeded my expectations. Time to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/garbage.jpg"><img class="alignleft size-thumbnail wp-image-309" title="garbage" src="http://www.ivankuznetsov.com/wp-content/uploads/garbage-150x150.jpg" alt="" width="150" height="150" /></a>According to <a href="http://blog.evanweaver.com/articles/2009/04/09/ruby-gc-tuning/" target="_blank">Evan Weaver from Twitter</a> it is possible for a typical production Rails app on Ruby 1.8 to recover 20% to 40% of user CPU by simply adjusting Ruby garbage collector settings. In August I set out on a quest to verify that statement on <a href="http://www.heiaheia.com" target="_blank">HeiaHeia</a> servers. Results have really exceeded my expectations. Time to execute application tests locally decreased by 46%. On production servers CPU utilisation decreased by almost 40%.</p>
<div><span id="more-305"></span></div>
<p>But let&#8217;s start from the beginning. I should say right away that we at HeiaHeia are using <a href="http://www.rubyenterpriseedition.com/" target="_blank">Ruby Enterprise Edition</a>, so I didn&#8217;t have to apply patches to Ruby source code that Evan is talking about in his post. Before starting to analyse GC current usage it will be useful to read a brilliant <a href="http://timetobleed.com/garbage-collection-and-the-ruby-heap-from-railsconf/">overview of Ruby garbage collection</a> by Joe Damato. It&#8217;ll help to understand what&#8217;s going to happen next. It is also useful to read <a href="http://www.rubyenterpriseedition.com/documentation.html#_garbage_collector_performance_tuning" target="_blank">REE documentation on garbage collector performance tuning</a>.</p>
<p>And as before any optimisation it is good to get the reference metrics, so that you know you actually improved something by changing settings, and didn&#8217;t make it worse. In this case I measured:</p>
<div>
<ul>
<li>number of garbage collector calls when loading HeiaHeia-feed</li>
<li>local tests execution time (unit + functional)</li>
<li>application server CPU load and average response time</li>
</ul>
</div>
<p>To measure number of garbage collector calls per one page I used <a href="http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector/" target="_blank">Scrap &#8211; a nice tool by Chris Heald</a>. Chris also describes the tuning process in great detail, so I&#8217;m not going to repeat it &#8211; just go and read his blog.</p>
<p>To measure local test execution time I just ran <span style="font-family: Consolas, Monaco, 'Courier New', Courier, monospace; line-height: 18px; font-size: 12px; white-space: pre;">rake test </span>5 times and took the average of all runs.</p>
<p>To measure application server CPU load and average response time I used <a href="http://www.newrelic.com/" target="_blank">NewRelic</a> tool (free version should be enough to do the measurement).</p>
<p>When I first loaded feed page with Scrap enabled I saw 36 GC cycles, and Ruby spend 1.12s in GC cycles (these figures are from the development server, so response time is big). After playing a bit with the settings and monitoring GC cycles number and unused heap after each allocation with Scrap, I ended up with the same settings as Twitter uses in production:</p>
<pre><code>export RUBY_HEAP_MIN_SLOTS=500000
export RUBY_HEAP_SLOTS_INCREMENT=250000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=50000000</code></pre>
<p>These settings reduced GC cycles number down to 7 (from 36), and Ruby spent now only 0.62s in GC instead of 1.12s when loading feed page (again, load times are bigger on our development server).</p>
<p>After introducing same settings on my local machine project tests took only 148s &#8211; down from 274 seconds before optimisation &#8211; a whopping 46% improvement.</p>
<p>We have multiple identical application servers, so I introduced the new settings only on one of the application servers, to compare the results on a live system (during low traffic hours). Here&#8217;s the picture from NewRelic:</p>
<pre><span style="font-family: monospace;">Server        Instances        Apdex          Resp.time    Throughput    CPU          Memory
</span><span style="font-family: monospace;">hh-app1     3 Instances         0.86      	407 ms       30 rpm      14 %	      349 MB
</span><span style="font-family: monospace;">hh-app2     3 Instances         0.91   	        311 ms	     30 rpm       8 %	      413 MB</span></pre>
<p>hh-app2 had optimised garbage collector. With the same throughput CPU load  was only 8% vs 14% with non-optimised GC. However that improvement came at a cost of increased memory consumption (413M vs 349M). However response time and lower CPU load proved to be a lot more important than memory consumption, so I rolled out the new settings on all production servers.</p>
<p>Making <a href="http://nginx.org/" target="_blank">nginx</a> utilise GC settings when spawning <a href="http://www.modrails.com/" target="_blank">Passenger</a> instances is easy, and is well <a href="http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector/" target="_blank">described by Chris</a>. Here are instructions that work nice with server and Nginx setup on Ubuntu as I described in <a href="http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html" target="_blank">earlier posts</a>.</p>
<p>Create /usr/local/bin/ruby-with-env file (as a root) that will set GC settings in the environment and then launch Ruby:</p>
<pre>#!/bin/bash
export RUBY_HEAP_MIN_SLOTS=1500000
export RUBY_HEAP_SLOTS_INCREMENT=500000
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
export RUBY_GC_MALLOC_LIMIT=50000000
exec "/usr/local/bin/ruby" "$@"</pre>
<div>Make this file executable by all:</div>
<pre>sudo chmod a+x /usr/local/bin/ruby-with-env</pre>
<div>Now tell Passenger to use that file instead of launching Ruby directly &#8211; edit /opt/nginx/conf/nginx.conf and replace</div>
<pre>passenger_ruby /usr/local/bin/ruby;</pre>
<div>with</div>
<pre>passenger_ruby /usr/local/bin/ruby-with-env;</pre>
<div>Now restart Nginx &#8211; and you&#8217;ve got yourself a faster Ruby!</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F10%2Fincreasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html&amp;title=Increasing%20Ruby%20interpreter%20performance%20by%20adjusting%20garbage%20collector%20settings" id="wpa2a_6"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/10/increasing-ruby-interpreter-performance-by-adjusting-garbage-collector-settings.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Call to undefined function: imagecreatefromjpeg()</title>
		<link>http://www.ivankuznetsov.com/2010/10/call-to-undefined-function-imagecreatefromjpeg.html</link>
		<comments>http://www.ivankuznetsov.com/2010/10/call-to-undefined-function-imagecreatefromjpeg.html#comments</comments>
		<pubDate>Sun, 10 Oct 2010 08:34:23 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[imagecreatefromjpeg]]></category>
		<category><![CDATA[jpeg]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=299</guid>
		<description><![CDATA[While installing new Joomla modules I came across this PHP error (yep, still have to deal with PHP occasionally). I had PHP compiled from source on Ubuntu 10.04 as per earlier instructions. Quick check of phpinfo() indicated that while gd module was compiled in, it didn&#8217;t have JPEG support: GD Support enabled GD Version bundled [...]]]></description>
			<content:encoded><![CDATA[<p>While installing new Joomla modules I came across this PHP error (yep, still have to deal with PHP occasionally). I had PHP compiled from source on Ubuntu 10.04 as per <a href="http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html">earlier instructions</a>. Quick check of phpinfo() indicated that while gd module was compiled in, it didn&#8217;t have JPEG support:</p>
<pre>GD Support         enabled
GD Version         bundled (2.0.34 compatible)
GIF Read Support   enabled
GIF Create Support enabled
PNG Support        enabled
WBMP Support       enabled
XBM Support        enabled</pre>
<p>Making sure that JPEG libraries are installed</p>
<pre>sudo aptitude install libjpeg libjpeg-dev</pre>
<p>and reconfiguring PHP with &#8211;with-jpeg-dir flag (the rest of the compilation process remains the same as <a href="http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html">here</a>)</p>
<pre>./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib
--enable-mbstring --with-openssl --with-mysql --with-mysql-sock
--with-gd --without-sqlite --disable-pdo --with-jpeg-dir=/usr/lib</pre>
<p>and then restarting nginx</p>
<pre>sudo /etc/init.d/nginx restart</pre>
<p>helped to solve the problem.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F10%2Fcall-to-undefined-function-imagecreatefromjpeg.html&amp;title=Call%20to%20undefined%20function%3A%20imagecreatefromjpeg%28%29" id="wpa2a_8"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/10/call-to-undefined-function-imagecreatefromjpeg.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Running Rails applications using Nginx with Passenger on Ubuntu Server</title>
		<link>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html#comments</comments>
		<pubDate>Fri, 14 May 2010 10:40:50 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[mod_rails]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=279</guid>
		<description><![CDATA[If you&#8217;re planning to run Rails applications on Nginx using Phusion Passenger, and do it on Ubuntu Linux, here&#8217;s what needs to be done. Even though there&#8217;s Ubuntu nginx package available (which works perfectly when you&#8217;re running PHP apps using FCGI), if you want to take into use Phusion Passenger, you&#8217;ll need to recompile Nginx [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/enterprise_logo.png"><img class="alignleft size-full wp-image-281" title="enterprise_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/enterprise_logo.png" alt="" width="261" height="68" /></a>If you&#8217;re planning to run <a href="http://rubyonrails.org/" target="_blank">Rails</a> applications on <a href="http://www.nginx.org" target="_blank">Nginx</a> using <a href="http://www.modrails.com/" target="_blank">Phusion Passenger</a>, and do it on <a href="http://www.ubuntu.com" target="_blank">Ubuntu</a> Linux, here&#8217;s what needs to be done.</p>
<p>Even though there&#8217;s Ubuntu nginx package available (which works perfectly when you&#8217;re running <a href="http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html">PHP apps using FCGI</a>), if you want to take into use Phusion Passenger, you&#8217;ll need to recompile Nginx from sources.</p>
<p>Instructions below were verified on Ubuntu 10.04 (Lucid Lynx) Server Edition.</p>
<p><span id="more-279"></span></p>
<p>If you already have Nginx ubuntu package installed, uninstall it (NOTE! purge will delete all configuration files &#8211; so if you changed them &#8211; make a backup for future reference):</p>
<pre>sudo aptitude purge nginx</pre>
<p>Assuming you already have Rails stack installed, install Passenger gem:</p>
<pre>sudo gem install passenger</pre>
<p>At the time of this writing the latest version of Passenger is 2.2.11</p>
<p>Let&#8217;s check dependencies that Ubuntu nginx package has and install them before compilation:</p>
<pre>aptitude show nginx | grep Depends</pre>
<div>You&#8217;ll see something like:</div>
<pre>Depends: libc6 (&gt;= 2.4), libpcre3 (&gt;= 7.7), libssl0.9.8 (&gt;= 0.9.8k-1), zlib1g</pre>
<div>Install build dependencies and start nginx module installation (it will offer you to recompile nginx)</div>
<pre>sudo apt-get install libc6 libpcre3 libssl0.9.8 zlib1g
sudo /usr/local/bin/passenger-install-nginx-module</pre>
<div>Choose option 1 (Yes: download, compile and install Nginx for me) unless you need special configuration parameters or need features not enabled by default (like SSL).</div>
<div>Further instructions assume that you also chose default installation directory /opt/nginx.</div>
<div>If you&#8217;ve purchased Passenger Enterprise Edition, don&#8217;t forget to register it:</div>
<pre>sudo /usr/local/bin/passenger-make-enterprisey</pre>
<div>Now add nginx init script (I just copied this from Ubuntu default nginx package):</div>
<pre>sudo vim /etc/init.d/nginx</pre>
<div>with the following content:</div>
<pre>#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $local_fs $remote_fs $network $syslog
# Required-Stop:     $local_fs $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the nginx web server
# Description:       starts nginx using start-stop-daemon
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/nginx/sbin
DAEMON=/opt/nginx/sbin/nginx
NAME=nginx
DESC=nginx

test -x $DAEMON || exit 0

# Include nginx defaults if available
if [ -f /etc/default/nginx ] ; then
        . /etc/default/nginx
fi

set -e

. /lib/lsb/init-functions

test_nginx_config() {
  if nginx -t $DAEMON_OPTS
  then
    return 0
  else
    return $?
  fi
}

case "$1" in
  start)
        echo -n "Starting $DESC: "
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
                --exec $DAEMON || true
        echo "$NAME."
        ;;
  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON || true
        sleep 1
        test_nginx_config
        start-stop-daemon --start --quiet --pidfile \
                /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS || true
        echo "$NAME."
        ;;
  reload)
        echo -n "Reloading $DESC configuration: "
        test_nginx_config
        start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/$NAME.pid \
            --exec $DAEMON || true
        echo "$NAME."
        ;;
  configtest)
        echo -n "Testing $DESC configuration: "
        if test_nginx_config
        then
          echo "$NAME."
        else
          exit $?
        fi
        ;;
  status)
        status_of_proc -p /var/run/$NAME.pid "$DAEMON" nginx &amp;&amp; exit 0 || exit $?
        ;;
  *)
        echo "Usage: $NAME {start|stop|restart|reload|force-reload|status|configtest}" &gt;&amp;2
        exit 1
        ;;
esac

exit 0</pre>
<div>Now make this script executable add it to default run levels:</div>
<pre>sudo chmod +x /etc/init.d/nginx
sudo /usr/sbin/update-rc.d -f nginx defaults</pre>
<div>Edit  nginx.conf to look like this:</div>
<pre>user www-data;
worker_processes  4;

error_log  /opt/nginx/logs/error.log;
pid        /var/run/nginx.pid;

events {
    worker_connections  8192;
    use epoll;
}

http {
    passenger_root /usr/local/lib/ruby/gems/1.8/gems/passenger-2.2.11;
    passenger_ruby /usr/local/bin/ruby;

    include       /opt/nginx/conf/mime.types;

    # set a default type for the rare situation that
    # nothing matches from the mimie-type include
    default_type application/octet-stream;

    # This log format is compatible with any tool like awstats
    # that can parse standard apache logs.
    log_format main '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"' ;

    access_log  /opt/nginx/logs/access.log;

    sendfile        on;
    tcp_nopush     on;

    keepalive_timeout  0;
    tcp_nodelay        on;

    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_proxied any;
    gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    include /opt/nginx/conf/sites-enabled/*;
}</pre>
<div>Now create virtual hosts structure (so that it looks like the structure created by Ubuntu original nginx package):</div>
<div>
<pre>sudo mkdir /opt/nginx/conf/sites-available
sudo mkdir /opt/nginx/conf/sites-enabled</pre>
</div>
<div>Now it is time to configure your first rails site. Create virtual host configuration in sites-available.</div>
<pre>sudo vim /opt/nginx/conf/sites-available/mysite.com</pre>
<div>Content can be something like:</div>
<pre>server {
        listen   80;
        server_name  www.mysite.com;

        access_log  /home/user/logs/www.mysite.com/access.log;
        root   /home/user/www.mysite.com/public;

        # serve static content directly
        location ~* \.(ico|jpg|gif|png|css|js|swf|html)$ {
          if (-f $request_filename) {
            expires max;
            break;
          }
        }

        passenger_enabled on;

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
          deny  all;
        }
}</pre>
<div>Make a symlink in sites-enabled directory and restart nginx.</div>
<pre>sudo ln -s /opt/nginx/conf/sites-available/mysite.com /opt/nginx/conf/sites-enabled/mysite.com
sudo /etc/init.d/nginx restart</pre>
<div>Now open the browser and check that your site is working.</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F05%2Frunning-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html&amp;title=Running%20Rails%20applications%20using%20Nginx%20with%20Passenger%20on%20Ubuntu%20Server" id="wpa2a_10"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/05/running-rails-applications-using-nginx-with-passenger-on-ubuntu-server.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Moving Joomla, WordPress and other PHP/FastCGI apps to Nginx</title>
		<link>http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html#comments</comments>
		<pubDate>Fri, 14 May 2010 07:01:50 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[fast-cgi]]></category>
		<category><![CDATA[joomla]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php-fpm]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=272</guid>
		<description><![CDATA[Have you moved your site from Apache to Nginx and now your FastCGI (php-cgi/spawn-fcgi) processes die/hang/crash periodically and your users see &#8220;HTTP 502 Bad gateway&#8221; or &#8220;HTTP 504 Gateway timeout&#8221; instead of a website? I have faced this problem and found a relatively simple and robust solution. Here&#8217;s how I did it on Ubuntu 9.10 (Karmic [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/nginx-logo.png"><img class="alignleft size-full wp-image-273" title="nginx-logo" src="http://www.ivankuznetsov.com/wp-content/uploads/nginx-logo.png" alt="" width="350" height="90" /></a>Have you moved your site from <a href="http://apache.org/" target="_blank">Apache</a> to <a href="http://nginx.org/" target="_blank">Nginx</a> and now your FastCGI (php-cgi/spawn-fcgi) processes die/hang/crash periodically and your users see &#8220;HTTP 502 Bad gateway&#8221; or &#8220;HTTP 504 Gateway timeout&#8221; instead of a website?</p>
<p>I have faced this problem and found a relatively simple and robust solution. Here&#8217;s how I did it on Ubuntu 9.10 (Karmic Koala) and 10.04 (Lucid Lynx) server edition.</p>
<p><span id="more-272"></span>Solution was to replace default FastCGI implementation with <a href="http://php-fpm.org/" target="_blank">PHP-FPM</a> (FastCGI Process Manager). PHP-FPM is not supported in PHP out of the box &#8211; so if you use PHP 5.2.*, you&#8217;ll need to apply a patch and recompile PHP, and if you&#8217;re using PHP 5.3.* (at least in 5.3.2 PHP-FPM is not yet in the core) &#8211; you&#8217;ll need to check out PHP-FPM from PHP SVN.</p>
<p>Let&#8217;s start with uninstalling default Ubuntu php packages:</p>
<pre>sudo apt-get remove php5*</pre>
<p>Now we need to install dependencies. Note, that Ubuntu comes with a new autoconf tool version, which is <a href="https://bugs.launchpad.net/ubuntu/+source/php5/+bug/411890" target="_blank">not compatible</a> with PHP, that&#8217;s why for successful compilation you need to temporarily install autoconf2.13 package.</p>
<pre>sudo apt-get install libcurl4-openssl-dev libmcrypt-dev libxml2-dev libpng-dev 
autoconf2.13 libevent-dev libltdl-dev</pre>
<p>Download latest stable PHP 5.2.13, Suhosin patch, PHP-FPM patch</p>
<pre>cd ~/tmp
wget <a href="http://pl2.php.net/get/php-5.2.13.tar.gz/from/pl.php.net/mirror">http://pl2.php.net/get/php-5.2.13.tar.gz/from/pl.php.net/mirror</a>
wget <a href="http://download.suhosin.org/suhosin-patch-5.2.13-0.9.7.patch.gz">http://download.suhosin.org/suhosin-patch-5.2.13-0.9.7.patch.gz</a>
wget <a href="http://php-fpm.org/downloads/php-5.2.13-fpm-0.5.13.diff.gz">http://php-fpm.org/downloads/php-5.2.13-fpm-0.5.13.diff.gz</a>
tar xvzf php-5.2.13.tar.gz
gunzip suhosin-patch-5.2.13-0.9.7.patch.gz
gunzip php-5.2.13-fpm-0.5.13.diff.gz
cd php-5.2.13
patch -p 1 -i ../php-5.2.13-fpm-0.5.13.diff
patch -p 1 -i ../suhosin-patch-5.2.13-0.9.7.patch
./buildconf --force
./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl
--with-mysql --with-mysql-sock --with-gd --without-sqlite --disable-pdo
make
make test
sudo make install</pre>
<p>Alternatively you can download latest stable PHP 5.3.2, Suhosin patch, apply PHP-FPM patch. Note, that not all PHP based projects and plugins work correctly with new PHP 5.3 &#8211; it is not backwards compatible with PHP 5.2. I had troubles at least with some Joomla plugins and ZenCart.</p>
<pre>cd ~/tmp
<a href="http://fi.php.net/get/php-5.3.2.tar.gz/from/this/mirror">http://fi.php.net/get/php-5.3.2.tar.gz/from/this/mirror</a>
wget <a href="http://download.suhosin.org/suhosin-patch-5.3.2-0.9.9.1.patch.gz">http://download.suhosin.org/suhosin-patch-5.3.2-0.9.9.1.patch.gz</a>
tar xvzf php-5.3.2.tar.gz
gunzip suhosin-patch-5.3.2-0.9.9.1.patch.gz
cd php-5.3.2
patch -p 1 -i ../suhosin-patch-5.3.2-0.9.9.1.patch
svn co <a href="http://svn.php.net/repository/php/php-src/trunk/sapi/fpm">http://svn.php.net/repository/php/php-src/trunk/sapi/fpm</a> sapi/fpm
./buildconf --force
./configure --enable-fastcgi --enable-fpm --with-mcrypt --with-zlib --enable-mbstring --with-openssl
--with-mysql --with-mysql-sock --with-gd --without-sqlite --disable-pdo --disable-reflection
make
make test
sudo make install</pre>
<p>Uninstall autoconf2.13 after compilation.</p>
<pre>sudo apt-get remove autoconf2.13</pre>
<p>Change user and group of php-fpm processes to user and group of your choice (e.g. www-data and www-data) &#8211; lines 63 and 66</p>
<pre>sudo vim /usr/local/etc/php-fpm.conf</pre>
<p>Edit PHP settings</p>
<pre>sudo vim /etc/php5/cgi/php.ini (in Ubuntu 9.xx)</pre>
<pre>sudo vim /etc/php5/apache2/php.ini (in Ubuntu 10.04)</pre>
<p>Set:</p>
<pre>max_execution_time = 30
memory_limit = 128M
error_reporting = E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR
display_errors = Off
log_errors = On
error_log = /var/log/php.log
register_globals = Off</pre>
<p>Now if you haven&#8217;t done so yet, install Nginx. Ubuntu 10.04 comes with the latest stable Nginx 0.7.65, so just do:</p>
<pre>sudo apt-get install nginx</pre>
<p>Now you can congifure your sites, e.g. for WordPress Nginx configuration can look like this:</p>
<pre>server {
        listen   80;
        server_name  blog.mysite.com;

        access_log  /home/user/logs/blog.mysite.com/access.log;

        location / {
          root   /home/user/blog.mysite.com;
          index  index.php index.html index.htm;

          # this serves static files that exist without running other rewrite tests
          if (-f $request_filename) {
              expires 30d;
              break;
          }

          # this sends all non-existing file or directory requests to index.php
          if (!-e $request_filename) {
              rewrite ^(.+)$ /index.php?q=$1 last;
          }

        }

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location ~ \.php$ {
          include /etc/nginx/fastcgi_params;
          fastcgi_pass  127.0.0.1:9000;
          fastcgi_index index.php;
          fastcgi_param  SCRIPT_FILENAME  /home/user/blog.mysite.com/$fastcgi_script_name;
        }

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
          deny  all;
        }
}</pre>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F05%2Fmoving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html&amp;title=Moving%20Joomla%2C%20WordPress%20and%20other%20PHP%2FFastCGI%20apps%20to%20Nginx" id="wpa2a_12"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Informal notes from #frozenrails 2010</title>
		<link>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html#comments</comments>
		<pubDate>Tue, 11 May 2010 07:17:53 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[frozenrails]]></category>
		<category><![CDATA[ror]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=248</guid>
		<description><![CDATA[Thanks to organisers from Kisko Labs and the HHLinuxClub on Friday, May 7th, 2010 Finland got its first  Rails conference. Conference has drawn very interesting speakers and  international crowd &#8211; from Finland (naturally), Sweden, Poland, Germany, Russia and other countries. I made a few notes from selected talks on the conference. Chris Wanstrath / GitHub (@defunkt) Slides: [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ivankuznetsov.com/wp-content/uploads/frozen_rails_logo.png"><img class="alignleft " title="frozen_rails_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/frozen_rails_logo.png" alt="" width="99" height="95" /></a>Thanks to organisers from <a href="http://www.kiskolabs.com/">Kisko Labs</a> and the <a href="http://www.hhlinuxclub.org/">HHLinuxClub</a> on Friday, May 7th, 2010 Finland got its first  Rails conference.</p>
<p>Conference has drawn very interesting speakers and  international crowd &#8211; from Finland (naturally), Sweden, Poland, Germany, Russia and other countries. I made a few notes from selected talks on the conference.</p>
<h3>Chris Wanstrath / GitHub (<a href="http://twitter.com/defunkt" target="_blank">@defunkt</a>)</h3>
<ul>
<li>Slides: <a href="http://www.slideshare.net/err/inside-github" target="_blank">http://www.slideshare.net/err/inside-github</a></li>
<li><a href="http://www.youtube.com/watch?v=4XpnKHJAok8" target="_blank">Linus Trovalds Google tech talk about git</a> &#8211; where Linus tell you that you&#8217;re stpid if you&#8217;re not using git</li>
<li><a href="http://github.com/talison/rack-mobile-detect" target="_blank">rack-mobile-detect</a> – is used by GitHub, super useful if you&#8217;re planning to create mobile optimized version</li>
<li>GitHub uses Unicorn as an application server – personally I&#8217;m not sure if that&#8217;s better than Apache + Passenger. Chris tells that Unicorn is cool, because does fair load balancing on Linux kernel level, also Rails are loaded only once &#8211; and then required number of processes are forked &#8211; and this is very fast, a lot faster than loading rails separately for each Mongrel. And when one of the processes dies &#8211; there&#8217;s no need to re-load Rails, but just fork another process.</li>
<li>GitHub users <a href="http://github.com/blog/531-introducing-bert-and-bert-rpc" target="_blank">BERT</a> to forward requests to one of their six servers – BERT to Erlang is the same as JSON to JavaScript</li>
<li>GitHub doesn&#8217;t use <a href="http://github.com/collectiveidea/delayed_job" target="_blank">delayed_job</a> anymore since they needed several queues with different priorities &#8211; so far they use <a href="http://github.com/blog/542-introducing-resque" target="_blank">resque</a>, but are considering developing a real queue management system</li>
</ul>
<p><span id="more-248"></span></p>
<h3>Jose Valim / Plataforma (<a href="http://twitter.com/josevalim" target="_blank">@josevalim</a>)</h3>
<ul>
<li>Brazilian Rails consultants and developers: <a href="http://plataformatec.com.br/" target="_blank">http://plataformatec.com.br/</a></li>
<li>Developed several interesting components to make their life easier &#8211; extracted common components from several customer projects and open-sourced them</li>
<li>User authorisation and roles: Devise – <a href="http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/" target="_blank">http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/</a></li>
<li><a href="http://blog.plataformatec.com.br/2010/04/authentication-is-with-devise/" target="_blank"></a>Nice forms with labels, error handling, etc. : Simple Form – <a href="http://github.com/plataformatec/simple_form" target="_blank">http://github.com/plataformatec/simple_form</a></li>
</ul>
<h3>Mike Dirolf / MongoDB (<a href="http://twitter.com/mdirolf" target="_blank">@mdirolf</a>) &amp; Jonathan Weiss / CouchDB (<a href="http://twitter.com/jweiss" target="_blank">@jweiss</a>)</h3>
<ul>
<li>Two very interesting NoSQL presentations: <a href="http://www.slideshare.net/mdirolf/mongodb-at-frozenrails" target="_blank">http://www.slideshare.net/mdirolf/mongodb-at-frozenrails</a>, <a href="http://www.slideshare.net/jweiss/couchdb-on-rails-frozenrails-2010" target="_blank">http://www.slideshare.net/jweiss/couchdb-on-rails-frozenrails-2010</a></li>
<li>Answering a question from the audience Mike said that fault tolerance is something that is not quite there yet in MongoDB &#8211; there is a possibility to do recovery, but there&#8217;s a chance data might be lost</li>
<li>There is no such issue in CouchDB, it also is written in Erland and provides REST API</li>
<li>Links to project homepages: <a href="http://couchdb.apache.org/" target="_blank">http://couchdb.apache.org/</a> &amp;<a href=" http://www.mongodb.org/" target="_blank"> http://www.mongodb.org/</a> &#8211; worth taking a look at both</li>
</ul>
<h3>Yehuda Katz / EngineYard (<a href="http://twitter.com/wycats" target="_blank">@wycats</a>)</h3>
<ul>
<li>Very interesting presentation about developing web application for mobile devices (in Rails 3)</li>
<li>One of the central messages &#8211; HTML5 is coming &#8211; learn how to use it now, if you want to stay in business</li>
<li>I really hope Yehuda will publish his slides &#8211; it was a presentation worth spreading around</li>
<li>interesting thoughts:
<ul>
<li>same optimization methods as we traditionally use for Rails apps on desktop are not suitable for mobile browsers due to constraints &#8211; connection availability, memory, cpu, battery, etc.</li>
<li>don&#8217;t count on browser cach on mobile devices – separate data and presentation, cache presentation using localStorage feature of HTML5, load only data from the web after that</li>
<li>mobile browsers are updated a lot faster than desktop borwser &#8211; there are new browsers in the new phones, and nobody uses 2 year old phone</li>
<li>HTML5 will become mainstream on mobile devices a lot faster than on desktop (IE6 will not happen on mobile)</li>
<li>when developing apps for mobile take into account that in some places people still pay per kilobyte of traffic</li>
<li>incremental rendering on the mobile is evil &#8211; it consumes battery and can be very slow, unpleasant and unusable for the user</li>
</ul>
</li>
<li>battery &#8211; unoptimized sites can easily drain the battery, and even though users are most likely to blame the phone manufacturer it is good to think about it</li>
<li>http://Railsdispatch.com – recommended reading about Rails 3</li>
</ul>
<h3>Carl Lerche / Engine Yard (<a href="http://twitter.com/carllerche" target="_blank">@carllerche</a>)</h3>
<ul>
<li>Carl told about Rails 3 and migration to version 3 from earlier ones <a href="http://www.slideshare.net/carllerche/frozen-rails-slides" target="_blank">http://www.slideshare.net/carllerche/frozen-rails-slides</a></li>
<li>Migration itself is not that difficult (provided that you know what you&#8217;re doing) – it can even be done in 15 minutes, but thus far stability and performance of Rails 3 / Ruby 1.9.1 are not quite there yet</li>
<li>Rails 3 is not finished &#8211; the plan is to make RC for RailsConf, and the it will be released “when it’s ready”</li>
<li>When asked if they have done performance tests on Rails 3, Carl answered that, yes, they did, and its sad.  Performance optimization is the next big step after stabilization.</li>
<li>When asked which Ruby release is better to use with Rails 3, Carl answered &#8211; 1.8.7, since Ruby 1.9.1 still segfaults and is not ready for production sites.</li>
</ul>
<h3>JetBrains (<a href="http://twitter.com/rubymine" target="_blank">@rubymine</a>):</h3>
<ul>
<li>new release of RubyMine is available with Rails3 support</li>
<li>guys from JetBrains tell that  TextMate development/maintenance is lagging behind, and they observe migration of TextMate and even vim users to RubyMine (there&#8217;s now vim interface emultion)</li>
</ul>
<h3>overall impression:</h3>
<ul>
<li>Apple is the king – virtually everybody was walking around with either MacBook, iPhone, iPad or all of the above</li>
<li>first Rails conference in Finland was a huge success &#8211; I really hope there will be FrozenRails 2011</li>
</ul>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F05%2Finformal-notes-from-frozenrails-2010.html&amp;title=Informal%20notes%20from%20%23frozenrails%202010" id="wpa2a_14"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/05/informal-notes-from-frozenrails-2010.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Web hosting for internet startups</title>
		<link>http://www.ivankuznetsov.com/2010/01/web-hosting-for-internet-startups.html</link>
		<comments>http://www.ivankuznetsov.com/2010/01/web-hosting-for-internet-startups.html#comments</comments>
		<pubDate>Sat, 16 Jan 2010 18:02:41 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Dreamhost]]></category>
		<category><![CDATA[Linode]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=227</guid>
		<description><![CDATA[A lot of companies launching their own internet services have faced the same question &#8211; where to host. Over the course of the last few months I was asked for opinion on this matter several times. While I have no definitive answer, here are some recommendations. Don&#8217;t start with maximum capacity, start small, and think [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" title="Linode" src="http://www.linode.com/images/linode_logo_gray.png" alt="" width="288" height="65" />A lot of companies launching their own internet services have faced the same question &#8211; where to host. Over the course of the last few months I was asked for opinion on this matter several times. While I have no definitive answer, here are some recommendations.</p>
<p>Don&#8217;t start with maximum capacity, start small, and think about scalability &#8211; how fast you can do it, and how you will do it. Then map the plans to what your selected hosting provider offers. Avoid temptation to use your own hardware, unless you really have resources for administering and maintaining it and a real need to have physical access to the servers. Even companies using their own hardware use virtualization to run virtual machines on top of physical ones.</p>
<p>Two years ago, when we were just experimenting with ideas of the social training log, a shared hosting option on Dreamhost gave us the best prices/features/quality combination. When we launched first closed version of the service named <a href="http://www.ivankuznetsov.com/2009/03/introducing-moozement.html">Moozement</a> at the time, we switched to Dreamhost VPS, which allowed enough flexibility and had reasonable pricing. For <a href="http://www.heiaheia.com" target="_blank">HeiaHeia</a> (<a href="http://www.ivankuznetsov.com/2010/01/heiaheia-probably-the-most-fun-way-to-keep-fit-2.html" target="_self">Moozement beta version</a>) we&#8217;ve chosen <a href="http://www.linode.com/?r=9fabdff6a260bde81ad4c6df63ec6a26f6940e94" target="_blank">Linode</a>, as it offers Xen virtualization (as opposed to Dreamhost&#8217;s VServer), servers with up to 14400Mb of RAM, easy resizing, wide selection of Linux distributions, and several data centres to choose from, including one in London. As HeiaHeia grows, we are preparing for the next step, but for now Linode proved to be excellent choice.</p>
<p>If your company is based in EU, you also need to remember about <a href="http://en.wikipedia.org/wiki/Data_Protection_Directive" target="_blank">EU Data Protection Directive</a> &#8211; your servers need to be physically located in one of the European Union countries or in the US with a provider following <a href="http://en.wikipedia.org/wiki/Safe_Harbor_Principles" target="_blank">Safe Harbor Principles</a>.</p>
<p>If you have no clue about how much CPU/RAM/traffic your application will need &#8211; check reference cases &#8211; there are plenty on the internet. Here are just a couple of examples: social network <a href="http://highscalability.com/blog/2009/9/22/how-ravelry-scales-to-10-million-requests-using-rails.html" target="_blank">Ravelry</a> and Facebook app <a href="http://highscalability.com/friends-sale-architecture-300-million-page-view-month-facebook-ror-app" target="_blank">Friends for Sale</a>.</p>
<p>Want second opinion? Check these:</p>
<ul>
<li>Teemu Kurppa from Huikea has a <a href="http://dirtyaura.org/blog/2009/09/22/programmer-friendly-virtual-private-server-hosts/" target="_blank">great write up on choosing hosting subject</a> &#8211; Teemu has chosen Slicehost</li>
</ul>
<ul>
<li>Eivind Uggedal has a <a href="http://journal.uggedal.com/vps-performance-comparison">very thorough comparison</a> of Slicehost, Linode, Prgmr, Rackspace and Amazon EC2 pricing and performance and arrives at a conclusion that Linode gives you best bang for the buck.</li>
</ul>
<p>In case you decide to use Linode, use <a href="http://www.linode.com/?r=9fabdff6a260bde81ad4c6df63ec6a26f6940e94">this referral link</a> to give us some reward <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>If you&#8217;re planning to host a low traffic service, and don&#8217;t want to spend much time on system administration &#8211; Dreamhost is a great starting point. And as I <a href="http://www.ivankuznetsov.com/2008/03/radiant-cms.html">already wrote earlier</a>, <a href="http://www.dreamhost.com/">Dreamhost</a> provides excellent value for money. If you are looking for a good hosting – use IVANKUZNETSOV promocode and get a $50 discount when setting up an account on Dreamhost.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2010%2F01%2Fweb-hosting-for-internet-startups.html&amp;title=Web%20hosting%20for%20internet%20startups" id="wpa2a_16"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2010/01/web-hosting-for-internet-startups.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up Ruby, Rails, Git and Redmine on Dreamhost</title>
		<link>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html</link>
		<comments>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html#comments</comments>
		<pubDate>Thu, 30 Jul 2009 14:58:27 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Dreamhost]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Web/Tech]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[redmine]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=195</guid>
		<description><![CDATA[The task is to have: - Redmine installation on redmine.mydomain.com - Several Git repositories on git.mydomain.com with different access rights to each one This proved to be a non-trivial task. There is a number of tutorials on the net, but none of them described the full solution. So after getting it all to work, I [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-196" title="Git, RedMine, Ruby, Rails on Dreamhost" src="http://www.ivankuznetsov.com/wp-content/uploads/git.png" alt="Git, RedMine, Ruby, Rails on Dreamhost" width="200" height="150" />The task is to have:<br />
- Redmine installation on redmine.mydomain.com<br />
- Several Git repositories on git.mydomain.com with different access rights to each one</p>
<p>This proved to be a non-trivial task. There is a number of tutorials on the net, but none of them described the full solution. So after getting it all to work, I decided to share all the tips and tricks. Feel free to comment, if you will find problems with the following set of instructions.<br />
<span id="more-195"></span>SSH to redmine.mydomain.com as a user that will be running Redmine (in the following examples it will be &#8216;redmine_user&#8217;).<br />
First, you need to compile openssl &#8211; it will be required for curl, git and redmine.</p>
<pre>mkdir ~/tmp
cd ~/tmp
wget http://www.openssl.org/source/openssl-0.9.8k.tar.gz
tar xzvf openssl-0.9.8k.tar.gz
cd openssl-0.9.8k
./config shared zlib --prefix=$HOME/.packages
make
make install</pre>
<p>Let&#8217;s tell the world that we keep binaries and libraries also in the local directory. Edit ~/.bashrc (it is used by all non-login shells):</p>
<pre>export TZ='Europe/Helsinki'
export PATH="$HOME/.packages/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/.packages/lib"
export GEM_HOME="$HOME/.gems"
export GEM_PATH="$GEM_HOME:/usr/lib/ruby/gems/1.8"
export PATH="$HOME/.packages/bin:$HOME/.gems/bin:$PATH"
export RUBYLIB="$HOME/.packages/lib:$RUBYLIB"
export LD_LIBRARY_PATH="$HOME/.packages/lib"

# this ensures our gem install processes don't get killed by the DreamHost police
alias gem="nice -n19 ~/.packages/bin/gem"</pre>
<p>(You can skip TZ &#8211; it is just usefule to have correct time set for your environment. Use tzselect to find out correct TZ string for your region)</p>
<p>And edit ~/.bash_profile (it is used by login shells):</p>
<pre>umask 002
PS1='[\h:$PWD]$ '
alias ll="ls -l"
EDITOR="/usr/bin/vim"
. .bashrc</pre>
<p>Now let&#8217;s apply the changes in active shell:</p>
<pre>cd ~ : . .bash_profile</pre>
<p>Then you need to compile curl, to be able to compile git with curl and execute clone commands on your server.</p>
<pre>cd ~/tmp
wget http://curl.haxx.se/download/curl-7.19.5.tar.gz
tar xzvf curl-7.19.5.tar.gz
cd curl-7.19.5
./configure --prefix=$HOME/.packages --with-ssl=$HOME/.packages
make
make install</pre>
<p>Now get and compile Git. If you are not using Dreamhost PS, you might want to compile it with NO_MMPAP=1, to reduce<br />
probability of git process getting killed by Dreamhost police robots due to extensive memory</p>
<pre>cd ~/tmp
wget http://www.kernel.org/pub/software/scm/git/git-1.6.4.tar.gz
tar xzvf git-1.6.4.tar.gz
cd git-1.6.4
./configure --prefix=$HOME/.packages --with-curl=$HOME/.packages
make
make install</pre>
<p>Let&#8217;s start with ruby and rails related stuff. First readline library is needed, for script/console to work.</p>
<pre>cd ~/tmp
wget http://ftp.gnu.org/gnu/readline/readline-5.2.tar.gz
tar xzvf readline-5.2.tar.gz
cd readline-5.2
./configure --prefix=$HOME/.packages
make
make install</pre>
<p>Install ruby:</p>
<pre>cd ~/tmp
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
tar zxvf ruby-1.8.7-p72.tar.gz
cd ruby-1.8.7-p72
./configure --prefix=$HOME/.packages --with-openssl-dir=$HOME/.packages --with-readline-dir=$HOME/.packages
make
make install</pre>
<p>Install rubygems:</p>
<pre>cd ~/tmp
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar zxvf rubygems-1.3.5.tgz
cd rubygems-1.3.5
ruby setup.rb config --prefix=$HOME/.packages
ruby setup.rb setup
ruby setup.rb install</pre>
<p>Now you can install all required gems and freeze them if necessary.</p>
<p><strong>Installing RedMine</strong></p>
<p>Refer to <a href="http://wiki.dreamhost.com/Redmine" target="_blank">http://wiki.dreamhost.com/Redmine</a> for details.</p>
<p>But there&#8217;s one trick &#8211; if you want RedMine to use just compiled version of Git &#8211; edit in lib/redmine/scm/adapters/git_adapter.rb:</p>
<pre># Git executable name
GIT_BIN = "/home/username/.packages/bin/git"</pre>
<p>If this is not done, default Dreamhost git will be used (which is too old at the moment 1.4.4.4) and Git repository browsing will not work in RedMine<br />
(see <a href="http://groups.google.com/group/phusion-passenger/browse_thread/thread/5080d7c7cfbcf20e" target="_blank">http://groups.google.com/group/phusion-passenger/browse_thread/thread/5080d7c7cfbcf20e</a>).</p>
<p><strong>Setting up Git repository</strong></p>
<p>Refer to <a href="http://wiki.dreamhost.com/Git" target="_blank">http://wiki.dreamhost.com/Git</a> for details.</p>
<p>Couple of tricks here. There are bugs in WebDAV functionality in Ubuntu &#8211; so if you&#8217;re using it &#8211; launch Nautilus, use &#8220;File-&gt;Connect to server&#8230;&#8221; menu from there (not from the system menu), don&#8217;t enter user name in the dialog &#8211; leave it empty and enter it when you&#8217;re requested username and password in the next dialog.</p>
<p>When setting up WebDAV access rights, give access to user &#8220;redmine&#8221;.</p>
<p><strong>Setting Git repository copy for Redmine</strong></p>
<p>Create ~/.netrc for your redmine user on Dreamhost</p>
<p>Insert the following line in that file</p>
<pre>machine git.mydomain.com login redmine password [redmine_password]</pre>
<p>where redmine_password is the password you gave to user redmine in the previous step.<br />
.netrc will ensure that password is not asked when git is accessing the repository.<br />
You don&#8217;t need to bother about creating .netrc if you have a public repository (or at least available for cloning without password).</p>
<p><strong>Create a local copy of the repository</strong></p>
<p>For RedMine to be able to display Git repository, it needs to have a local clone of the repository.</p>
<pre>mkdir ~/git_project_clones
cd git_project_clones
git clone http://git.mydomain.com/repository_name</pre>
<p>Now you should have a local copy that can be used from RedMine.<br />
All you have left to do is to set up regular pulls from the master repository to this local copy. Use command</p>
<pre>crontab -e</pre>
<p>Add the following line to pull latest change into local copy every 5 minutes:</p>
<pre>*/5 * * * * cd /home/redmine_user/git_project_clones/repository_name &amp;&amp; /home/redmine_user/.packages/bin/git pull</pre>
<p>Make sure that you specify full path to git &#8211; otherwise it will execute Dreamhost default git 1.4.4.4 and command will fail with &#8220;refusing to create funny ref &#8216;remotes/origin/*&#8217; locally&#8221; error.</p>
<p>Save and exit cron editor.</p>
<p>(You might also want to check Redmine own wiki: <a href="http://www.redmine.org/wiki/redmine/HowTo_keep_in_sync_your_git_repository_for_redmine" target="_blank">http://www.redmine.org/wiki/redmine/HowTo_keep_in_sync_your_git_repository_for_redmine</a>)</p>
<p>Set repository in the settings of your project in RedMine: /home/redmine_user/git_project_clones/repository_name/.git</p>
<p>Now you need to manually update Git repository changesets in RedMine:</p>
<pre>cd ~/mydomain.com
script/runner "Repository.fetch_changesets" -e production</pre>
<p>And set a hook to your repository to do this every time repository is updated &#8211; edit ~/git_project_clones/repository_name/.git/hooks/post-update file and add the following command ther:</p>
<pre>cd /home/redmine_user/mydomain.com &amp;&amp; script/runner "Repository.fetch_changesets" -e production</pre>
<p>When writing this blogpost I found a lot of useful information on Dreamhost own wiki as well on these blog posts:<br />
<a href="http://www.wavethenavel.com/2008/09/08/bootstrapping-a-dreamhost-account-for-rails-and-git/" target="_blank"> http://www.wavethenavel.com/2008/09/08/bootstrapping-a-dreamhost-account-for-rails-and-git/</a><br />
<a href="http://juliobiason.net/2008/05/19/git-repositories-on-dreamhost-via-ssh/" target="_blank"> http://juliobiason.net/2008/05/19/git-repositories-on-dreamhost-via-ssh/</a><br />
<a href="http://www.simonecarletti.com/blog/2009/07/configuring-git-repository-with-redmine/" target="_blank"> http://www.simonecarletti.com/blog/2009/07/configuring-git-repository-with-redmine/</a></p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2009%2F07%2Fsetting-up-ruby-rails-git-and-redmine-on-dreamhost.html&amp;title=Setting%20up%20Ruby%2C%20Rails%2C%20Git%20and%20Redmine%20on%20Dreamhost" id="wpa2a_18"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2009/07/setting-up-ruby-rails-git-and-redmine-on-dreamhost.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Introducing Moozement</title>
		<link>http://www.ivankuznetsov.com/2009/03/introducing-moozement.html</link>
		<comments>http://www.ivankuznetsov.com/2009/03/introducing-moozement.html#comments</comments>
		<pubDate>Wed, 04 Mar 2009 22:10:25 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[HeiaHeia]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Social Networks]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Web/Tech]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=108</guid>
		<description><![CDATA[Last year I got involved in the development of a new social network &#8211; Moozement. There are plenty of social networks out there, there are even white label social networks. So why create another one? Jyri Engeström wrote some time ago about the case for object-centered sociality: &#8220;&#8216;social networking&#8217; makes little sense if we leave [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-112" title="moozement" src="http://www.ivankuznetsov.com/wp-content/uploads/moozement.jpg" alt="moozement" width="314" height="96" />Last year I got involved in the development of a new social network &#8211; <a href="http://www.moozement.com" target="_blank">Moozement</a>. There are <a href="http://en.wikipedia.org/wiki/List_of_social_networking_websites" target="_blank">plenty of social networks</a> out there, there are even <a href="http://www.ning.com" target="_blank">white label social networks</a>. So why create another one?</p>
<p><a href="http://www.zengestrom.com" target="_blank">Jyri Engeström</a> wrote some time ago about <a href="http://www.zengestrom.com/blog/2005/04/why_some_social.html" target="_blank">the case for object-centered sociality</a>: <em>&#8220;&#8216;social networking&#8217; makes little sense if we leave out the objects that mediate the ties between people&#8221;</em>. I could not agree with him more. The glue of each community is something that unites them &#8211; common interest, social object. When you join new social network, you typically start by building your social graph &#8211; re-establishing links to the real people you know, checking if they have already registered, inviting those whom you would like to see in the new environment. But there must be something beyond the initial phase of building the social graph. And this is the problem that haunts giants like Facebook and MySpace. You cannot possibly have common interest with everyone, and you don&#8217;t want to share the same things with everyone.</p>
<p><span id="more-108"></span>While Facebook is still growing strongly, it&#8217;s morphing into some sort of a generic social utility. Thanks to the <a href="http://developers.facebook.com/" target="_blank">Platform API</a> there are all kinds of applications available on <a href="http://www.facebook.com/apps/">Facebook</a>, some of them creating social objects (like <a href="http://www.facebook.com/apps/application.php?id=8278986302">Circle of Moms</a> or <a href="http://www.facebook.com/apps/application.php?id=2219089314">Cities I&#8217;ve Visited</a>), but it feels like true passions of people are quite rare in generic networks. When it comes to your most important hobbies, you might want to share your thoughts and data with other likeminded people and not necessarily with all aquaintances on Facebook. This is one of the reasons why specialized social networks are thriving. <a href="http://www.dogster.com" target="_blank">Dogster.com</a> and <a href="http://www.catster.com" target="_blank">catster.com</a> <a href="http://www.catster.com/" target="_blank"></a>are two perfect examples of such networks with very strong social objects. <a href="http://blog.pmarca.com/" target="_blank">Mark Andreesen</a>&#8216;s creation <a href="http://www.ning.com" target="_blank">Ning</a> &#8211; a place where everyone can build own social network &#8211; already has hundreds of thousands of networks.</p>
<div>Online sports services can be divided into at least three major categories:</div>
<div>
<div><strong>Well-being services</strong></p>
<p>There are plenty of online training log services promoting weight management, wellness, healthy lifestyle, sport and exercise. There are many good and innovative services in this segment, but they&#8217;re all somewhat serious by definition (in a good way) &#8211; you need to be on a program to make perfect use of them.</p></div>
<div class="im"><strong>Advanced sports services</strong></p>
<p>There are also some useful advanced sports services, provided by giants like <a href="http://nikeplus.nike.com" target="_blank">Nike</a><a href="http://nikeplus.nike.com/" target="_blank"></a>, <a href="https://www.polarpersonaltrainer.com/" target="_blank">Polar</a> and <a href="http://sportstracker.nokia.com" target="_blank">Nokia</a>. These services are great for automatically collecting data about your exercises and utilizing it in various ways. They are targeting enthusiasts, who typically use heart rate monitors, GPS devices, altimeters and other equipment to monitor their progress.</p>
<p><strong>Casual sports services</strong></p>
<p><strong></strong>I believe <a href="http://www.moozement.com">Moozement</a> established and defined this category &#8211; by combining social networking and online training logs in a casual way. It is so simple that anybody doing any kind of sports can use it and benefit from it. Simplicity and wide set of available sports sets it apart from all existing solutions. Moozement entry barrier is so low that you can literally connect to all your sporty friends. Moozement concentrates on the social aspect of physical activity, gives an opportunity to brag about your achievements, yet not taking it very seriously. You can log cycling 10km to work, or skiing 3km on Saturday afternoon, or even that you walked 50 stairs up the metro escalator. Every bit counts.</div>
<div>Moozement is targeting casual and amateur sportsmen and has already proven to be an excellent way to motivate people to exercise more because of the peer pressure. The buddy log on Moozement gives you an excellent overview on how you are doing compared to your friends this week (or month, or year). Sometimes it might look like comparing apples and oranges, but it is just for fun anyway. If you want to take it more seriously, it is possible to create a group &#8211; e.g. just for your friends who are into rollerblading &#8211; and compare results only in the group log.</p>
<div class="im">There are a lot of other nice features. E.g. <a href="http://apps.facebook.com/moozement/" target="_blank">Moozement Facebook application</a> allows you to put your ranking among your friends to your Facebook profile and put your exercises into your Facebook feed &#8211; to widen the circle of your bragging &#8211; while Facebook might be lacking passion, it sure has the numbers ; )</p>
<p>Let&#8217;s see where Moozement&#8217;s development curve will take it. For me it is a hobby project, but I can see a bright future in it.</p>
<p>Now I would encourage you to go to <a href="http://www.moozement.com/" target="_blank">http://www.moozement.com</a> and check it out for yourself. All feedback is welcome &#8211; I will make sure that it reaches developers.</div>
</div>
</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.ivankuznetsov.com%2F2009%2F03%2Fintroducing-moozement.html&amp;title=Introducing%20Moozement" id="wpa2a_20"><img src="http://www.ivankuznetsov.com/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.ivankuznetsov.com/2009/03/introducing-moozement.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

