Chili Pepper Design

Web development relleno

Configuring and Compiling Nginx and PHP-FPM on Ubuntu for Magento, Part 3

| Comments

This is the 3rd and final article about installing Magento on Nginx with PHP-FPM. Part 1 is here, and Part 2 is here.

This part explains how I set up my public web directories, and how I did the Nginx configuration files for a Magento site. One of the tricky things about switching to Nginx from Apache is that Nginx does not use .htaccess files or the usual Apache mod_rewrite rules for pretty/SEO URLs. You can replicate all of Magento’s mod_rewrite rules with Nginx’s own rewrite module, but it takes some getting used to and Magento doesn’t come with them pre-written (like the mod_rewrite rules in the .htaccess files).

Here are some of the resources I used:

First we’ll set up the directory structure like we are used to with Apache:


# mkdir /usr/local/nginx/sites-available
# mkdir /usr/local/nginx/sites-enabled
# mkdir /var/www/example1.com/public
# mkdir /var/www/example1.com/log
# cp  /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf-original

Then set up the base nginx conf file /usr/local/nginx/conf/nginx.conf:


user www-data;
worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    include /usr/local/nginx/sites-enabled/*;
}

Then set up the Nginx conf file for your website. I am using the default site in this example /usr/local/nginx/sites-available/default, but if you have multiple sites instead of default you would create files called site1.com, site2.com, etc.

This file is where all of the rewrite magic is. The url in this example is example1.com, which you should replace with your own. The document root is /var/www/example1.com/public which, again, you will need to change to match your own configuration.


# fastcgi nodes
upstream  backend  {
    server unix:/tmp/fcgi.sock;
}

# redirect all non-www requests to www requests (it would be easy to reverse this)
server {
    listen   80;
    server_name  example1.com;
    rewrite ^/(.*) http://www.example1.com/$1 permanent;
}

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

    # protection (we have no .htaccess)
    location ~ (/(app/|includes/|lib/|/pkginfo/|var/|report/config.xml)|/\.svn/|/.hta.+) {
        deny all;
    }
   # pass php files over to PHP-FPM via the socket
    location ~ (\.php)$ {
        fastcgi_index index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        if (-e $request_filename) { # check if requested path exists
            fastcgi_pass backend;
        }
    }
    # the javascript compressor
    location ^~ /js/index.php {
        fastcgi_pass   backend;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_NAME $fastcgi_script_name;
        fastcgi_param  SCRIPT_FILENAME  /var/www/example1.com/public$fastcgi_script_name;
        include /etc/nginx/fastcgi_params;
        access_log off;
        expires 30d;
    }
   # special case for the error "report" pages
    location /report/ {
        fastcgi_index index.php;
        include /etc/nginx/fastcgi_params;
        fastcgi_param  SCRIPT_NAME /report/index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/example1.com/public/report/index.php;
        if (!-f $request_filename) {
            fastcgi_pass backend;
            break;
        }
    }
    # pass everything else over to PHP-FPM via the socket
    location / {
        root /var/www/example1.com/public/; # absolute path doc root
        index index.php index.html index.htm;

        # set expire headers
        if ($request_uri ~* "\.(ico|css|js|gif|jpe?g|png)$") {
            expires max;
        }
        # set fastcgi settings, not allowed in the "if" block
        include /etc/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        fastcgi_param SCRIPT_NAME /index.php;
        # rewrite - if file not found, pass it to the backend
        if (!-f $request_filename) {
            fastcgi_pass backend;
            break;
        }
        error_page 404 index.php;
    }
    access_log /var/www/example1.com/log/access.log;
    error_log /var/www/example1.com/log/error.log;
}

I am no expert with Nginx, but a lot of Google searching and trial and error gave me the file above, and it seems to work. I hope it is helpful, even if this exact code doesn’t work for you.

Finally, activate the site by creating a symbolic link to it and restarting the server:


# ln -s /usr/local/nginx/sites-available/default /usr/local/nginx/sites-enabled/default
# ln -s /usr/local/nginx/sites-enabled /etc/sites
# /etc/init.d/nginx restart

And that’s it! You should now have Magento running on Nginx! (After, of course, also installing mysql and a sendmail program, and probably an FTP server, and who knows what else :)

Now, how to make it actually go faster than Apache? There are many settings you can tweak. Look in fastcgi_params to change PHP-FPM settings, php.ini to change APC settings, my.cnf to change mysql settings, nginx.conf to adjust the number of worker processes and the keepalive timeouts… the list goes on. Good luck!

Comments