Running Ushahidi Using Nginx

I have read and heard so many good things about Nginx in terms of performance and memory consumption. I have been using Apache for a very long time for web development. After lots of research, I’m convinced and ready to move away from Apache in favour of Nginx. It’s not that I need Nginx’s power, as shared by Joe Williams, but as a developer I seek new learning experiences.

Nginx is easy to setup. There are lot of articles on how to set it up to run PHP scripts using FastCGI. In this post I’m going to share with you my configuration files and how I got it to work with Ushahidi in a sub directory.

I’m running Ubuntu Quantal, Nginx v1.2.1, PHP5-fpm v5.4.6 and Ushahidi v2.7 develop branch. Nginx configuration structure looks similar to that of Apache, so it was easy navigating through the configuration files. I knew exactly where to look.

Virtual Host
I made a copy of the default configuration in  /etc/nginx/sites-available and disabled it by removing the symlink in /etc/nginx/site-enabled. If you are familiar with Apache, you will realize there are similarities in the directory structure.

My virtual host(vhost) file called ‘sites’ is located at  /etc/nginx/sites-available. I have heavily commented the code to explain the necessary details of it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
server {

    # Listen on port 80 and make this the default vhost
    listen 80 default;

    # The root document
    root /var/www;

    # The index files.
    index index.php index.html index.htm;

    # Make the site accessible from http://localhost/
    server_name localhost;

    location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to displaying a 404.
        try_files $uri $uri/ /index.php$uri?$args;
    }

    # Location of ushahidi install - /var/www/develop. Setup clean url.
    location /develop {

        # These two lines Made it possible for static files to be
        # served without a rewrite. I read ifs are evil.
        # Use try_files instead but I couldn't figure out how to
        # use try_files for this.

        if (-f $request_filename) {
            # If the request is an existing file, do nothing
            break;
        }
       
        if (-d $request_filename) {
            # If the request is an existing directory, do nothing
            break;
        }

        # Rewrite say localhost/develop/reports to
        # localhost/develop/index.php/reports
        rewrite ^/develop/(.+)$ /develop/index.php?kohana_uri=$1 last;
    }

    # Prevent Kohana's system files from being publicly accessed.
    # Throw a forbiden error message to the user
    location ~* ^/develop/(modules|application|system) {
        return 403;
    }

    # Include PHP support. The PHP configuration is in file
    # called php_conf in the same folder as this file
    include php_conf;

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    location ~ /\.ht {
        deny all;
    }
}

PHP configuration
PHP configured to run via php5-fpm. The php_conf file is also at   /etc/nginx/sites-available

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
location ~ \.php {
    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   $document_root$fastcgi_script_name;
    fastcgi_param SCRIPT_NAME       $fastcgi_script_name;
    fastcgi_param REQUEST_URI       $request_uri;
    fastcgi_param DOCUMENT_ROOT     $document_root;
    fastcgi_param REMOTE_ADDR       $remote_addr;
    fastcgi_param REMOTE_PORT       $remote_port;
    fastcgi_param SERVER_NAME        $server_name;
    fastcgi_param SERVER_PROTOCOL   $server_protocol;
   
    fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
    fastcgi_param  SERVER_SOFTWARE    nginx;

    fastcgi_param REDIRECT_STATUS   200;
    fastcgi_split_path_info ^(.*\.php)(.*)$;
    fastcgi_param PATH_INFO         $fastcgi_path_info;
    fastcgi_intercept_errors        on;
    fastcgi_index                   index.php;

    # PHP5-fpm configured to run via socket instead of TCP
    fastcgi_pass unix://var/run/php5-fpm.sock;
   
}

After giving it a spin, my web apps load faster compared to when they were in the hands of Apache. I now have an execution speed of 0.411 versus 1.227. I did a little experiment. I turned on profiling in Ushahidi’s main controller and ran Ushahidi using Nginx and Apache. See the images below for the final result. Pay attention to the total execution times.

Nginx

Ushahidi running on Nginx

Ushahidi running on Nginx

Apache2

Ushahidi running on Apache

Ushahidi running on Apache


If you have an Ushahidi install and want to switch to Nginx, feel free to copy my configuration but remember to modify it to fit your setup.