<?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</title>
	<atom:link href="http://www.ivankuznetsov.com/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>REE segfaults when Rails application has too many localisation files</title>
		<link>http://www.ivankuznetsov.com/2011/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html</link>
		<comments>http://www.ivankuznetsov.com/2011/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html#comments</comments>
		<pubDate>Fri, 01 Jul 2011 22:03:56 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=349</guid>
		<description><![CDATA[We ran into an interesting problem &#8211; at some point of time our Rails application started to fail occaionally because of REE segfaults on startup. Even starting the console with &#8216;script/console production&#8217; was occasionally failing with REE segfault. Application was growing, new features were added and segfaults started happening more and more often. There was [...]]]></description>
			<content:encoded><![CDATA[<p>We ran into an interesting problem &#8211; at some point of time our Rails application started to fail occaionally because of REE segfaults on startup. Even starting the console with &#8216;script/console production&#8217; was occasionally failing with REE segfault. Application was growing, new features were added and segfaults started happening more and more often. There was no one single place where crashes occurred, so there was no clear understanding how to tackle this problem.</p>
<p>Examples of crashes we observed:</p>
<pre>/vendor/rails/actionpack/lib/action_controller/routing/route.rb:205):2:
   [BUG] Segmentation fault
/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/1.8/yaml.rb:133:
   [BUG] Segmentation fault
/vendor/rails/activesupport/lib/active_support/vendor/i18n-0.3.7/i18n/
   backend/base.rb:257: [BUG] Segmentation fault
/vendor/rails/actionpack/lib/action_view/template.rb:226: [BUG] Segmentation fault
/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/pauldix-sax-machine-0.0.14/
   lib/sax-machine/sax_document.rb:30: [BUG] Segmentation fault
/vendor/rails/activesupport/lib/active_support/memoizable.rb:32: [BUG] Segmentation fault</pre>
<p>After banging my head against the wall for a week I found a solution (even two) and what might seem to be a likely reason for the segfaults. Two &#8220;suspects&#8221; &#8211; lack of available memory and incorrect version of libxml were ruled out. What seems to be the actual reason is the total size of the localisation files in config/locales loaded upon startup:</p>
<pre>$ du -shb config/locales
1665858    config/locales</pre>
<pre>$ cd config/locales
$ find . -type f | wc -l
805</pre>
<p>So ~1.6Mb in 805 files give occasional segfaults. Adding 200Kb of localisation files more started giving 100% segfaults on script/console startup.</p>
<p>Now I&#8217;ve found two workarounds for this problem.</p>
<p>1. Recompile REE with &#8211;no-tcmalloc flag</p>
<pre>./ruby-enterprise-1.8.7-2011.03/installer --no-tcmalloc</pre>
<p>Note that on 64-bit platforms tcmalloc is disabled by default.</p>
<p>2. Enable large pages feature in tcmalloc</p>
<p>This is described in <a href="http://google-perftools.googlecode.com/svn/tags/perftools-1.6/INSTALL" target="_blank">tcmalloc documentation</a> as: &#8220;Internally, tcmalloc divides its memory into &#8220;pages.&#8221;  The default page size is chosen to minimize memory use by reducing fragmentation. The cost is that keeping track of these pages can cost tcmalloc time. We&#8217;ve added a new, experimental flag to tcmalloc that enables a larger page size.  In general, this will increase the memory needs of applications using tcmalloc.  However, in many cases it will speed up the applications as well, particularly if they allocate and free a lot of memory.  We&#8217;ve seen average speedups of 3-5% on Google applications.&#8221;</p>
<p>There&#8217;s a warning &#8211; &#8220;this feature is still very experimental&#8221;, but it works to solve the problem with too many localisation files.</p>
<p>To compile REE with tcmalloc with large pages enables I just edited ruby-enterprise-1.8.7-2011.03/source/distro/google-perftools-1.7/src/common.h &#8211; replaced</p>
<pre>#if defined(TCMALLOC_LARGE_PAGES)
static const size_t kPageShift  = 15;
static const size_t kNumClasses = 95;
static const size_t kMaxThreadCacheSize = 4 &lt;&lt; 20;
#else
static const size_t kPageShift  = 12;
static const size_t kNumClasses = 61;
static const size_t kMaxThreadCacheSize = 2 &lt;&lt; 20;
#endif</pre>
<p>with</p>
<pre>static const size_t kPageShift  = 15;
static const size_t kNumClasses = 95;
static const size_t kMaxThreadCacheSize = 4 &lt;&lt; 20;</pre>
<p>On production servers I opted for no tcmalloc for now &#8211; but I hope there&#8217;ll be a <a href="http://code.google.com/p/rubyenterpriseedition/issues/detail?id=73" target="_blank">better way to deal with this issue</a> soon.</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%2F07%2Free-segfaults-when-rails-application-has-too-many-localisation-files.html&amp;title=REE%20segfaults%20when%20Rails%20application%20has%20too%20many%20localisation%20files" 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/07/ree-segfaults-when-rails-application-has-too-many-localisation-files.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pitfalls of Rails fragment caching with memcached</title>
		<link>http://www.ivankuznetsov.com/2011/06/pitfalls-of-rails-fragment-caching-with-memcached.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/pitfalls-of-rails-fragment-caching-with-memcached.html#comments</comments>
		<pubDate>Wed, 29 Jun 2011 15:52:36 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=319</guid>
		<description><![CDATA[Fragment caching is a powerful technique for improving performance of your web application. Rails site describes in detail how to apply this technique. Rails are providing developers with really excellent abstractions, but it&#8217;s always good to know what&#8217;s under the hood and how it all works. There are a few things that might potentially cause [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-356" title="300px-Ruby_on_Rails_logo" src="http://www.ivankuznetsov.com/wp-content/uploads/300px-Ruby_on_Rails_logo.jpg" alt="" width="150" />Fragment caching is a powerful technique for improving performance of your web application. Rails site <a href="http://guides.rubyonrails.org/caching_with_rails.html#fragment-caching" target="_blank">describes in detail</a> how to apply this technique.</p>
<p>Rails are providing developers with really excellent abstractions, but it&#8217;s always good to know what&#8217;s under the hood and how it all works.</p>
<p>There are a few things that might potentially cause bugs in your code, or waste your time (speaking from my own experience). So here goes:</p>
<p>1. Beware of globally keyed fragments</p>
<p>Let&#8217;s take example from Rails tutorial:</p>
<pre>&lt;% cache do %&gt;
  All available products:
  &lt;% Product.all.each do |p| %&gt;
    &lt;%= link_to p.name, product_url(p) %&gt;
  &lt;% end %&gt;
&lt;% end %&gt;</pre>
<p>Now if you need to deal with a multi-language site you might want to make cache fragment language dependent. What might seem a convenient solution:</p>
<pre>&lt;%- cache([user.locale.to_s]) do -%&gt;</pre>
<p>will turn into a source of very interesting problems. While calling the cache method without parameters will automatically create a controller/action specific cache key, calling it with a key will make this fragment a globally keyed fragment. Cache key in the first case is going to look like &#8220;views/localhost:3000/controller-name&#8221;, and in the other case &#8220;views/en&#8221; &#8211; this is not as unique identifier any more.</p>
<p>While automatic cache key naming provided by rails is very convenient, it is very easy to run into a problem with duplicate cache key names used in different places.</p>
<p>2. Another pitfall of automatic cache key naming is that you shall never assume that when creating a cache with global key you can later find it using e.g. <a href="http://lzone.de/articles/memcached.htm" target="_blank">telnet interface</a> to memcache. Example &#8211; add</p>
<pre>&lt;%- cache('unique_cache_key') do -%&gt;
&lt;%- end -%&gt;</pre>
<p>in your view and then try to read directly from memcache:</p>
<pre>$ telnet localhost 11211
GET unique_cache_key
END</pre>
<p>At the same time</p>
<pre>GET views/unique_cache_key</pre>
<p>will work. It&#8217;s easy to make this mistake trying to check or delete cache keys directly from memcache when using Rails cache methods.</p>
<p>3. delete_matched is not supported by memcached (see rails/activesupport/lib/active_support/cache/mem_cache_store.rb)</p>
<p>In practice that means that if you&#8217;re using memcached as Rails cache engine and trying to delete or expire fragment cache using standard Rails methods and regexp &#8211; you&#8217;ll fail.</p>
<p>expire_fragment(/base\/xyz.*/)</p>
<p>will fail miserably. Ideal solution is not to use explicit cache expiration, but rather create cache keys in such a way that doesn&#8217;t require expiration. Alternatively it&#8217;s possible to use <a href="https://github.com/jkassemi/memcache-store-extensions" target="_blank">extensions</a> implementing delete_matched for memcached (haven&#8217;t tried it myself though).</p>
<p><em>Tip: one very useful tool for checking memcached is <a href="https://github.com/fauna/peep" target="_blank">peep</a> by Evan Weaver &#8211; allows you to peek into the cache and see what&#8217;s really cached and how it is used.</em></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%2Fpitfalls-of-rails-fragment-caching-with-memcached.html&amp;title=Pitfalls%20of%20Rails%20fragment%20caching%20with%20memcached" 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/pitfalls-of-rails-fragment-caching-with-memcached.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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_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/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_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/2011/06/vim-is-the-best-editor-also-for-ror-development.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Installing Flash player browser plugin in 64-bit Ubuntu 11.04</title>
		<link>http://www.ivankuznetsov.com/2011/06/installing-flash-player-browser-plugin-in-64-bit-ubuntu-11-04.html</link>
		<comments>http://www.ivankuznetsov.com/2011/06/installing-flash-player-browser-plugin-in-64-bit-ubuntu-11-04.html#comments</comments>
		<pubDate>Wed, 15 Jun 2011 09:30:48 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=322</guid>
		<description><![CDATA[I got a new hard drive for my laptop and decided to make a leap of faith and move to 64-bit version of Ubuntu, since I had to install a fresh system anyway. In case you didn&#8217;t know &#8211; Adobe doesn&#8217;t have stable Flash player version for 64-bit Linux. Adobe Labs offer preview release codenamed [...]]]></description>
			<content:encoded><![CDATA[<p>I got a new hard drive for my laptop and decided to make a leap of faith and move to 64-bit version of Ubuntu, since I had to install a fresh system anyway.</p>
<p>In case you didn&#8217;t know &#8211; Adobe doesn&#8217;t have stable Flash player version for 64-bit Linux. Adobe Labs offer <a href="http://labs.adobe.com/technologies/flashplayer10/square/">preview release codenamed &#8220;Square&#8221;</a> for 64-bit platforms. It can&#8217;t be installed via standard Ubuntu repositories, so get ready to get your hands dirty in the terminal.</p>
<p>To install 64-bit Flash player plugin do the following:</p>
<p>1. Download the latest version of the plugin at <a href="http://labs.adobe.com/downloads/flashplayer10_square.html" target="_blank">http://labs.adobe.com/downloads/flashplayer10_square.html</a> (currently it is v.10.2 preview 3 from November 30th, 2010)<br />
2. Go to your downloads directory and extract the plugin binary</p>
<pre>tar xvzf flashplayer10_2_p3_64bit_linux_111710.tar.gz</pre>
<p>3. Create a directory for browser plugins in your users home directory</p>
<pre>mkdir -p ~/.mozilla/plugins</pre>
<p>4. Move extracted in step 2 Flash player plugin binary to its new location</p>
<pre>mv libflashplayer.so ~/.mozilla/plugins</pre>
<p>5. Close all browser windows and restart the browser.</p>
<p>6. In Firefox or Chrome go to about:plugins to verify that there&#8217;s Shockwave Flash plugin available</p>
<p>&nbsp;</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%2Finstalling-flash-player-browser-plugin-in-64-bit-ubuntu-11-04.html&amp;title=Installing%20Flash%20player%20browser%20plugin%20in%2064-bit%20Ubuntu%2011.04" 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/2011/06/installing-flash-player-browser-plugin-in-64-bit-ubuntu-11-04.html/feed</wfw:commentRss>
		<slash:comments>3</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_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/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_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/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_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/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_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/2010/05/moving-joomla-wordpress-and-other-phpfastcgi-apps-to-nginx.html/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Setting up your own git server on Ubuntu</title>
		<link>http://www.ivankuznetsov.com/2010/05/setting-up-your-own-git-server-on-ubuntu.html</link>
		<comments>http://www.ivankuznetsov.com/2010/05/setting-up-your-own-git-server-on-ubuntu.html#comments</comments>
		<pubDate>Thu, 13 May 2010 12:39:00 +0000</pubDate>
		<dc:creator>Ivan Kuznetsov</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[gitosis]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://www.ivankuznetsov.com/?p=262</guid>
		<description><![CDATA[This will create a new user &#8216;gitosis&#8217; and prepare a structure for repositories in /srv/gitosis. Now let&#8217;s initialize a gitosis-admin repo &#8211; it is used for managing repositories and access Of course there&#8217;s always an option to use github. And if you&#8217;re working on an open source project, or want to concentrate on coding and [...]]]></description>
			<content:encoded><![CDATA[<p>This will create a new user &#8216;gitosis&#8217; and prepare a structure for repositories in /srv/gitosis. Now let&#8217;s initialize a gitosis-admin repo &#8211; it is used for managing repositories and access<img class="alignleft size-full wp-image-261" title="git-logo" src="http://www.ivankuznetsov.com/wp-content/uploads/git-logo.png" alt="" width="97" height="188" /></p>
<p>Of course there&#8217;s always an option to use <a href="http://www.github.com" target="_blank">github</a>. And if you&#8217;re working on an open source project, or want to concentrate on coding and not system administration, github is a lot better option than setting up and managing your own git server (I&#8217;ve been so impressed by <a href="http://twitter.com/defunkt" target="_blank">@defunkt</a>&#8216;s presentation on <a href="http://www.frozenrails.eu" target="_blank">#frozenrails</a>, that started recommending github to everyone <img src='http://www.ivankuznetsov.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  But if you already pay for a virtual machine somewhere (like <a href="http://www.linode.com" target="_blank">Linode</a>), then setting up your own git server might be a viable option, especially that it is sooo easy.</p>
<p>The following instructions have been verified on Ubuntu 10.04 Lucid Lynx, but should work at least on Ubuntu 9.04 and 9.10 just as well.</p>
<p><span id="more-262"></span></p>
<p>Let&#8217;s start with installing gitosis itself. Issue the following command on the server:</p>
<pre>sudo apt-get install gitosis</pre>
<p>This will create a new user &#8216;gitosis&#8217; and prepare a structure for repositories in /srv/gitosis. Now let&#8217;s initialize a gitosis-admin repo &#8211; it is used for managing repositories and access rights.</p>
<pre>sudo -H -u gitosis gitosis-init &lt; ~/tmp/my_public.key</pre>
<p>You need to have a public key for accessing it. If you don&#8217;t have one yet, you can use</p>
<pre><code>ssh-keygen -t rsa</code></pre>
<p>command on your local machine to generate public/private key pair. Copy public key to the server before initializing gitosis-admin repository.</p>
<p>Now with gitosis-admin repo initialized on the server &#8211; let&#8217;s clone it to the local computer.</p>
<pre>git clone gitosis@myserver.com:gitosis-admin.git</pre>
<p>If you see an error like:</p>
<pre>Permission denied (publickey).
fatal: The remote end hung up unexpectedly</pre>
<p>That is most likely because you restricted access to you server via ssh to only certain users, and gitosis is not one of them. Edit /etc/ssh/sshd_config, find AllowUsers line and add gitosis to the list.</p>
<p>Now that you have successfully cloned gitosis-admin repo to your local computer, you can add  new users and new repositories.</p>
<p>To add new repository, edit gitosis.conf and add lines like:</p>
<pre>[group myrepo]
writable = myrepo
members = user@computer</pre>
<p>After that commit and push the changes to gitosis-admin project:</p>
<pre>git commit -a -m "Added myrepo repository"</pre>
<p>Now you can clone this new repository to your local machine (note .git added to the name of the repository):</p>
<pre>git clone gitosis@mygitserver.com:myrepo.git</pre>
<p>To allow new user to access your repository, get this user&#8217;s public key, copy it to gitosis-admin/keydir as newuser@computer.pub, then edit gitosis.conf and add newuser@computer (without .pub) to the list of members:</p>
<pre>[group myrepo]
writable = myrepo
members = user@computer newuser@computer</pre>
<p>Now add new files and commit and push changes to git server (make sure you really add all files and don&#8217;t forget to push &#8211; these are quite common mistakes when adding new users).</p>
<pre>git add .
git commit -m "Added user newuser"
git push</pre>
<p>With a freshly cloned empty repository you&#8217;ll need to add you first files, do a commit and push origin master:</p>
<pre>vim README.txt
git commit -a -m "Added readme"
git push origin master</pre>
<p>Now you can git pull and git push as much as you like.</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%2F05%2Fsetting-up-your-own-git-server-on-ubuntu.html&amp;title=Setting%20up%20your%20own%20git%20server%20on%20Ubuntu" 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/2010/05/setting-up-your-own-git-server-on-ubuntu.html/feed</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
	</channel>
</rss>

