Back to top

Building Nginx (Microcaching) + MariaDB/MySQL + PHP-FPM + Debian 6 + APC + Memcache + Drupal 7 server

It has been 2 years, since I have written Build Nginx + PHP-FPM + APC + Memcache + Drupal 7 on a bare-bone Ubuntu 10.04 or Debian 5 server. Since then, many people and companies have informed me that they have been using the setup from that blog.

2 years is quite a long time; a lot of softwares are updated, and a lot of configuration & practice have changed. Now, it's the time for a REBUILD:

Again, let's start with getting an account with (Linode), login with ROOT:
Basic server configuration
Set up Hostname
echo "plato" > /etc/hostname
hostname -F /etc/hostname

# Edit /etc/hosts (IPv6)
# add: plato
2600:3c01::a123:b456:c789:d012 plato

# Configurate timezone
dpkg-reconfigure tzdata

# update server packages
nano /etc/apt/sources.list

# add two lines below:

deb squeeze all
deb-src squeeze all

cat dotdeb.gpg | apt-key add -

apt-get update
apt-get upgrade --show-upgraded

Secure the server
# add a system admin account
adduser example_user
usermod -a -G sudo example_user
ssh example_user@123.456.78.90

# From now on, we use the new admin account with sudo.

# disable the root SSH access
sudo nano /etc/ssh/sshd_config
# update this line:PermitRootLogin no
sudo service ssh restart

# Configure firewall:
sudo iptables -L
sudo nano /etc/iptables.firewall.rules
# Paste:

# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT

# Accept all established inbound connections

# Allow all outbound traffic - you can modify this to only allow certain traffic

# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT

# Allow SSH connections
# The -dport number should be the same port number you set in sshd_config
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT

# Allow ping
-A INPUT -p icmp -j ACCEPT

# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

# Drop all other inbound - default deny unless explicitly allowed policy


sudo iptables-restore

# Make firewall auto-run after the reboot:
sudo nano /etc/network/if-pre-up.d/firewall


sudo chmod +x /etc/network/if-pre-up.d/firewall

# Install Fail2Ban, which auto-dectect simple attack and stop it:
sudo aptitude install fail2ban

Install PHP-FPM
sudo aptitude install php5 php5-cli php5-dev php5-gd php-pear php5-fpm php5-geoip libgeoip1 libgeoip-dev geoip-database

# Update some settings:
sudo nano /etc/php5/fpm/php.ini
memory_limit: 512M

Install Nginx
sudo aptitude install nginx

# configure virtual hosting
sudo mkdir -p /srv/www/{public_html,logs}
sudo chown -R www-data:www-data /srv/www
sudo chmod -R 775 /srv/www
cd /etc/nginx/sites-available/
sudo wget
# You need to input the correct domain names that you are using, so edit it:
sudo nano

sudo nano /etc/php5/fpm/pool.d/www.conf
# change line "listen =" to: (using socket is faster!)
listen = /tmp/php-fpm.sock
sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled

