<?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>HostingFu &#187; nginx</title>
	<atom:link href="http://hostingfu.com/tag/nginx/feed" rel="self" type="application/rss+xml" />
	<link>http://hostingfu.com</link>
	<description>Web Hosting Blog by a Software Developer</description>
	<lastBuildDate>Mon, 19 Jul 2010 09:27:08 +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>Quick Nginx Status Script</title>
		<link>http://hostingfu.com/article/quick-nginx-status-script</link>
		<comments>http://hostingfu.com/article/quick-nginx-status-script#comments</comments>
		<pubDate>Wed, 03 Jun 2009 08:52:15 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=189</guid>
		<description><![CDATA[Just to share another script that I hacked together to monitor my sites. Nginx is a great web server software and since I last wrote about it more than 2 years ago, I have since pretty much converted all my sites to Nginx (sorry Lighttpd). Nginx came with this HTTP stub status module that you [...]]]></description>
			<content:encoded><![CDATA[<p>Just to share another script that I hacked together to monitor my sites. <a href="http://nginx.net/">Nginx</a> is a <strong>great</strong> web server software and since I <a href="http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps">last wrote about it</a> more than 2 years ago, I have since pretty much converted <em>all</em> my sites to Nginx (sorry Lighttpd).</p>
<p>Nginx came with <a href="http://wiki.nginx.org/NginxHttpStubStatusModule">this HTTP stub status module</a> that you can get the current server status in a HTML page. However it&#8217;s <em>not pretty</em> comparing to Lighttpd&#8217;s and Apache&#8217;s. Moreover, the information it provides is a bit cryptic.</p>
<p><span id="more-189"></span></p>
<p>For example, when you browse to the stub status page (please refer to the wiki document linked earlier on how to set it up), all you get is 4 lines of text:</p>
<pre class="code">
$ curl http://myserver/nginx_status
Active connections: 183
server accepts handled requests
 914384 914384 2725561
Reading: 3 Writing: 2 Waiting: 178
</pre>
<p>Not very meaningful. Instead, I wrote a small Python script (download here: <a href="http://hostingfu.com/files/nginx/nginxstats.py"><b>nginxstats.py</b> (2.3kb)</a>) that does something like this:</p>
<pre class="code">
$ ./nginxstats.py http://myserver/nginx_status
Conn     Conn/s     Request/s  Read  Write Wait
-------- ---------- ---------- ----- ----- -----
     157       9.57      31.07     0     2   155
     140      10.20      36.13     0     1   139
     147       9.33      33.60     0     4   143
     189      12.60      40.07     1     4   184
     164      13.07      41.53     5     2   157
</pre>
<p>Basically it fetches the data from the stub status page every 30 seconds (configurable in the script) and then do some calculation to find out how many connections have been established within the time frame, and what&#8217;s the average connections/second and requests/second. Similar to tools like <code>vmstat</code>, it basically runs continuously (until interrupted).</p>
<p>Very <em>useful</em> when you are getting slashdotted :)</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/quick-nginx-status-script/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Keeping Your PHP/FastCGI Processes Alive</title>
		<link>http://hostingfu.com/article/keeping-your-php-fastcgi-processes-alive</link>
		<comments>http://hostingfu.com/article/keeping-your-php-fastcgi-processes-alive#comments</comments>
		<pubDate>Sat, 30 May 2009 04:10:08 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=188</guid>
		<description><![CDATA[A few days ago I spotted this forum post on Linode Forum &#8212; someone&#8217;s Nginx to PHP FastCGI set up kept on throwing 502 Gateway Error after a few days. I have a mystery and I&#8217;m not sure how to solve it. My 360 Linode is running several WordPress-based sites using nginx. Everything is great, [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago I spotted <a href="http://www.linode.com/forums/viewtopic.php?t=4234">this forum post</a> on Linode Forum &#8212; someone&#8217;s Nginx to PHP FastCGI set up kept on throwing <b>502 Gateway Error</b> after a few days.</p>
<blockquote><p>I have a mystery and I&#8217;m not sure how to solve it. My 360 Linode is running several WordPress-based sites using nginx. Everything is great, except I find that, every few days, fastcgi fails and I start getting 502 gateway errors when I try to post a comment or upload an image, etc. Restarting fastcgi fixes the problem.</p></blockquote>
<p>It looks like a very similar issue I had with Ubuntu 8.04 (and PHP 5.2.4), which was fixed when I <a href="http://hostingfu.com/article/debian-gnu-linux-5-lenny-released">migrated to Debian 5 Lenny</a>. It appears that the OP is indeed running the problematic Ubuntu 8.04. Well. I still have <b>no idea</b> what the real issue was (thus do not know how to report a bug), except my PHP FastCGI process will crash multiple times during busy time of the day (but it&#8217;s only 2-3 requests/second average).</p>
<p><span id="more-188"></span></p>
<p>Before switching to Lenny, I have tested multiple methods to keep my PHP FastCGI processes alive, including running check/restarting script every 5 minutes, etc. However at the end even 5 minutes downtime felt a bit excessive, so I wrote a simple daemon in Python to keep an eye on Nginx&#8217;s error log, and restart PHP/FastCGI processes whenever something bad has been detected. The problem here is that the PHP/FastCGI processes actually do not die &#8212; Nginx simply cannot communicate with them. So I need to restart PHP whenever Nginx splits a dummy.</p>
<p><del>I put the code on <b>Linode Pastebin here</b></del>. <ins>Linode has appeared to remove that script from their Pastebin, but you can <a href="http://hostingfu.com/files/python/phpmonitor.py"><b>Download it here</b></a></ins>, modify some variables in the code (for example the email addresses, start/stop script location, etc), and then run it as root.</p>
<p>What it does:</p>
<ul>
<li>It will damonize first.</li>
<li>Scanning <code>/var/log/nginx/error.log</code> every 2 seconds, using similar algorithm as <code>tail -f</code>.</li>
<li>If &#8220;104: Connection reset by peer&#8221; or &#8220;111: Connection refused&#8221; is detected in the log,
<ul>
<li>Run <code>killall -9 php-cgi</code></li>
<li>Run <code>/etc/init.d/spawn-fcgi-php start</code> to restart the PHP FastCGI processes</li>
</ul>
</li>
</ul>
<p>It should use minimum memory + CPU/IO (around 3.5MB RSS, and stat calls are pretty fast). At least it keeps me peace at night that I know if my PHP processes are crashing, there&#8217;s a guardian to bring them back up. It still runs on my VPS at Linode &#8212; even though with Debian 5 I am getting crashes once every 2 weeks instead of 4-5 times a day.</p>
<p>Hopefully it will be useful to some.</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/keeping-your-php-fastcgi-processes-alive/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Nginx and Mirror on Demand</title>
		<link>http://hostingfu.com/article/nginx-and-mirror-demand</link>
		<comments>http://hostingfu.com/article/nginx-and-mirror-demand#comments</comments>
		<pubDate>Tue, 17 Jul 2007 13:23:59 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=125</guid>
		<description><![CDATA[Just saw Igor Sysoev announced the release of Nginx 0.6.4 on the mailing list, and saw him demonstrating the new proxy_store and fastcgi_store directives (which have been available since 0.6.3), making &#8220;mirror on demand&#8221; so much easier to do as an developer. Here is the configuration code Ignor demonstrated in his email: location /images/ { [...]]]></description>
			<content:encoded><![CDATA[<p>Just saw <a href="http://sysoev.ru/">Igor Sysoev</a> announced the release of <a href="http://nginx.net/">Nginx</a> 0.6.4 on the mailing list, and saw him demonstrating the new <code>proxy_store</code> and <code>fastcgi_store</code> directives (which have been available since 0.6.3), making &#8220;mirror on demand&#8221; so much easier to do as an developer.</p>
<p>Here is the configuration code Ignor demonstrated in his email:</p>
<p><span id="more-125"></span></p>
<pre class="code">
location /images/ {
   root                 /data/www;
   error_page           404 = /fetch$uri;
}

location /fetch {
   internal;

   proxy_pass           http://backend;
   proxy_store          on;
   proxy_store_access   user:rw  group:rw  all:r;
   proxy_temp_path      /data/temp;

   alias                /data/www;
}
</pre>
<p>Basically <code>proxy_store</code> or <code>fastcgi_store</code> saves the backend result into files on the local file system, so subsequent requests to the same URI can be handled by on-disk cache without forwarding the request to the potentially-expensive backend again. Traditionally it requires the backend being able to write to local files (for example, <a href="http://fucoder.com/code/gravatar-cache/">one of my small project</a> does just that), however it is not always possible as they might not share the same file system.</p>
<p>You might still need a separate cron job to periodically invalidate the cache. However it just makes writing the backend much simpler.</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/nginx-and-mirror-demand/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GoDaddy TurboSSL Certificate on Nginx</title>
		<link>http://hostingfu.com/article/godaddy-turbossl-certificate-nginx</link>
		<comments>http://hostingfu.com/article/godaddy-turbossl-certificate-nginx#comments</comments>
		<pubDate>Tue, 19 Jun 2007 08:37:52 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[godaddy]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=118</guid>
		<description><![CDATA[Last Sunday I had my first chance of buying an SSL certificate and setting it up on Nginx. Prior to that I have always just signed with my own CA, and then just import my own CA&#8217;s certificate into browser&#8217;s root certificate repository. Anyway. What happened was on a website I am developing, I have [...]]]></description>
			<content:encoded><![CDATA[<p>Last Sunday I had my first chance of buying an SSL certificate and setting it up on <a href="http://nginx.net/">Nginx</a>. Prior to that I have always just signed with my own CA, and then just import my own CA&#8217;s certificate into browser&#8217;s root certificate repository.</p>
<p>Anyway. What happened was on a website I am developing, I have provided some API via Javascript, so this guy I am partnering with can just include my dynamically generated Javascript to produce content on his site. However, his site runs entirely on HTTPS but mine is not, so you get that dreadful <a href="http://support.microsoft.com/kb/184960">This Page Contains Both Secure and Non-Secure Items</a> error message in some IE versions.</p>
<p>I guess the easiest way for me to fix it up is actually running the site on HTTPS as well. So I went out and bought a certificate from GoDaddy (<em>$18/year &#8212; why so much price difference?</em>), but it wasn&#8217;t that trivial as GoDaddy does not have any installation instruction for Nginx, which my site is running under. <strong>Why not</strong>?! Consider Ngnix already has a sizable market penetration (especially if are a <a href="http://googleonlinesecurity.blogspot.com/2007/06/web-server-software-and-malware.html">Russian malware distributor</a>). Well, here are the steps.</p>
<p><span id="more-118"></span></p>
<h3 id="toc-1-buy-the-ssl-certificate">1. Buy the SSL Certificate</h3>
<p><img src="http://hostingfu.com/files/images/godaddy-logo.png" alt="GoDaddy" width="200" height="87" style="float:right;margin:0 0 1ex 1ex;"/> I got mine from <a href="http://www.godaddy.com/">GoDaddy</a>&#8216;s TurboSSL Certificate for $20/year, although there are lots of coupons out there that gives you 10% off. I know you can also get very cheap SSL certs from resellers of <a href="http://www.rapidssl.com/">RapidSSL</a>. Seriously I have no idea about the pricing difference from a technical point of view. These are just your public keys signed by the certificate authority, aren&#8217;t they? But I guess its probably the verification process that makes the difference.</p>
<p>I am not running an ecommerce site, so the cheapest one suits me fine. Nor do I want any phone/fax verification because (1) I do not live in the US (2) I need my cert right now!</p>
<h3 id="toc-2-download-the-certificate">2. Download the Certificate</h3>
<p>GoDaddy provides information on how you can use OpenSSL to generate a private key for your webserver, create a certificate request, and then paste this request onto GoDaddy&#8217;s site for verification.</p>
<p>After the request has been verified, a certificate will be generated for you to download. As there is no Nginx option, choose <b>Apache 2.x</b>. You will get a ZIP containing two files:</p>
<ol>
<li><tt>&lt;Common Name&gt;.crt</tt> &#8212; Your certificate.</li>
<li><tt>gd_intermediate_bundle.crt</tt> &#8212; GoDaddy Certificate Intermediates Bundle</li>
</ol>
<p>If you don&#8217;t see the second file, you should be able to download it from <a href="https://certificates.godaddy.com/Repository.go">their repository</a>.</p>
<h3 id="toc-3-upload-them-onto-webserver">3. Upload Them onto Webserver</h3>
<p>You need to concatenate your certificate file and GoDaddy&#8217;s intermediate certificate to form the final certificate. I usually name my files <code><em>domain</em>.crt</code>. Then you need to upload <b>both</b> your private key file (generated in step 2) and the certificate file to your server running Nginx.</p>
<p>For example if your domain is <code>example.com</code>:</p>
<pre class="code">
# cat example.com.crt gd_intermediate_bundle.crt > /etc/nginx/example.com.crt
# cp example.com.key /etc/nginx/example.com.key
</pre>
<p>Note that concatenating the two files together is important. SSL certificate issuers are chained, and the intermediate bundle provides the &#8220;missing link&#8221; between well-known certificate authorities in your browser&#8217;s root CA list, and your website&#8217;s own certificate.</p>
<h3 id="toc-4-turn-on-ssl-module-in-nginx">4. Turn on SSL Module in Nginx</h3>
<p>Now you can activate your SSL site in Nginx. Use the following configuration in your <code>nginx.conf</code>:</p>
<pre class="code">
server {
    listen 443;
    server_name example.com;
    ssl on;
    ssl_certificate /etc/nginx/example.com.crt;
    ssl_certificate_key  /etc/nginx/example.com.key;
    ...
}
</pre>
<p>Restarting Nginx, and your web server will now be serving encrypted content.</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/godaddy-turbossl-certificate-nginx/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Running Drupal with Clean URL on Nginx or Lighttpd</title>
		<link>http://hostingfu.com/article/running-drupal-with-clean-url-on-nginx-or-lighttpd</link>
		<comments>http://hostingfu.com/article/running-drupal-with-clean-url-on-nginx-or-lighttpd#comments</comments>
		<pubDate>Wed, 17 Jan 2007 07:36:13 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[drupal]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=82</guid>
		<description><![CDATA[First of all, my previous post on Nginx vs. Lighttpd for a small VPS seems to be a &#8220;hit&#8221;. Thanks to Glenn for submitting it to programming.reddit.com, which got picked up by a few bloggers. Got around 1,000 unique visitors on the day where the post went live, which I guess is pretty good for [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://drupal.org/"><img src="http://hostingfu.com/files/images/drupal-logo.png" alt="Drupal Logo" width="100" height="109" style="float:right;margin:0 0 1ex 1ex"/></a> First of all, my previous post on <a href="http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps">Nginx vs. Lighttpd for a small VPS</a> seems to be a &#8220;hit&#8221;. Thanks to <a href="http://blog.slaven.net.au/">Glenn</a> for submitting it to <a href="http://programming.reddit.com/">programming.reddit.com</a>, which got picked up by a few bloggers. Got around 1,000 unique visitors on the day where the post went live, which I guess is pretty good for this one-post-a-week site of mine.</p>
<p>Since I have briefly touched on the &#8220;URL rewrite-ability&#8221; of Nginx and Lighttpd in my previous post, I think it might actually be useful to have some examples showing how rewrite rules are written on these web servers to support clean URLs. I will take the open source CMS <a href="http://drupal.org/">Drupal</a> for example, as it is what <b>Hosting Fu</b> runs on. Btw, <a href="http://drupal.org/drupal-5.0">Drupal 5.0</a> has just been released and it rocks.</p>
<p><span id="more-82"></span></p>
<h3 id="toc-prerequisite">Prerequisite</h3>
<p>These are the things that I assume you would know before reading this article.</p>
<ul>
<li><strong>Why clean URL</strong>. Pick your reason. SEO or general dislike of query string.</li>
<li><strong>Setting up PHP</strong>. I won&#8217;t be talking about how to set up PHP/FastCGI on Nginx or Lighttpd. Here&#8217;s one for <a href="http://wiki.codemongers.com/NginxFcgiExample">Nginx</a> and one for <a href="http://trac.lighttpd.net/trac/wiki/TutorialLighttpdAndPHP">Lighttpd</a>.</li>
<li><strong>Installing Drupal</strong>. Check related section in <a href="http://drupal.org/node/258">Drupal handbook</a>.</li>
</ul>
<p>I am only going to discuss the rewriting rules needed to enable clean URL in Drupal on either Nginx or Lighttpd.</p>
<h3 id="toc-apaches-mod_rewrite">Apache&#8217;s Mod_Rewrite</h3>
<p>Like most open source PHP applications, Drupal came with a <code>.htaccess</code> file assuming Apache is serving the pages. We will use it as the reference on how the rewrite rules can be written for the other two web servers.</p>
<p>Here&#8217;s the bit in <code>.htaccess</code> that does rewrites:</p>
<pre class="code">
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
</pre>
<p>What it does is:</p>
<ul>
<li>If requested file exists, serve it.</li>
<li>If requested directory exists, serve it depending on how index option is configured.</li>
<li>Otherwise, send all requests to <code>index.php</code>, setting parameter &#8216;q&#8217; as the path of the original request, and then append the rest of the query string.</li>
</ul>
<p>Simple. Now let&#8217;s see how you can do the same with the other two web servers.</p>
<h3 id="toc-lighttpd">Lighttpd</h3>
<p>This site runs on <a href="http://www.lighttpd.net/">Lighttpd</a> 1.4.13, and there seems to be a lot of different ways to do clean URL with Drupal on Lighttpd. Although it came with its own &#8220;mod_rewrite&#8221;, but I found the functionality is very limited. The biggest problem I found is the lack of conditional rules to check whether a file or directory already exists. At the end you have to either (1) make lots of exceptions in Lighttpd&#8217;s rewrite rules, or (2) modify Drupal so it works better with Lighttpd.</p>
<p>I went with the second option.</p>
<p>Well, here are the steps.</p>
<ol>
<li>
<p>After Drupal has been installed and tested with clean URL disabled, add the following rules to lighty&#8217;s configuration file:</p>
<pre class="code">
server.error-handler-404 = "/index.php";
</pre>
<p>It basically makes <code>index.php</code> the 404 error handler, so any request that does is not handled by a local file or directory will be sent to Drupal.</p>
</li>
<li>
<p>Add the following PHP code to Drupal. I just append them to the end of <code>sites/default/settings.php</code>.</p>
<pre class="code">
if (strpos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') !== false) {
    $_lighty_url = $base_url.$_SERVER['REQUEST_URI'];
    $_lighty_url = @parse_url($_lighty_url);

    if ($_lighty_url['path'] != '/index.php' &amp;&amp; $_lighty_url['path'] != '/') {
        $_SERVER['QUERY_STRING'] = $_lighty_url['query'];
        parse_str($_lighty_url['query'], $_lighty_query);
        foreach ($_lighty_query as $key =&gt; $val)
            $_GET[$key] = $_REQUEST[$key] = $val;
        $_GET['q'] = $_REQUEST['q'] = substr($_lighty_url['path'], 1);
    }
}
</pre>
<p>Let me explain what it does:</p>
<ul>
<li>If we are behind lighty, turn on this hack (I use Nginx for my development box so this code does not apply).</li>
<li>Try to parse the <code>REQUEST_URI</code>. If invoked as 404 error handler, we will parse the <code>QUERY_STRING</code> ourselves and copy the values to PHP&#8217;s <code>$_GET</code> and <code>$_REQUEST</code> variables.</li>
<li>Also set the path bit of <code>REQUEST_URI</code> as query argument <code>q</code>.</li>
</ul>
<p>The reason why we have to parse <code>QUERY_STRING</code> is, Lighttpd <a href="http://trac.lighttpd.net/trac/wiki/FrequentlyAskedQuestions#Whatkindofenvironmentdoesserver.error-handler-404setup">deliberately</a> does not set <code>QUERY_STRING</code> if FastCGI is invoked as 404 error handler.</p>
</li>
<li>
<p>Restart lighty, go to Drupal to enable clean URL and see whether it works.</p>
</li>
</ol>
<p>Well, it has been working fine for me, but YMMV.</p>
<h3 id="toc-nginx">Nginx</h3>
<p><a href="http://nginx.net/">Nginx</a> comes with conditional code for rewrite rules so it is much easier. I basically have the following code in my Nginx configuration file to emulate Apache&#8217;s behaviour.</p>
<pre class="code">
if (!-e $request_filename) {
    rewrite ^/(.*)$ /index.php?q=$1 last;
}
</pre>
<p>That&#8217;s it! Restarting Nginx, and you can now turn on clean URL in Drupal.</p>
<p><strong>However</strong>, Nginx is not perfect, and so far I have found one small issue with its rewrite engine. When you use regular expression in Nginx&#8217;s rewrite rules, it will try to encode the matches in the replacement URL. So far I have seen it broke Drupal&#8217;s search module. For example, if you search for &#8220;Hosting Fu&#8221;, Drupal will use the following URL:</p>
<pre class="code">
GET /search/node/Hosting+Fu HTTP/1.1
</pre>
<p>However, Nginx will rewrite that to:</p>
<pre class="code">
GET /index.php?q=search/node/Hosting%2BFu HTTP/1.1
</pre>
<p>Note it encoded &#8216;+&#8217; to &#8216;%2B&#8217;, which confuses Drupal, who thinks that you are actually searching the phrase &#8216;Hosting+Fu&#8217;. In case of Apache, &#8216;+&#8217; passed through rewrite rules untouched.</p>
<h3 id="toc-conclusion">Conclusion</h3>
<p>Many open source PHP applications that I have experience with always <strong>assume</strong> the existence of Apache, and provide clean URL to only Apache users. On the other hand, developers of other frameworks like Ruby on Rails, Django, Webpy, etc take clean URL for granted because it is something handled right inside the framework. It makes the life of the web server guy much easier &#8212; what rewrite? Just proxy or pass through the whole damn thing!</p>
<p>I am hoping more and more PHP applications will use simplified rewrite rules. Let applications themselves take care of parsing the <code>REQUEST_URI</code>, instead of generating a million lines of Apache mod_rewrite rules and dumping them into <code>.htaccess</code> files.</p>
<p>Meanwhile, Nginx users will have much easier time porting those rules then the Lighttpd users.</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/running-drupal-with-clean-url-on-nginx-or-lighttpd/feed</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
		<item>
		<title>Nginx vs. Lighttpd for a small VPS</title>
		<link>http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps</link>
		<comments>http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps#comments</comments>
		<pubDate>Wed, 10 Jan 2007 04:41:27 +0000</pubDate>
		<dc:creator>scotty</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[lighttpd]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[vps hosting]]></category>
		<category><![CDATA[web server]]></category>

		<guid isPermaLink="false">http://hostingfu.com/?p=81</guid>
		<description><![CDATA[I have been using Lighttpd for almost a year and Nginx for a month on my servers. I know that they were created to be massively scalable, solving the C10k problem. However their asynchronised-IO model and small memory foot-print also make them suitable as alternative HTTP servers for memory-limited VPS. Alternative = Anything but the [...]]]></description>
			<content:encoded><![CDATA[<p>I have been using <a href="http://www.lighttpd.net/">Lighttpd</a> for almost a year and <a href="http://nginx.net">Nginx</a> for a month on my servers. I know that they were created to be massively scalable, solving the <a href="http://www.kegel.com/c10k.html">C10k problem</a>. However their asynchronised-IO model and small memory foot-print also make them suitable as alternative HTTP servers for memory-limited VPS. Alternative = Anything but the current defacto <a href="http://httpd.apache.org/">Apache</a>.</p>
<p>I will be writing more about Lighttpd and Nginx later during the year, but will try to use this post to draw some comparison between <a href="http://nginx.net/">Nginx</a>, the new darling of these light-weight web servers, and <a href="http://www.lighttpd.net/">Lighttpd</a>, many Web 2.0 developers&#8217; all time favourite.</p>
<p><span id="more-81"></span></p>
<h3 id="toc-lighttpd">Lighttpd</h3>
<p><img src="http://hostingfu.com/files/images/light-logo.png" width="120" height="115" alt="Lighttpd" style="float:right;margin:0 0 1ex 1ex"/> I have been running Lighttpd (pronounced &#8220;lighty&#8221;) on my home servers and development boxes since the beginning of 2006. It is a great replacement for Apache if you have the whole box to yourself, i.e. you don&#8217;t need to worry about supporting <code>.htaccess</code> files that your users might use. Currently this website is hosted on lighttpd-1.4.13 on a Gentoo VPS.</p>
<p><b>Pros</b></p>
<ul>
<li><b>Light weight</b>. Clean restart of 1.4.13 takes no more than 2Mb RSS on this 64bit VPS. It binds the port, drops the privilege and that&#8217;s it! A single process does all the tricks even when you have hundreds of concurrent connections. No more pre-fork MPM with mis-configured <code>MaxClient</code> that sends you to swap hell.</li>
<li><b>Speed</b>. Very fast static file serving. Very fast FastCGI serving. Very fast proxy serving.</li>
<li><b>Modules</b>, and <a href="http://trac.lighttpd.net/trac/wiki/Docs">lots of them</a>. Good comprehensive documentation as well. It even has <a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModSCGI">SCGI</a> for your Quixote apps.</li>
<li><b>Mod_magnet</b>. Wanna a scripting engine right inside your web server? <a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModMagnet">Mod_magnet</a> integrates <a href="http://www.lua.org/">Lua</a> into lighttpd, so your World of Warcraft scripting skillz can be put into better use.</li>
<li><b>Community</b>. It has got a <a href="http://blog.lighttpd.net/">Blog</a>, a <a href="http://trac.lighttpd.net/trac/">Wiki/bug tracker</a> and a <a href="http://forum.lighttpd.net/">forum</a>. It is easy to find help when you need one.</li>
</ul>
<p><b>Cons</b></p>
<ul>
<li><b>Stability</b> (or lack of according to the RoR folks). I had quite a lot of issues using Lighttpd as proxy+HTTPS front-end for our Python stuff, but the same app runs fine with just lighttpd + proxy without HTTPS.</li>
<li><b>Mod_rewrite</b> (or again, lack of it). Built-in rewriting engine sucks, and porting Apache mod_rewrite rules over can be non-trivial sometimes. <b>Update</b>: Here&#8217;s an article I have written on <a href="http://hostingfu.com/article/running-drupal-with-clean-url-on-nginx-or-lighttpd">Drupal clean URL on Nginx and Lighttpd</a>, which looks at the URL rewrite options of these two web servers.</li>
<li><b>Memory leak</b>. The RSS of my lighty process grows by about 1.5Mb per day, but then I don&#8217;t have lots of traffic (less than 50k requests a day). At the end I just need to restart it once a week. Many people have far worse memory leaking issues I heard.</li>
</ul>
<h3 id="toc-nginx">Nginx</h3>
<p><img src="http://hostingfu.com/files/images/nginx-logo.png" width="121" height="32" alt="Nginx" style="float:right;margin:0 0 1ex 1ex"/> I have been running Nginx (pronounced &#8220;engine X&#8221;) on my development box and two of my VPS&#8217;s since December 2006. It is <em>Russian</em>, fast and very configurable. I am currently using 0.5.5 for my sites, but don&#8217;t be deceived by its version number &#8212; it is very stable.</p>
<p><b>Pros</b></p>
<ul>
<li><b>Light weight</b>. It is not as light weight as lighttpd when it clean-starts. At least two processes are needed &#8212; one master process running as root that binds to the port, and one or more worker processes that handle the actual requests. Around 7Mb RSS together on my 64bit VPS (and only 4.5Mb on 32bit VPS). Still beats Apache hands down.</li>
<li><b>Fast</b>. Some benchmarks have shown that Nginx has a slight edge over Lighttpd, but so far I haven&#8217;t been able to notice any. Again, much faster than Apache over static file serving or proxying, especially when you turn up the value of keep alive (more than 1 minute for example).</li>
<li><b>Modules</b>. There are <a href="http://wiki.codemongers.com/Nginx">many modules</a> available on Nginx. Some very useful, and some are just plain weird. While lighttpd has Lua embedded, you can now also <a href="http://wiki.codemongers.com/NginxEmbeddedPerlModule">embed the whole Perl interpretor</a> inside Nginx.</li>
<li><b>Better Rewrite Module</b>. A much better rewrite module than Lighttpd that supports complex conditions. Porting mod_rewrite rules from Apache is actually now feasible without touching the apps themselves.</li>
<li><b>Stable and not leaking</b>. Been running Nginx on a production site doing PHP-FastCGI, and have no issue what so ever.</li>
</ul>
<p><b>Cons</b></p>
<ul>
<li><b>Lack of community</b>. Where can I find help regarding Nginx? There&#8217;s only <a href="http://irclog.turbogears.org/archive/freenode/nginx">IRC</a> as far as I know. And while the lead developer writes beautiful code, all documentation <a href="http://sysoev.ru/nginx/">were initially in Russian</a> which was a big stumbling block before the <a href="http://wiki.codemongers.com/Nginx">English docs</a> came along.</li>
<li><b>No CGI support</b>. Oh well, maybe I am the only one who still hacks small CGI scripts. Apparently Nginx does not spawn CGI or FastCGI processes, which means you need to either (1) convert it into external-spawn FastCGI, or (2) proxy to another web server that does CGI.</li>
<li><b>No simple virtual host support</b>. Lighttpd has <a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModSimpleVhost">mod_simple_vhost</a> and <a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModEVhost">mod_evhost</a> to let you quickly deploy lots of name-based virtual hosts. You <em>can</em> somehow do the same with using <code>$server_name</code> in <code>root</code> and a wild-card in <code>server_name</code>, but it&#8217;s still not as clean as lighttpd. At the end you will find Nginx configuration files much more verbose if you run lots of small sites off a single web server.</li>
<li><b>No X-sendfile support</b>. I found Lighttpd&#8217;s X-sendfile support very useful when my scripts need to send back large files, and was disappointed to find out that Nginx does not have it. <a href="http://wiki.codemongers.com/NginxXSendfile">X-Accel-Redirect</a> is different as it requires extra configuration on web server, which makes your web-app less portable.</li>
</ul>
<h3 id="toc-conclusion">Conclusion</h3>
<p>I don&#8217;t think I am a suitable judge to say which one is better, as (1) I have only been running Nginx for a month, and (2) my level of traffic does not really stress test these high-performing web servers. At the moment I think I like Nginx better purely because it does not leak, and its rewrite module that enables me to run many off-the-shelf open source PHP apps with clean URL.</p>
<p>Again, I might change my mind in 3 months time when I find out more warts about Nginx. We will see.</p>
]]></content:encoded>
			<wfw:commentRss>http://hostingfu.com/article/nginx-vs-lighttpd-for-a-small-vps/feed</wfw:commentRss>
		<slash:comments>55</slash:comments>
		</item>
	</channel>
</rss>
