Never Ending Security

It starts all here

Setup Nginx + php-FPM + apc + MariaDB on Debian 7 – The perfect LEMP server

Debian webserver

Debian is a great choice for setting up linux webservers. According to current stats it is the most popular server OS followed closely by centos. I am a great fan of the apt/dpkg/gdebi commands, which make it so easy to install and update packages on the system.

To setup a complete functional php webserver, you need to install a couple of extra things which include a webserver and a database. In this post we shall be setting up nginx, php, php-fpm, apc and MariaDB.

Nginx is a modern webserver, that has been designed to handle large amounts of traffic using the least amount of resources in terms of RAM and CPU. Before nginx the traditional webserver used through out the internet was apache. However as the internet became more populated, the need for a faster and efficient webserver grew.

Nginx vs Apache

Apache by design is very bulky and has tons of features, most of which are not necessary for typical websites. It was probably designed to satisfy everyone’s needs, but this ended up making it a large and heavy webserver with mostly unused features.

Nginx on the other hand is a very sleek and swift webserver that focuses entirely on speed, scalability, and efficiency. The technicals of how it does so are large and beyond the scope of this post. May be we could take a look later on. Just for your information this website runs on nginx.

Now without any further discussion lets get to work.

1. Install Nginx on Debian

The nginx package is right there in the debian repositories so you dont have to look anywhere else. Fire up apt-get and install it.

# apt-get install nginx

Now launch the nginx server.

# service nginx start
Starting nginx: nginx.

Now access the nginx server from browser by opening the url


and you should get the welcome message

Welcome to nginx!

Important notes

There are few things you should memorise to manage your nginx server better. The nginx configuration files are found in the following location

root@localhost:/etc/nginx# ls
conf.d		koi-win		  naxsi.rules	scgi_params	 uwsgi_params
fastcgi_params	mime.types	  nginx.conf	sites-available  win-utf
koi-utf		naxsi_core.rules  proxy_params	sites-enabled

We shall not modify the nginx.conf file directly. Instead we create a separate configuration file for each vhost/site and save it in the following directories.


This is similar to apache. The sites-enabled directory contains the configurations for vhosts that are to be enabled. It contains symlinks to the corresponding configuration files in sites-available directory.

Setup a virtualhost

Now that we have installed nginx, its time to setup a virtual host. This is what you would be doing on a real webserver to setup your site.

Inside /etc/nginx/sites-available you would see a file named default. It is a template file to create your own configuration files. Just copy it and name it to your site.

# cp default
root@localhost:/etc/nginx/sites-available# ls  default

We choose to name the configuration files with the site name, so that it is easier to remember and maintain.
Now open up and edit the things as per your need.
You would see a server block similar to this

