page info

Apache to Nginx Migration

This is quite an old (ca. 2008) wiki page detailing how I migrated some web services from Apache to Nginx. Much of the original was introductory, but by now (2013) Nginx is an established web server of some note.

why migrate?

If Apache is used by 60% of the websites out there, aren't all software stacks tuned to use it? Shouldn't it be the best option even if it is not the best webserver?

Webservers have to support and handle many different tasks. Some of them are especially efficient at handling some types of tasks (like serving static media) while being incapable of performing others. nginx allows you to take a "best of breed" approach by being an extremely fast load balancer, thus being (in theory) able to delegate subtasks out to applications or application stacks that excel in handling those tasks.

Basic Nginx Architecture Possibilities

As nginx is quite a fast load balancer and an HTTP server, it can change the way you develop your application structure. Classic 3-tier architecture is much more attractive when each tier will be lightweight memory-wise and blazing fast. Most DIY Apache configurations end up being 2-tier, with the webserver & appserver combined and memory-resident to reduce the delay in handing off connections from the web to your application. This is the way that apache/mod_php and apache/mod_python work.

3-Tier is starting to become popular in the python world with apache and mod_wsgi. Although both FastCGI & mod_wsgi are usually run as Apache modules, the actual processes that are taking care of the requests are run separately from the server.

FastCGI

Nginx comes with FastCGI support built in, and the configuration is very simple:

server {
    listen example.com:80
    server_name www.example.com;
    # set indexes to index.php or index.html
    index index.php index.html;
    root /var/www/example.com;

    location ~ .php$ {
        # 'pass' the request to FastCGI running @ localhost:9000
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        # set the parameter 'SCRIPT_FILENAME' to be the docroot + script name
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

mod_wsgi

There exists both the excellent apache/mod_wsgi from Graham Dumpleton and some significantly less popular Nginx modules called mod_wsgi which attempt to do the same thing. These days, it is far more popular in the python world to use pure python fast-connection http servers like gunicorn and front them with hardened slow-connection http proxies. Nginx is one such popular proxy.

Serving PHP content

PHP is servable through FastCGI. Since this document was written, most people have come to use the php-fpm server for FastCGI php deployment. Although the configuration isn't quite as baked in as apache/mod_php, as you can see above a simple setup is not too complex.

Serving (X) content

As mentioned above, modern web application stacks from Ruby (with passenger), Python (gunicorn, uwsgi), Node.js or Golang nearly all deploy by speaking HTTP to a fronting proxy (or in Go's case, sometimes to the internet directly).

This wiki is itself written in Go, and is deployed through Nginx along with various other apps with the following virtualhost + proxy_pass configuration:

upstream wiki {
    server localhost:8002 fail_timeout=0;
}

server {
    listen 80;
    server_name wiki.jmoiron.net;

    location / {
        proxy_pass http://wiki;
    }

    access_log  /var/log/nginx/wiki.access.log;
    error_log   /var/log/nginx/wiki.error.log;
}