<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Dave Dash</title>
 <link href="http://davedash.com/tag/fastcgi/atom.xml" rel="self"/>
 <link href="http://davedash.com/tag/fastcgi"/>
 <updated>2012-01-17T21:54:19-08:00</updated>
 <id>http://davedash.com/</id>
 <author>
   <name>Dave Dash</name>
   <email>dd+atom1@davedash.com</email>
 </author>

 
 <entry>
   <title>nginx proxying to apache</title>
   <link href="http://davedash.com/2008/04/16/nginx-proxying-to-apache/"/>
   <updated>2008-04-16T00:00:00-07:00</updated>
   <id>http://davedash.com/2008/04/16/nginx-proxying-to-apache</id>
   <content type="html">&lt;p&gt;I gave up on fastcgi with NginX and django.  Too many things just didn't work, so I decided to keep Apache, but lock it down and thrown NginX in the front to serve static content and to prevent max client issues.&lt;/p&gt;

&lt;p&gt;I also applied a similar approach for symfony.  Server configurations after the jump...&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;Apache&lt;/h3&gt;

&lt;p&gt;You should configure Apache as you would if you were serving directly from Apache.  In otherwords, if you are already using Apache, you don't need to do anything different, save changing a port.&lt;/p&gt;

&lt;p&gt;The one tweak I made to a standard configuration is to limit the allowed hosts to just the ones I want.&lt;/p&gt;

&lt;p&gt;Here's my django app's &lt;code&gt;apache.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NameVirtualHost *
&amp;lt;VirtualHost *&amp;gt;
    ServerName onyxfoundation.org

    SetEnvIf X-Magic-Header ^secret$ let_me_in
    &amp;lt;Location &quot;/&quot;&amp;gt;
            SetHandler python-program
            PythonHandler django.core.handlers.modpython
            SetEnv DJANGO_SETTINGS_MODULE onyx.settings
            PythonDebug On
            PythonPath &quot;['/var/www/django/'] + sys.path&quot;
            Order Deny,Allow
            Deny from all
            Allow from env=let_me_in
    &amp;lt;/Location&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the &lt;code&gt;SetEnvIf&lt;/code&gt; it can be set however you want, I prefer to match a specific header that I send from &lt;code&gt;nginx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you are using symfony, something like this will be more appropriate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *&amp;gt;
        ServerName reviewsby.us
        DocumentRoot /var/www/reviewsby.us/web
        DirectoryIndex index.php
       SetEnvIf X-Magic-Header ^secret$ let_me_in

        &amp;lt;Directory /var/www/reviewsby.us/web&amp;gt;
                Options Indexes FollowSymLinks

                RewriteEngine On

                RewriteRule ^$ index.html [QSA]
                RewriteRule ^([^.]+)$ $1.html [QSA]

                RewriteCond %{REQUEST_FILENAME} !-f
                RewriteRule ^(.*)$ index.php [QSA]
                Order Deny,Allow
                Deny from all
                Allow from env=let_me_in
        &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You'll also need to listen on a different port (preferably one that is not exposed to the outside world):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Listen 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;NginX&lt;/h3&gt;

&lt;p&gt;Now NginX needs to be configured to do 2 things:
1. Serve all static content
2. Pass requests that need interpreting to django or symfony&lt;/p&gt;

&lt;p&gt;The Django conf of Nginx is very easy:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server {
  listen   80;
  server_name onyxfoundation.org;

  location ^~ /static/ {
    alias        /var/www/django/onyx/static/;
    access_log   off;
    expires      30d;
  }

  location / {
    proxy_pass      http://127.0.0.1:8080/;
    proxy_redirect  off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    proxy_set_header        X-Magic-Header &quot;secret&quot;;
    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;

  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The settings are trivial.  Everything that's &lt;code&gt;/static&lt;/code&gt; gets served straight from NginX and the django application is served over Apache.&lt;/p&gt;

&lt;p&gt;The same thing is a bit trickier in symfony:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;server {
  listen   80;
  server_name  reviewsby.us;

  charset utf-8;

  location  /sf/ {
    alias  /var/www/reviewsby.us/lib/vendor/symfony/data/web/sf/;
  }
  location /css/ {
    alias /var/www/reviewsby.us/web/css/;
  }
  location /images/ {
    alias /var/www/reviewsby.us/web/images/;
  }

  location /js/ {
    alias /var/www/reviewsby.us/web/js/;
  }

  location / { 
    proxy_pass http://reviewsby.us:8080/;
    proxy_redirect off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
    proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    proxy_set_header        X-Magic-Header &quot;secret&quot;;
    client_max_body_size       10m;
    client_body_buffer_size    128k;

    proxy_connect_timeout      90;
    proxy_send_timeout         90;
    proxy_read_timeout         90;

    proxy_buffer_size          4k;
    proxy_buffers              4 32k;
    proxy_busy_buffers_size    64k;
    proxy_temp_file_write_size 64k;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The added difficulty with symfony is specific to this app (and most default apps) since static content is split amongst the web root (&lt;code&gt;/js&lt;/code&gt;, &lt;code&gt;/css&lt;/code&gt;, &lt;code&gt;/images&lt;/code&gt;, etc) versus the suggested django approach of throwing everything in &lt;code&gt;/static&lt;/code&gt;.  I now adopt this approach for symfony as well.  It makes everything more flexible in the long-run.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;If you've been hesitating about putting a reverse proxy in front of Apache, hopefully this can help you out.  NginX is a lightweight fast server that can handle far more requests than Apache.  By putting it on the front-lines you can give your app that extra inch it needs to keep churning out requests.&lt;/p&gt;

&lt;p&gt;Let me know if this configuration works for you.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Keep a second web server around for luck...</title>
   <link href="http://davedash.com/2008/02/12/keep-a-second-web-server-around-for-luck/"/>
   <updated>2008-02-12T00:00:00-08:00</updated>
   <id>http://davedash.com/2008/02/12/keep-a-second-web-server-around-for-luck</id>
   <content type="html">&lt;p&gt;I had one of those mid-day &quot;what's going on with my server&quot; heart-atacks.  I have a service that emails me when &lt;a href=&quot;http://reviewsby.us/&quot;&gt;reviewsby.us&lt;/a&gt; is down.  On my old server if it went down, I could just restart the server and it'd be back up.  That was big old apache, running out of memory or something.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://reviewsby.us/&quot;&gt;Reviewsby.us&lt;/a&gt; is a medium sized site.  It gets a fair amount of traffic at a steady pace.  Even in this case I decided I was in need for a new server, so I looked into nginx.  It's fast and it can serve static content well and pass things to fastcgi.  Joshua Schachter explains the &lt;a href=&quot;http://joshua.schachter.org/2008/01/proxy.html&quot;&gt;proxy in front&lt;/a&gt; concept pretty well.&lt;/p&gt;

&lt;p&gt;Back to my web developer heart attack...&lt;/p&gt;

&lt;p&gt;Well this setup had been holding up for a better part of a month fairly well... then I saw that a lot of the pages just lagged.  I restarted fastcgi and nginx (it was a fastcgi issue).  Rather than try to debug something I couldn't, I quickly installed apache2 and setup the server the tried and tested way.&lt;/p&gt;

&lt;p&gt;This all took place in a half an hour.  Not the end of the world, but not elegant either.  In the future, I'll revert to using nginx (possibly nginx+apache versus nginx+fastcgi) but I'll keep my other configurations around when all hell breaks loose.&lt;/p&gt;
</content>
 </entry>
 

</feed>

