<?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>geek# &#187; Linux</title>
	<atom:link href="http://geeksharp.com/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://geeksharp.com</link>
	<description>techno-babble for the masses</description>
	<lastBuildDate>Thu, 27 May 2010 14:57:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mercurial Web with FastCGI &amp; Nginx</title>
		<link>http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/</link>
		<comments>http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 01:29:07 +0000</pubDate>
		<dc:creator>Scott Anderson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mercurial]]></category>
		<category><![CDATA[Source Control]]></category>

		<guid isPermaLink="false">http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/</guid>
		<description><![CDATA[So I’ve finally decided to make the switch to a distributed source control system.&#160; The benefits are well-documented, and I&#8217;ve grown weary of Subversion.&#160; After some research, I decided Mercurial would be best for me.&#160; Since I have OCD, and I wanted to push via HTTP to my remote repository, I did some homework and [...]]]></description>
			<content:encoded><![CDATA[<p>So I’ve finally decided to make the switch to a distributed source control system.&#160; The benefits are well-documented, and I&#8217;ve grown weary of Subversion.&#160; After some research, I decided Mercurial would be best for me.&#160; Since I have OCD, and I wanted to push via HTTP to my remote repository, I did some homework and figured out how to get everything running on my VPS.&#160; If you’d like to see how I did it, read on.</p>
<h4>Step 1:&#160; Prerequisites</h4>
<p>Since my VPS runs Ubuntu Linux 9.10, there are a few packages to install before we get started.&#160; Run the following command to install them:</p>
<pre class="brush: plain;">sudo apt-get install python-setuptools acl python-dev spawn-fcgi</pre>
<p>Now you need to make sure your main partition has the acl system enabled in /etc/fstab.&#160; Modify the partition options to look something like this:</p>
<pre class="brush: plain;"># /etc/fstab: static file system information.
#
# &lt;file system&gt; &lt;mount point&gt;   &lt;type&gt;  &lt;options&gt;       &lt;dump&gt;  &lt;pass&gt;
proc            /proc           proc    defaults        0       0
/dev/xvda       /               ext3    noatime,errors=remount-ro,acl 0       1
/dev/xvdb       none            swap    sw              0       0</pre>
<p>Pay attention to that <b>acl</b> option in the default partition above.&#160; Now you can just remount the partition:</p>
<pre class="brush: plain;">sudo mount -o remount,acl /</pre>
<h4>Step 2:&#160; Install Mercurial and flup</h4>
<p>Mercurial is obvious, but flup might be new to you.&#160; Flup is a python module that allows us to create a WSGI server to host the repositories.</p>
<pre class="brush: plain;">sudo easy_install mercurial
sudo easy_install flup</pre>
<h4>Step 3:&#160; Create a user account to hold your repositories</h4>
<p>I prefer to place my repositories underneath a normal user account and then add www-data and myself to the group.&#160; Here are the commands to set it all up:</p>
<pre class="brush: plain;">sudo /usr/sbin/groupadd hg
sudo /usr/sbin/useradd -g hg -s /bin/false hg
sudo mkdir /var/hg
sudo chown hg:hg /var/hg
sudo /usr/sbin/usermod -G hg www-data
sudo /usr/sbin/usermod -G hg scott</pre>
<p>The next part deserves a little bit of explaining.&#160; Basically the whole /var/hg folder should be owned by the group <strong>hg</strong> that we just created.&#160; But what we need to ensure three things.&#160; First, the hg group should have write permissions to the root folder.&#160; Second, we need to make sure that any new files created under this folder will belong to the group <strong>hg</strong> also.&#160; And third, we need to make sure that the default permissions for this folder are read/write for the owner and the group.&#160; These two commands will ensure each of these rules is followed, which is why we added the <strong>acl</strong> package earlier and remounted the main filesystem.</p>
<p>I’m sure there are other ways to accomplish this (like running Nginx and the FastCGI process as the <strong>hg</strong> user), but this is the method I prefer, and it saves a lot of headaches down the road dealing with why a push won’t go.&#160; So here are the three commands you need to execute:</p>
<pre class="brush: plain;">sudo chmod -R g+rwxs,o+rx /var/hg
sudo setfacl -R -m d:u::rwx,d:g::rwx,d:m:rwx,d:o:r-x /var/hg</pre>
<h4>Step 4:&#160; Create the hgwebdir.cgi script</h4>
<p>This script is used to serve the incoming requests for the FastCGI interface, mine is <strong>/opt/hg-fastcgi/hgwebdir.fcgi</strong></p>
<pre class="brush: plain;">#!/usr/bin/env python
#
# An example CGI script to export multiple hgweb repos, edit as necessary

# adjust python path if not a system-wide install:
#import sys
#sys.path.insert(0, "/path/to/python/lib")

# enable demandloading to reduce startup time
from mercurial import demandimport; demandimport.enable()

# Uncomment to send python tracebacks to the browser if an error occurs:
#import cgitb
#cgitb.enable()

# If you'd like to serve pages with UTF-8 instead of your default
# locale charset, you can do so by uncommenting the following lines.
# Note that this will cause your .hgrc files to be interpreted in
# UTF-8 and all your repo files to be displayed using UTF-8.
#
#import os
#os.environ["HGENCODING"] = "UTF-8"

from mercurial.hgweb.hgwebdir_mod import hgwebdir
from flup.server.fcgi import WSGIServer

# The config file looks like this.  You can have paths to individual
# repos, collections of repos in a directory tree, or both.
#
# [paths]
# virtual/path1 = /real/path1
# virtual/path2 = /real/path2
# virtual/root = /real/root/*
# / = /real/root2/*
#
# [collections]
# /prefix/to/strip/off = /root/of/tree/full/of/repos
#
# paths example:
#
# * First two lines mount one repository into one virtual path, like
# '/real/path1' into 'virtual/path1'.
#
# * The third entry tells every mercurial repository found in
# '/real/root', recursively, should be mounted in 'virtual/root'. This
# format is preferred over the [collections] one, using absolute paths
# as configuration keys is not supported on every platform (including
# Windows).
#
# * The last entry is a special case mounting all repositories in
# '/real/root2' in the root of the virtual directory.
#
# collections example: say directory tree /foo contains repos /foo/bar,
# /foo/quux/baz.  Give this config section:
#   [collections]
#   /foo = /foo
# Then repos will list as bar and quux/baz.
#
# Alternatively you can pass a list of ('virtual/path', '/real/path') tuples
# or use a dictionary with entries like 'virtual/path': '/real/path'

WSGIServer(hgwebdir('/var/hg/hgweb.config')).run()</pre>
<p>Make sure you set this script as executable with the following command:</p>
<pre class="brush: plain;">chmod +x /opt/hg-fastcgi/hgwebdir.fcgi</pre>
<h4>Step 5:&#160; Create the Mercurial hgweb.config</h4>
<p>There’s a simple INI-style config file we have to create.&#160; I called mine <strong>/var/hg/hgweb.config</strong>.&#160; If you decide to place yours elsewhere, you need to modify the last line of the <strong>hgwebdir.fcgi</strong> script you created in step 4.</p>
<pre class="brush: plain;">[web]
baseurl = /
allow_push = *
push_ssl = false

[collections]
/var/hg = /var/hg</pre>
<h4>Step 6:&#160; Create the FastCGI init.d script</h4>
<p>This script will not only handle starting and stopping your FastCGI process for Mercurial; it will also handle restarting the service on reboot.&#160; Make sure you save this as <strong>/etc/init.d/fcgi-hg.</strong></p>
<pre class="brush: plain;">#! /bin/sh
#
# fcgi-hg     Startup script for the nginx HTTP Server
#
# chkconfig: - 84 15
# description: Loading php-cgi using spawn-cgi
#	       HTML files and CGI.
#
# Author:  Ryan Norbauer &lt;ryan.norbauer@gmail.com&gt;
# Modified:     Geoffrey Grosenbach http://topfunky.com
# Modified:     David Krmpotic http://davidhq.com
# Modified:	Kun Xi http://kunxi.org
PATH=/opt/python/bin:$PATH
DAEMON=/usr/bin/spawn-fcgi
FCGIHOST=127.0.0.1
FCGIPORT=9003
FCGIUSER=www-data
FCGIGROUP=www-data
FCGIAPP=/opt/hg-fastcgi/hgwebdir.fcgi
PIDFILE=/var/run/fcgi-hg.pid
DESC="HG in FastCGI mode"

# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0
test -x $FCGIAPP || exit 0

start() {
	$DAEMON -a $FCGIHOST -p $FCGIPORT -u $FCGIUSER -g $FCGIGROUP -f $FCGIAPP -P $PIDFILE 2> /dev/null || echo -en "\n already running"
}

stop() {
	kill -QUIT `cat $PIDFILE` || echo -en "\n not running"
}

restart() {
	kill -HUP `cat $PIDFILE` || echo -en "\n can't reload"
}

case "$1" in
  start)
    echo -n "Starting $DESC: "
    start
  ;;
  stop)
    echo -n "Stopping $DESC: "
    stop
  ;;
  restart|reload)
    echo -n "Restarting $DESC: "
    stop
    # One second might not be time enough for a daemon to stop,
    # if this happens, d_start will fail (and dpkg will break if
    # the package is being upgraded). Change the timeout if needed
    # be, or change d_stop to have start-stop-daemon use --retry.
    # Notice that using --retry slows down the shutdown process somewhat.
    sleep 1
    start
  ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&#038;2
    exit 3
  ;;
esac

exit $?</pre>
<p>Now you need to update the rc.d directories so this service will start when you reboot your box.&#160; This simple command will do it for you:</p>
<pre class="brush: plain;">update-rc.d fcgi-hg defaults</pre>
<p>Now you’ll be able to start and stop your service like this:</p>
<pre class="brush: plain;">/etc/init.d/fcgi-hg start
/etc/init.d/fcgi-hg stop
/etc/init.d/fcgi-hg restart</pre>
<h4>Step 7:&#160; Create hguser.config for user setup</h4>
<p>I prefer not to keep my repositories open to everyone (for obvious reasons) so we need to create an htpasswd-style user configuration file.&#160; Note that since this will be used for <strong>basic</strong> authentication, credentials will be sent in plain text.&#160; If that matters to you, then you should configure your Nginx install to use SSL, but this is outside the scope of this article.&#160; Anyway, onward.&#160; You should put this file at <strong>/var/hg/hguser.config</strong></p>
<pre class="brush: plain;"># Format &lt;user&gt;:&lt;encrypted-password&gt;:&lt;comment&gt;
scott:myencryptedpassword:Scott Anderson</pre>
<p>Obviously you need to replace the username with your username, and the password with an appropriately encrypted value.&#160; If you have Ruby installed, this is easy, just launch <strong>irb</strong> and type the following command:</p>
<pre class="brush: plain;">&quot;password&quot;.crypt(&quot;salt&quot;)</pre>
<p>Copy the encrypted value into the file and you’re all set.</p>
<h4>Step 8:&#160; Modify your Nginx configuration</h4>
<p>There are about 100 ways to setup websites in Nginx, so I’ll assume you know where to place server sections.&#160; If you followed my previous tutorial, this will be in a file something like <strong>/usr/local/nginx/sites-enabled/geeksharp.com</strong>.&#160; The block should look something like this:</p>
<pre class="brush: plain;">server {
    listen 80;
    server_name dev.geeksharp.com;
    root /var/hg/;
    gzip on;

    location / {
        include fastcgi_params;
        fastcgi_pass 127.0.0.1:9003;
        fastcgi_param DOCUMENT_ROOT /var/hg/;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_param REQUEST_METHOD $request_method;
        fastcgi_param CONTENT_TYPE $content_type;
        fastcgi_param CONTENT_LENGTH $content_length;
        fastcgi_param SCRIPT_FILENAME /opt/hg-fastcgi/hgwebdir.fcgi;
        auth_basic 'geek# Source Control';
        auth_basic_user_file /var/hg/hgusers.config;
    }
}</pre>
<p>That’s it!&#160; You can edit all these miscellaneous files to suit your needs.&#160; If you did everything correctly, all you need to do is start the <strong>fcgi-hg</strong> script and then restart nginx.&#160; When you want to create a new repository, you should create it in <strong>/var/hg</strong> like so:</p>
<pre class="brush: plain;">hg init /var/hg/project</pre>
<p>Once you get everything running and you create a few repositories, you should see something like this:</p>
<p><a href="http://geeksharp.com/wp-content/uploads/2010/01/mercrepos.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="merc-repos" border="0" alt="merc-repos" src="http://geeksharp.com/wp-content/uploads/2010/01/mercrepos_thumb.png" width="636" height="294" /></a> </p>
<p>Hope this helps someone out there.&#160; If you have questions, or something doesn’t work, let me know and I try and help you out.&#160; Good luck! <img src='http://geeksharp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://geeksharp.com/2010/01/20/mercurial-web-with-fastcgi-nginx/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nginx and Rails and PHP, Oh My!</title>
		<link>http://geeksharp.com/2009/12/09/nginx-and-rails-and-php-oh-my/</link>
		<comments>http://geeksharp.com/2009/12/09/nginx-and-rails-and-php-oh-my/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 05:45:14 +0000</pubDate>
		<dc:creator>Scott Anderson</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Nginx]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://geeksharp.com/?p=39</guid>
		<description><![CDATA[As you could probably guess, my blog (and several sites of my friends) are hosted on a lovely Linux VPS provided by Linode.  I honestly can’t say enough nice things about the service and reliability I’ve received from Linode (and no they don’t pay me to speak highly of them!).  But that’s not really the [...]]]></description>
			<content:encoded><![CDATA[<p>As you could probably guess, my blog (and several sites of my friends) are hosted on a lovely Linux VPS provided by <a href="http://www.linode.com/" target="_blank">Linode</a>.  I honestly can’t say enough nice things about the service and reliability I’ve received from Linode (and no they don’t pay me to speak highly of them!).  But that’s not really the point of this post.  The point is actually quite simple:  My VPS doesn’t have a lot of memory, and I’m always wary of my resource consumption.  A few months ago, I moved from <a href="http://www.apache.org/" target="_blank">Apache</a> to <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a> for this reason, alone.  Let’s face it… Apache is a memory hog, and that problem is well-documented, so I won’t really go into details here.  “Lighty” has served me well for the past few months, but for reasons I’m about to explain, I felt the need to move to a different platform.</p>
<p>So earlier this year I wrote a post about how I wanted to learn <a href="http://rubyonrails.org/" target="_blank">Ruby on Rails</a>.  For a while now, I’ve put that project on the back burner.  I decided after my last post on the subject that <a href="http://www.asp.net/mvc/" target="_blank">ASP.NET MVC</a> was more fitting for me because, let’s face it, I’m a .NET developer right?  And aren’t .NET developers supposed to stick with .NET stuff?  After deploying my first site using ASP.NET MVC, I came away with a feeling that it was a little heavier than I’d like it to be, and I really don’t like paying for another separate Windows VPS just to host one website!  There’s also the fact that Linux is way more efficient in limited resource deployments (like VPS’s).  All of this boils down to the fact that Rails called to me once again, and I decided that if I was going to do Rails development, I needed to figure out the deployment environment.</p>
<p>After doing some research, <a href="http://www.rubyenterpriseedition.com/" target="_blank">Ruby Enterprise Edition</a> and <a href="http://www.modrails.com/" target="_blank">Phusion Passenger</a> seemed like the obvious choice for production Rails deployment.  Both products value resource management in environments just like mine, and the numbers they claim to achieve were very impressive!  If you want to run Phusion Passenger, however, your choices in a web server are limited to Apache or <a href="http://nginx.net/" target="_blank">Nginx</a>.  Considering my previous encounters with Apache, I decided Nginx was the way to go.  That said, after hours of fussing getting this environment set up properly, I decided that it would be best if I contributed a guide to the community.  This wasn’t the easiest process in the world, and I hope this tutorial can help someone else avoid the headaches that I faced.</p>
<h4>Step 1: Environment and pre-requisites</h4>
<p>First and foremost, I use a 32-bit version of Ubuntu 9.10 Karmic Koala on my VPS.  the instructions you see are specific to my environment, but I’m sure they could be adapted for use in others.  On my server, there were some packages that were necessary pre-requisites.  Here are the steps to install them:</p>
<p>First, edit your /etc/apt/sources.list and remove the comment marks (#) in front of the universe repository lines</p>
<pre class="brush: plain;">deb http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic universe
deb http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe
deb-src http://us.archive.ubuntu.com/ubuntu/ karmic-updates universe
deb http://security.ubuntu.com/ubuntu karmic-security universe
deb-src http://security.ubuntu.com/ubuntu karmic-security universe</pre>
<p>Next you need to issue the following commands to get all the rest of the packages you need:</p>
<pre class="brush: plain;">sudo apt-get update
sudo apt-get install build-essential libxml2-dev libssl-dev libbz2-dev curl libcurl4-openssl-dev libpng12-dev libmcrypt-dev mysql-server libmysqlclient-dev libxslt1-dev autoconf2.13 libltdl-dev libreadline5-dev libsqlite3-ruby postgresql-server-dev-8.4 libpcre3-dev</pre>
<p>Next you need to install libevent.  There is a version of this in the repository, but it&#8217;s pretty out of date, and PHP-FPM prefers the newer version.  For this requirement, I decided to compile from source.  Use the following commands to get this installed.</p>
<pre class="brush: plain;">wget http://monkey.org/~provos/libevent-1.4.13-stable.tar.gz
cd libevent-1.4.13-stable
./configure
make &amp;&amp; sudo make install</pre>
<h4>Step 2: Compiling PHP  from source with Suhosin and PHP-FPM</h4>
<p>So the reason I decided to compile PHP from source is because it&#8217;s the easiest way (for me) to apply the PHP-FPM patch and make sure I have everything I need.  I realize that there may be some Ubuntu packages out there at some point, but there weren&#8217;t any that were easily found when I performed these steps.  That said, our first step is to snag the PHP source and then apply the Suhosin patch.</p>
<pre class="brush: plain;">wget http://us2.php.net/get/php-5.3.1.tar.bz2/from/this/mirror
bzip2 -dc php-5.3.1.tar.bz2 | tar xf -
wget http://download.suhosin.org/suhosin-patch-5.3.1-0.9.8.patch.gz
gunzip suhosin-patch-5.3.1-0.9.8.patch.gz
patch -d php-5.3.1 -p1 &lt; suhosin-patch-5.3.1-0.9.8.patch</pre>
<p>Now we have to install the PHP-FPM patch.  In order to do this, we actually need a legacy version of autoconf and autoheader, because the PHP buildconf script relies on them.  Luckily, they were installed earlier when we grabbed stuff from the Ubuntu repositories.  All we have to do is set some environment variables to force the legacy versions to be used.  Then we can just apply the patch and compile PHP.</p>
<pre class="brush: plain;">export PHP_AUTOCONF=/usr/bin/autoconf2.13
export PHP_AUTOHEADER=/usr/bin/autoheader2.13
wget http://launchpad.net/php-fpm/master/0.6/+download/php-fpm-0.6~5.3.1.tar.gz
tar -zxf php-fpm-0.6~5.3.1.tar.gz
php-fpm-0.6-5.3.1/generate-fpm-patch
patch -d php-5.3.1 -p1 &lt; fpm.patch
cd php-5.3.1
./buildconf --force
./configure --enable-bcmath --with-bz2 --enable-calendar --with-fpm --with-libevent=shared --with-curl --enable-dba --enable-exif --enable-ftp --with-gd --with-gettext --enable-mbstring --with-mysql --with-mysqli --with-pdo-mysql --with-openssl --with-pcre-regex --enable-shmop --enable-soap --enable-sockets --enable-sysvmsg --enable-wddx --enable-zip --with-zlib --enable-sysvsem --enable-sysvshm --with-mcrypt --enable-pcntl --enable-mbregex --with-mhash --with-xsl
sudo make all install</pre>
<h4>Step 3: Compiling Ruby Enterprise Edition and Nginx</h4>
<p>Now that PHP-FPM is installed, we need to get Nginx up and running.  The good part is that Ruby Enterprise Edition comes bundled with Phusion Passenger which will handle compiling Nginx for us.  We do, however, need to download the Nginx source manually because there are some options that we&#8217;d like to pass to the Nginx configure script.</p>
<pre class="brush: plain;">cd ..
wget http://sysoev.ru/nginx/nginx-0.7.64.tar.gz
tar -zxf nginx-0.7.64.tar.gz
wget http://rubyforge.org/frs/download.php/66162/ruby-enterprise-1.8.7-2009.10.tar.gz
tar -zxf ruby-enterprise-1.8.7-2009.10.tar.gz
sudo ruby-enterprise-1.8.7-2009.10/installer</pre>
<p>The cool part about Ruby Enterprise Edition is that it&#8217;s completely isolated from the rest of your system, and it installs most of the default gems for you.  As a matter of fact, the only thing left to do is to actually install Nginx with Phusion Passenger support, and that&#8217;s exactly what we&#8217;re doing next!</p>
<pre class="brush: plain;">sudo /opt/ruby-enterprise-1.8.7-2009.10/bin/passenger-install-nginx-module</pre>
<p>While running through this installer, there are a series of prompts.  Be sure you answer the following:</p>
<pre class="brush: plain;">Enter your choice (1 or 2) or press Ctrl-C to abort: 2
Please specify the directory: &lt;enter your directory, in my case it was /home/scott/nginx-0.7.64&gt;
Please specify a prefix directory [/opt/nginx]: /usr/local/nginx
Extra arguments to pass to configure script: --sbin-path=/usr/local/sbin --with-http_ssl_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_gzip_static_module</pre>
<h4>Step 4: Configuration of PHP-FPM and Nginx</h4>
<p>Sweet!  At this point you should have a shiny new Nginx install.  Before we can start it up, though, there are a few configuration files we have to mess with.  First we need to configure PHP-FPM to run as the proper user and place a default php.ini file in the appropriate directory.  First, let&#8217;s edit php-fpm.conf.  There are 4 lines we need to change, so just search through the file and make sure they look like this:</p>
<pre class="brush: plain;">&lt;value name="owner"&gt;www-data&lt;/value&gt;
&lt;value name="group"&gt;www-data&lt;/value&gt;
&lt;value name="user"&gt;www-data&lt;/value&gt;
&lt;value name="group"&gt;www-data&lt;/value&gt;</pre>
<p>Next we need to copy in the default php.ini file from the source directory.</p>
<pre class="brush: plain;">sudo cp php-5.3.1/php.ini-production /usr/local/etc/php.ini</pre>
<p>Finally, we need to configure Nginx.  I don&#8217;t like having one huge configuration file, so I really like to split things up.  You can edit this to your liking, but here&#8217;s basically how I set my default config (found at /usr/local/nginx/conf/nginx.conf):</p>
<pre class="brush: plain;">user  www-data;
worker_processes  6;

events {
 worker_connections  1024;
}

http {
 include       mime.types;
 default_type  application/octet-stream;
 sendfile        on;
 keepalive_timeout  10 10;

 passenger_root /opt/ruby-enterprise-1.8.7-2009.10/lib/ruby/gems/1.8/gems/passenger-2.2.7;
 passenger_ruby /opt/ruby-enterprise-1.8.7-2009.10/bin/ruby;

 gzip  on;
 gzip_comp_level 1;
 gzip_proxied any;
 gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

 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  /var/log/nginx_access.log main;

 error_log  /var/log/nginx_error.log crit;

 include /usr/local/nginx/sites-enabled/*;
}</pre>
<p>Now we need to set some default fastcgi options in /usr/local/nginx/conf/fastgci_params.  I just appended these to the end of the file.</p>
<pre class="brush: plain;">fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;</pre>
<p>Next, I like to create a &#8220;/usr/local/nginx/sites-enabled&#8221; directory that houses each website&#8217;s configuration details.  First I&#8217;ll show the configuration I used to handle URL rewrites for WordPress (this blog).  I called the file /usr/local/nginx/sites-enabled/geeksharp.com.</p>
<pre class="brush: plain;">server {
 listen 80;
 server_name *.geeksharp.com *.geeksharp.info *.geeksharp.org geeksharp.info geeksharp.org;
 rewrite ^(.*) http://geeksharp.com$1 permanent;
}

server {
 listen 80;
 server_name geeksharp.com;
 location / {
 root   /var/www;  # absolute path to your WordPress installation
 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;
 }
 }

 location ~ \.php$ {
 fastcgi_pass 127.0.0.1:9000;
 fastcgi_index index.php;
 fastcgi_param SCRIPT_FILENAME /var/www$fastcgi_script_name;
 include fastcgi_params;
 }
}</pre>
<p>Here&#8217;s how I&#8217;d set up a rails site.  In this example, the file is called /usr/local/nginx/sites-enabled/geeksharp.net.</p>
<pre class="brush: plain;">server {
 listen 80;
 server_name *.geeksharp.net;
 rewrite ^(.*) http://geeksharp.net$1 permanent;
}

server {
 listen 80;
 server_name geeksharp.net;
 root /home/scott/geeksharp.net/public;
 passenger_enabled on;
 access_log /home/scott/geeksharp.net-access.log;
 error_log /home/scott/geeksharp.net-error.log;
}</pre>
<h4>Step 5: Startup scripts</h4>
<p>Finally, I like to ensure that all my stuff comes up when the system reboots, so here&#8217;s a neato Nginx init.d script that I found.  Place this file at /etc/init.d/nginx, and make sure you give it execute permissions (chmod +x!)</p>
<pre class="brush: plain;">#! /bin/sh

### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# 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
DAEMON=/usr/local/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

case "$1" in
 start)
 echo -n "Starting $DESC: "
 start-stop-daemon --start --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
 --exec $DAEMON -- $DAEMON_OPTS
 echo "$NAME."
 ;;
 stop)
 echo -n "Stopping $DESC: "
 start-stop-daemon --stop --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
 --exec $DAEMON
 echo "$NAME."
 ;;
 restart|force-reload)
 echo -n "Restarting $DESC: "
 start-stop-daemon --stop --quiet --pidfile \
 /usr/local/nginx/logs/$NAME.pid --exec $DAEMON
 sleep 1
 start-stop-daemon --start --quiet --pidfile \
 /usr/local/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
 echo "$NAME."
 ;;
 reload)
 echo -n "Reloading $DESC configuration: "
 start-stop-daemon --stop --signal HUP --quiet --pidfile /usr/local/nginx/logs/$NAME.pid \
 --exec $DAEMON
 echo "$NAME."
 ;;
 *)
 N=/etc/init.d/$NAME
 echo "Usage: $N {start|stop|restart|force-reload}" &gt;&amp;2
 exit 1
 ;;
esac

exit 0</pre>
<p>Finally, make sure you update your rc.d</p>
<pre class="brush: plain;">sudo update-rc.d nginx defaults
sudo update-rc.d php-fpm defaults</pre>
<p>Please note that if for some reason nginx won&#8217;t start, chances are you have a config issue.  When you issue a restart command, the config errors usually will not be displayed.  The best way to track them down is to is to simply issue a stop command followed by a start command, and your errors will be displayed.  If you ever need to restart your services manually, you can use these commands (I find that restart can be buggy, which is why I explicity stop and start each one):</p>
<pre class="brush: plain;">sudo /etc/init.d/php-fpm stop &amp;&amp; sudo /etc/init.d/php-fpm start
sudo /etc/init.d/nginx stop &amp;&amp; sudo /etc/init.d/nginx start</pre>
<p>So that&#8217;s it! I know this is an epic post, but I hope it helps someone. Leave comments if you have specific questions or if I left out something particularly useful. Again, I understand that there&#8217;s probably a better way to do something, so feel free to share your thoughts!  As a final thought, I would like to thank <a href="http://interfacelab.com/nginx-php-fpm-apc-awesome/" target="_blank">Joshua Dorkin</a> for providing a great article on which I based a lot of this material!</p>
]]></content:encoded>
			<wfw:commentRss>http://geeksharp.com/2009/12/09/nginx-and-rails-and-php-oh-my/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