server {
	#listen   80; ## listen for ipv4; this line is default and implied
	#listen   [::]:80 default_server ipv6only=on; ## listen for ipv6

	root /usr/share/nginx/www;
	index index.html index.htm;

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

This first thing to configure here is the server_name. Name it to your site. For example


When someone opens in his browser, the http header contains this hostname which nginx would pickup and search for a matching server block. When a matching server block is found, it would use the configuration from that particular server block.

Another thing to configure is the web root directory for this site/vhost. Note that this is by default/usr/share/nginx/www which you might want to change to something else.

The general convention is to have a separate directory for each vhost. For example


So create an appropriate directory and point the root setting in the configuration file to the directory.

root /usr/share/nginx/www/;

After doing these changes, save the configuration file and create a symlink the /etc/nginx/sites-enabled directory.

root@localhost:/etc/nginx/sites-available# ls  default
root@localhost:/etc/nginx/sites-available# cd ..
root@localhost:/etc/nginx# cd sites-enabled/
root@localhost:/etc/nginx/sites-enabled# ln -s ../sites-available/ 
root@localhost:/etc/nginx/sites-enabled# ls  default

Now test your new configuration

# nginx -t
nginx: [warn] conflicting server name "localhost" on, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

The last line of the output must say successful, or some error would be shown. It might show some warnings which can be fixed later.

Finally restart nginx for the new configuration to take effect

# service nginx restart
Restarting nginx: nginx: [warn] conflicting server name "localhost" on, ignored

So the new configuration has taken effect. Now create a new index.html file in the new web root of this virtual host and open it from the browser and it should work.

2. Install php and php-fpm

The next thing to install is the php interpreter and php-fpm. Php-FPM is dedicated fastcgi process manager for php that can interface or connect with any compatible webserver and manage php processes to process php requests.

Nginx <== communicates ==> Php-FPM <== manages ==> php child process

Install the necessary packages first.

# apt-get install php5 php5-fpm

It will automatically install the necessary dependencies. You can install php5-cli package also if you need the php command to run php scripts.

Php-fpm runs as a separate server and nginx communicates with it over a socket. Hence the php execution is totally outside the server. Also since fpm keeps php process persistent, it fully supports APC.

Now locate the php fpm configuration files. The files at located at


A pool is a bunch of php processes running with same user/group. So if you want the php files of each site to run with a separate user permission, then you need to create separate pools of fpm. For simplicity sake we just showing a single pool here.

The pool configuration files are inside the pool.d directory. Navigate in

root@localhost:/etc/php5/fpm/pool.d# ls

Open the http://www.conf file which is again a template for you to use and create separate configuration files for each pool.
It looks something like this

; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('www' here)

; Per pool prefix
; It only applies on the following directives:
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = www-data
group = www-data

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   ''    - to listen on a TCP socket to a specific address on
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses on a
;                            specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php5-fpm.sock

; Set listen(2) backlog.
; Default Value: 128 (-1 on FreeBSD and OpenBSD)
;listen.backlog = 128

The above thing consists of comments mostly and the most important 4 lines are

1. [www]  this is the pool name  2. user = www-data  this is the user with whose permissions the php script would be run  3. group = www-data this is the group  4. listen = /var/run/php5-fpm.sock this is the socket for communicating with this pool. This socket must be given to nginx for nginx to be able to talk to fpm

Connect fpm with nginx

We are not going to change much here. Just note down the socket path. We have to put this into the nginx configuration file. Go back to your nginx configuration and open it again.

It contains a section for php fpm configuration which looks like this

# pass the PHP scripts to FastCGI server listening on
#location ~ \.php$ {
#	fastcgi_split_path_info ^(.+\.php)(/.+)$;
#	# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#	# With php5-cgi alone:
#	fastcgi_pass;
#	# With php5-fpm:
#	fastcgi_pass unix:/var/run/php5-fpm.sock;
#	fastcgi_index index.php;
#	include fastcgi_params;

Uncomment it and make it look like this

location ~ \.php$ {
	fastcgi_split_path_info ^(.+\.php)(/.+)$;
#	# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

#	# With php5-cgi alone:
#	fastcgi_pass;
	# With php5-fpm:
	fastcgi_pass unix:/var/run/php5-fpm.sock;
	fastcgi_index index.php;
	include fastcgi_params;

Test PHP

Now put up a file in the web root with the phpinfo call.


And then open the file in browser and the php information block should come up, saying that php is setup and working correctly.


Another thing that you can do is add index.php to the index files list. So that when accessing a directory, if no file is specified, then index.php gets called.

root /usr/share/nginx/www/;
index index.html index.htm index.php;

Setup apc – alternate php cache

APC is a great way to speed up the execution of php scripts. Apc compiles php code and keeps the opcode in memory and uses it next time without compiling the same php code again from file. This drastically speeds up execution. Apart from opcode cache, apc also offers a user cache to store raw data for the php application in memory.

Php as of version 5.5 has new feature called OPcache which does the same thing as apc opcode cache thereby deprecating apc.

Setting up apc is very simple and quick. Just install the apc package for php

# apt-get install php-apc

Then restart php fpm

# service php5-fpm restart

Now check the phpinfo page again and it should have the apc details as well. The apc configuration file is located at


The configuration can be tweaked a bit for optimal performance for your needs. Here is the kind of configuration that I use

Check the list of apc configuration parameters for more information.

3. Install MariaDB on Debian

Now comes the last and final component of the LEMP stack. That is the MariaDB database and not mysql. Well by now you should be knowing that mysql is in the hands of oracle and no more a community belonging. So major corps have started switching to mariadb. The good thing is that mariadb is binary compatible with mysql with lots of additional features. So if you are already using mysql for your php applications then shifting to mariadb would be absolutely hassle free.

MariaDB is not present in the debian repositories. To get the repositories visit the following page

Select Debian as the distro, Wheezy as the release and version 10.0 of mariadb. Then select a mirror on the right side. Now scroll down to the bottom of the page to find the repository details.

Here are the commands that I got

sudo apt-get install python-software-properties
sudo apt-key adv --recv-keys --keyserver 0xcbcb082a1bb943db
sudo add-apt-repository 'deb wheezy main'

Now update the apt cache and install the mariadb packages

sudo apt-get update
sudo apt-get install mariadb-server mariadb-client

While installation mariadb would ask for the password of user root. Enter the password and make sure not to forget.

After the installation finishes check your mariadb version

# mysql -V
mysql  Ver 15.1 Distrib 10.0.3-MariaDB, for debian-linux-gnu (x86_64) using readline 5.1

Note that the command name is same as with mysql. But the name mariadb is there in the version information.

Webserver is ready

So now the LEMP web server is ready to use. You may want to install a couple of extra goodies like phpmyadmin to manage your database better. Phpmyadmin is there in the debian repository so install it right from there.

Have any questions ? Feel free to comment below.

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s