Dec 08 2009

ExpressionEngine and Nginx

Getting your ExpressionEngine site up and running on Nginx is really pretty simple.  I have been interested in Nginx for some time given its low memory footprint and ability to serve static files very quickly.  In the past year, I have become kind obsessed in properly optimizing websites like Y-Slow or Google Page Speed says I should, so I see this as a natural extension.

The big caveat for me is I do not like FastCGI at all.  Not looking for a debate, it’s just my opinion.  Being the ruler of this domain, I’m entitled to it.  smile  So I’m focusing on running Nginx to serve static files & proxy PHP requests over to Apache.  Nice thing about this is that we can tear out some apache modules that aren’t needed, and make it pretty lean.  I suppose the other caveat is that, I like to play.  If gregaker.net got more than 3 hits a day or was mission critical, it would be on load-balanced hosted at EngineHosting, as you don’t get better than EngineHosting.  Period.  (disclaimer, I work for EngineHosting as well, but hey, only the best, right?)

So onto it!

Install Apache & Nginx as your Linux Distro says you should, and let’s start with Nginx.  There are plenty of tutorials out there on the base layout of both Nginx & Apache, so I’m going to just talk about the vhost for each.

Nginx:

## Force www so we can serve static content from a cookieless domain.
server {
    listen 80
;
    
server_name example.com;

    
location {
        root 
/var/www/example.com/html;
    
}

    
if ($host ~* ^example\.com{
        rewrite 
^(.*)$ http://www.example.com$1 permanent;
    
}
}

server {
    listen 80
;
    
server_name www.example.com;

    
access_log  /var/www/example.com/log/nginx.access.log;

    
root /var/www/example.com/html;

    
location {
        root 
/var/www/example.com/html;
        
index index.html index.htm index.php;

        
proxy_set_header X-Forwarded-Host $host;
        
proxy_set_header X-Forwarded-Server $host;
        
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
}

    
# serve static files directly
    
location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|swf)$ {
        access_log        off
;
        
expires           max;
    
}

    
# Send PHP over to apache for it's thing
    
location \.php{
        proxy_set_header X
-Forwarded-Host $host;
        
proxy_set_header X-Forwarded-Server $host;
        
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for
        
proxy_pass http://1.1.1.1:8080;  ## Your Server IP and whatever port you want to tell apache to listen on.
    
}

    
## I don't like catch-all URL rewrites, so I'm going to be explicit in what I am rewriting.
    
rewrite ^/home(.*)? /index.php?/home$1 last;
    
rewrite ^/member(.*)? /index.php?/member$1 last;
    
rewrite ^/forums(.*)? /index.php?/forums$1 last;
}

server {
    listen 80
;

    
server_name static.gregaker.net;

    
root /var/www/static.example.com/html;

    
access_log off;
    
expires    max;

So, we have the base setup for Nginx.  We are

  • Rewriting no-www to http://www.example.com.  As I said in the comments, I want to serve static content from a cookieless domain.
  • Any static content that lives on the main www domain, we are going to send VERY far-future expires headers.  Best thing to do if you change them is to change the actual file name, eg: my_photo.yyyymmddnn.jpg
  • Pass off requests to PHP files to Apache on the server IP listening on another port.  If you have multiple IPs, you can listen on port 80, but this works for me as you can lock down the alternate port with IPTables.
  • Setup a static subdomain to server our main images uploads, css, javascript, etc from. There is really no need to add overhead or disk space with access logs, so I turn it off.

Apache is going to see every request coming from 127.0.0.1, but never fear, mod_rpaf to the rescue.  Set this up, and along with the X-Forwarded-For headers we are sending, Apache will see the proper IP address of your visitors.

The Apache VHost is simple & easy.  You might want to add more, but a really bare bones example is:

<VirtualHost 1.1.1.1:8080>
   
DocumentRoot /var/www/example.com/html
   ServerName www
.example.com
   ServerAlias example
.com

   ErrorLog 
/var/www/example.com/log/apache.error.log
   CustomLog 
/var/www/example.com/log/apache.access.log combined
</VirtualHost

Start Nginx & Apache and you will be off and running with your ExpressionEngine site on Nginx proxying PHP to Apache.


Post a Comment





Submit the word you see below: