How to configure Nginx, PHP-FPM, MySQL, Memcached, APC and Drush for Drupal 7 on Debian 7.0 Wheezy

August 15, 2013

This setup is only tested only on Debian 7 "Wheezy" distribution. Although with small changes will also work on Debian 6, and of course Ubuntu (it's easier setup).

My goal is to make stable Debian based VPS for use of Drupal 7 with Nginx and PHP-FPM. Last post have covered basics and is for Debain 6 "Sgueeze" (you can read here How to setup Nginx + PHP-FPM + Drupal 7.0 on Debian Squeeze).

In this post I have covered much widely use of Nginx, primarily based on perusio & troubleshooter configuration.
My blog and several other sites currently using this setup on small VPS on DigitalOcean (2GB Ram, 2CPU).

Also with this setup, all Drupal features works (clean URL, multi site, etc..)

First you need clean minimal installation of Debian 7.
(if you try on existing server, probably some erros will appear, post below comments)

Update & Upgrade

apt-get update
apt-get upgrade

Timezone change (if you do not need to change timezone, ignore this step)

dpkg-reconfigure tzdata

Adding repository (edit /etc/apt/sources.list and add links to dotdeb repository)

vi /etc/apt/sources.list
deb http://packages.dotdeb.org wheezy all
​deb-src http://packages.dotdeb.org wheezy all

Adding keys for the repository

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | sudo apt-key add -

Update & Upgrade

apt-get update
apt-get upgrade

Nginx & Mysql & Memcached installation

apt-get install nginx-extras mysql-server mysql-client memcached

You probably noticed that I use nginx-extras package, you can see comparison between available Nginx packages here.
(all configuration files later in this setup are made for nginx-extras, so if you install other nginx package, some stuff will not work, but you can remove them from suggested nginx configuration)

PHP-FPM & APC installation

apt-get install php5-fpm php5-gd php5-mysql php-apc php-pear php5-cli php5-common php5-curl php5-mcrypt php5-cgi php5-memcached

Drush installation (v5.9)

pear channel-discover pear.drush.org
pear install drush/drush

_(if you want double check which drush version is installed, enter in terminal this line: drush version)

Nginx & PHP-FPM restart
While now is installed all necessary, it's not yet needed to restart, but is not bad to check if default stuff are installed properly without errors.

/etc/init.d/php5-fpm restart
/etc/init.d/nginx restart

PHP-FPM configuration & multiple pool
This PHP5-FPM pool configuration uses three pools, www1, www2 and www3 and unix sockets (defined in upstream_phpcgi_unix.conf). You need to create three pools or alternatively, change upstream_phpcgi_unix.conf to match your existing PHP5-FPM configuration.

cd /etc/php5/fpm/pool.d
mv www www1
cp www1 www2
cp www1 www3

Now we have three pools, and is needed to change in each of this files reference to sockets (each pool require its own socket). Or you can download all three files below and upload them to folder /etc/php5/fpm/pool.d

vi /www1
line 4 - rename www to www1
line 33 - put listen path to: /var/run/php5-fpm-www1.sock

vi /www2
line 4 - rename www to www2
line 33 - put listen path to: /var/run/php5-fpm-www2.sock

vi /www3
line 4 - rename www to www3
line 33 - put listen path to: /var/run/php5-fpm-www3.sock

Nginx configuration for Drupal

1. Remove default nginx configuration (backup)

mv /etc/nginx /etc/nginx.old

2. Getting troubleshooter configuration from github
This configuration has several changes from original perusio configuration, and is only for Drupal 7.
While perusio configuration you can use on both 6 and 7 version of Drupal.

cd /etc
git clone https://github.com/troubleshooter/drupal7-with-nginx.git​
mv drupal7-with-nginx nginx

3. Adjust nginx for your domain
In folder /etc/nginx/sites-available you will find configuration for example.com domain.Rename this file to yourdomain.com.conf

cd nginx/sites-available
mv example.com.conf yourdomain.com.conf

After that you need to change domain name in this file for your need. Replace all reference for example.com to yourdomain.com.

vi yourdomain.com.conf

Additional, path to root of your site is then /var/www/sites/yourdomain.com, this adjust fo your needs. (e.g in my setup all sites are /var/www/mydomain.com

Also, additional if you want that server do not listen for IPv6, comment all reference to them. Or if you want that server listens on exact IPv6 address, insert them in nginx config. You can see which IPv6 address have the server with this command:

ip -f inet6 addr show eth0

3. Nginx microcache
Microcaching requires the presence of /var/cache/nginx/microcache directory which don't exist by default. You must create it and grant the appropriate permissions to the Nginx user (in Debian 7 it's www-data)

mkdir /var/cache/nginx/
mkdir /var/cache/nginx/microcache/
chown www-data:www-data /var/cache/nginx/microcache

4. Nginx SSL
This Nginx configuration requires SSL (if you do not want SSL, skip this step, but you need then adjust Nginx configuration). Below are instruction for generating self-signed certificate, and location for them are following current Nginx configuration. You can adjust all this for your needs.

Create directory

mkdir /etc/nginx/ssl

Generate key & certificate

openssl genrsa -des3 -out ssl.key 1024
(enter your key)

openssl req -new -key ssl.key -out server.csr
(enter your information for certificate)

cp ssl.key ssl.key.org
openssl rsa -in ssl.key.org -out ssl.key

openssl x509 -req -days 365 -in server.csr -signkey ssl.key -out ssl-unified.crt

Moving key and certificate according to current nginx configuration (or edit location in yourdomain.com.conf)

mkdir /etc/nginx/ssl/certs/
mv ssl-unified.crt /etc/nginx/ssl/certs/ssl-unified.crt

mkdir /etc/nginx/ssl/private
mv ssl.key /etc/nginx/ssl/private/ssl.key

5. Enabling your site configuration
Final step for Nginx is to create sites-enabled folder, and then create symlinks to sites which you want to enable

mkdir /etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/000-default.conf /etc/nginx/sites-enabled/000-default.conf
ln -s /etc/nginx/sites-available/yourdomain.com.conf /etc/nginx/sites-enabled/yourdomain.com.conf

Nginx & PHP-FPM restart
This should be last step, restart PHP-FPM and Nginx.

/etc/init.d/php5-fpm restart
/etc/init.d/nginx restart

If Nginx throw error regarding types_hash, server_names or variables try to uncomment following lines and change values in /etc/nginx/nginx.conf :

variables_hash_max_size 1024; # default 512
variables_hash_bucket_size 64; # default is 64

or add this two lines

types_hash_bucket_size 2048;
server_names_hash_bucket_size 64;

Now you should have configured Nginx & PHP-FPM & APC & Memcached and Drush on Debian 7.
At last drupal installation or migration is needed.

WWW directory
By default /var/www directory do not exist, so we need to create them and assign ownership to www-data group
(if your work with www-data group as you should, drush need read/write permission)

mkdir /var/www
chown www-data:www-data /var/www

Drupal installation (switching to www-data)

su www-data
cd /var/www
wget http://ftp.drupal.org/files/projects/drupal-7.23.tar.gz
tar -xzvf drupal-7.23.tar.gz
mv drupal-7.23 yourdomain.com

Additional configuration
APC - tweak your APC settings with following or adjust to your needs

vi /etc/php5/mods-available/apc.ini

add this lines:

apc.enabled=1
apc.shm_segments=1
apc.shm_size=64M
apc.ttl=7200
apc.write_lock = 1
apc.slam_defense = 0

Memcached
Configuration file is located in etc folder: /etc/memcached.conf.
Probably is good to increase memory poll at least to 128MB (default is 64MB)
Change line 23 from -m 64 to -m 128

PHP-FPM & Nginx & Mysql

All further tweaking depends also on your server and Drupal sites. High traffic sites need a lot more tweaking from this. You have some example of configuration for mysql, php-fpm, etc.., but use them with caution

Additional resources Nginx & PHP-FPM for Drupal
More about Nginx for Drupal 7 you have on following links, also configuration which I used is well documented on github.

Files
mysql-78.zip
nginx-77.zip
php-fpmpool-76.zip