Configure Nginx Microcache (Also, putting Microcache into memory,FEEL the lightning SPEED)
sudo nano /etc/nginx/conf.d/microcache.conf
fastcgi_cache_path /dev/shm/microcache levels=1:2 keys_zone=microcache:5M max_size=1G inactive=2h;
map $http_cookie $cache_uid {
default nil; # hommage to Lisp :)
~SESS[[:alnum:]]+=(?<session_id>[[:alnum:]]+) $session_id;

map $request_method $no_cache {
default 1;
GET 0;
# Make Nginx auto-run afer reboot:
sudo update-rc.d nginx defaults

# boot Nginx
sudo /etc/init.d/nginx start

Install MariaDB
Long story in short, Since Oracle bought MySQL, many of the original developers left and started the new thing ---- MariaDB. So, it's a drop in replacement for MySQL. You can treat them as the same thing.
sudo nano /etc/apt/sources.list.d/MariaDB.list

# MariaDB 5.5 repository list - created 2012-12-08 07:39 UTC
deb squeeze main
deb-src squeeze main

sudo apt-key adv --recv-keys --keyserver 0xcbcb082a1bb943db

sudo aptitude update
sudo aptitude install libmariadbclient-dev libmariadbclient18 libmariadbd-dev libmysqlclient18 mariadb-client mariadb-client-5.5 mariadb-client-core-5.5 mariadb-common mariadb-server mariadb-server-5.5 mariadb-server-core-5.5 mariadb-test mariadb-test-5.5 mysql-common

Install Drupal
cd /srv/www/
sudo wget
sudo tar -xvzf drupal-7.18.tar.gz
cd drupal-7.18
sudo cp -a . ../public_html/
sudo chown www-data:www-data public_html -R

Install Memcache, APC
sudo aptitude install memcached libmemcached-tools memstat make
sudo pecl install memcache
sudo pecl install apc

# Create the file below for Memcache
sudo nano /etc/php5/conf.d/memcache.ini

# Create the file below for APC
sudo nano /etc/php5/conf.d/apc.ini
apc.shm_size = 256M
apc.apc.stat = 0

Install uploadprogress
sudo pecl install uploadprogress

# Create the file below for uploadprogress
sudo nano /etc/php5/conf.d/uploadprogress.ini

# Reboot:
sudo service nginx restart
sudo service mysql restart
sudo service php5-fpm restart
sudo service memcached restart


If you need high performance Drupal server consulting service,please contact INsReady




Very nice guide.
Shouldn't you install php5-mysql?

I am having a 61 join


I am having a 61 join limitation on my Drupal 6, probably because my views and content types are too complicated for MySQL. Do you think MariaDB would remove this limit?

Having some problems with firewall rules


Hi, great tutorial. Everything works great except, perhaps I am making a mistake, in the firewall rules. maybe I am overlapping the steps or mixing up the rules. Could you please separate / clarify the same?

... recurrent error at 'sudo pecl install apc'


Hi, I was thrilled to find your guide here... just what I was looking for!!

So, I've followed it to the letter, with the exception of using the drupal repositories for 7.21 especially as the connection to kept failing...
(another small issue at "sudo cp -a . ../public_html/" ... I had to first create the 'public_html' directory myself)

The main issue: got all the way to issuing the "sudo pecl install apc" command and am getting an error I don't know how to deal with or even interpret [everything else looked fine, so I'm just posting the last few lines of output which contained the error]:

running: make
/bin/bash /tmp/pear/temp/pear-build-rootZlgTaM/APC-3.1.13/libtool --mode=compile cc -D_GNU_SOURCE -I. -I/tmp/pear/temp/APC -DPHP_ATOM_INC -I/tmp/pear/temp/pear-build-rootZlgTaM/APC-3.1.13/include -I/tmp/pear/temp/pear-build-rootZlgTaM/APC-3.1.13/main -I/tmp/pear/temp/APC -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -g -O2 -c /tmp/pear/temp/APC/apc.c -o apc.lo
libtool: compile: cc -D_GNU_SOURCE -I. -I/tmp/pear/temp/APC -DPHP_ATOM_INC -I/tmp/pear/temp/pear-build-rootZlgTaM/APC-3.1.13/include -I/tmp/pear/temp/pear-build-rootZlgTaM/APC-3.1.13/main -I/tmp/pear/temp/APC -I/usr/include/php5 -I/usr/include/php5/main -I/usr/include/php5/TSRM -I/usr/include/php5/Zend -I/usr/include/php5/ext -I/usr/include/php5/ext/date/lib -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DHAVE_CONFIG_H -g -O2 -c /tmp/pear/temp/APC/apc.c -fPIC -DPIC -o .libs/apc.o
In file included from /tmp/pear/temp/APC/apc.c:45:0:
/usr/include/php5/ext/pcre/php_pcre.h:29:18: fatal error: pcre.h: No such file or directory
compilation terminated.
make: *** [apc.lo] Error 1
ERROR: `make' failed

any help/direction you can offer is so very appreciated...


~ Max

Add new comment