Running Drupal on Nginx with Memcached
Drupal is a great CMS system for deploying websites quickly and managing them easily. Traditionally Drupal was run on a LAMP stack, but this configuration does not necessarily offer the best performance for the system. These days you can squeeze more performance out of Drupal by running it on a LEMP (Linux-Nginx-MySQL-PHP) stack in which Apache is replaced by the Nginx reverse-proxy. Further performance improvement can be gained by hooking up memcached to handle cacheing. This article explains how you can prepare a professional LEMP server for your Drupal sites.
Prerequisites
I assume you have a server available on which you have root privileges. I am using a server running Debian 7, so everything here should work the same on an Ubuntu server or other Debian-based distribution. If you're using an RPM-based distro (such as CentOS), you will need to replace the apt-get
commands by their yum
counterparts.
If you don't have a server to play with, I would recommend the inexpensive VPS servers offered by Digital Ocean. If you click through this link when signing up, you'll pay a bit of my server bill :)
I'm also assuming you configured your DNS to point a domain at the server's IP. In this text, I assume it's example.com
Update your system
It'a always a good idea to keep every part of your system up-to-date and since APT makes is so simple, let's start with an update of the APT cache and a system upgrade (installing up-to-date versions of all packages).
$ sudo apt-get update
$ sudo apt-get upgrade
Install MySQL
$ sudo apt-get install mysql-server
During the installation process you will be asked for a password for the root user. If you don't set it during installation, you can set it later using the following command (substitute a password for NEWPASSWORD).
$ mysqladmin -u root password NEWPASSWORD
Install Nginx
$ sudo apt-get install nginx
$ sudo service nginx start
You can navigate to your server (http://example.com) with your browser and Nginx should greet you with the words "Welcome to nginx!".
Install PHP-FPM
Under Apache PHP code is executed by the web server (via mod_php). The Nginx philosophy is somewhat different. It's a reverse proxy rather then a server, so it's not running any code itself. Instead it can serve (proxy) data generated by CGI applications running on your system.
For PHP this is PHP-FPM (FastCGI Process Manager). This is a daemon process which waits for incoming requests to execute PHP code, runs the scripts and returns their output. More information can be found on the PGP-FPM site.
sudo apt-get install php5-fpm
Configure PHP-FPM
Edit the /etc/php5/fpm/php.ini
and change cgi.fix_pathinfo to 0.
sudo vim /etc/php5/fpm/php.ini
; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
; previous behavior was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting
; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
; http://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=0
Now check the php5-fpm configuration file /etc/php5/fpm/pool.d/www.conf
and make sure that php5-fpm communicates with the outside world through a socket file:
Restart the php-fpm service:
sudo service php5-fpm restart
Install Drush and Drupal
Install Drupal dependencies
$ sudo apt-get install php5-mysql
$ sudo apt-get install php5-gd
Create a MySQL database and user for Drupal.
$ mysql -u root -p
mysql> CREATE DATABASE example;
mysql> GRANT ALL PRIVILEGES ON example.* TO example@localhost IDENTIFIED BY 'hskd7e345kfi';
Install Drush
$ sudo apt-get install drush
Install Drupal in any way you prefer, for instance using Drush like this:
$ cd /webapps/ # Or wherever you want to keep your sites
$ drush dl drupal-7.22
$ mv drupal-7.22/ example-drupal
$ cd example-drupal
$ drush site-install standard --account-name=admin --account-pass=admin --db-url=mysql://example:hskd7e345kfi@localhost/example
Create an Nginx virtual server configuration for Drupal
Each Nginx virtual server should be described in a file in the /etc/nginx/sites-available
directory. You select which sites you want to enable by making symbolic links to those in the /etc/nginx/sites-enabled
directory.
Create a new nginx server configuration file for your Drupal site running on example.com in /etc/nginx/sites-available/example-drupal
. The file should contain something along the following lines. A good explanation can be found on the Nginx wiki.
Restart Nginx:
$ sudo service nginx restart
You can now visit your Drupal site at http://example.com and log in as admin with the password admin. Remember to change your password.
Add memcached as Drupal's cache backend
Install memcached and the memcache PHP extension.
$ sudo apt-get install memcached
$ sudo apt-get install php5-memcached
Edit the php.ini file to enable the extension and configure memcache. At minimum add the following lines:
In order to enable memcached-based cacheing on your Drupal site, you will need to download and enable the memcache module:
$ cd /webapps/example-drupal
$ drush dl memcache
$ drush en memcache
You will also need to add cache_backends
configuration to your settings.php file.
$ vim sites/default/settings.php
Add the following lines:
$conf['cache_backends'][] = 'sites/all/modules/memcache/memcache.inc';
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
Your site is now cached using memcache. You can enable a module which installed along memcache, which will display a summary of how many memcache hits or misses were executed during the generation of every page in the admin.
$ drush en memcache_admin
That's it, I hope it helps. If you have any problems or see areas which could be improved, feel free to leave me a comment or send me a message.