Install, Configure & Optimise NGINX on Debian Squeeze

nginx (pronounced “engine-x”) is a Web server and a reverse proxy server for HTTP, SMTP, POP3 and IMAP protocols, with a strong focus on high concurrency, performance and low memory usage. According to BuiltWith, it is used on 9.92% of the top 1 million websites, and its growth within the top 10k, 100k and 1 million segments is increasing.

The purpose of this tutorial is to install and configure NGINX (to host WordPress sites) on a low end cloud server (256MB instance from Rackspace).

Step 1 : Add the Dotdeb repository

The version of NGINX in the Debian repository is slightly outdated. We need to grab the latest version of NGINX to benefit from all new updates and bug fixes. Read this article on Adding the Dotdeb repository to your Rackspace Cloud (Debian Squeeze) Server.

Step 2 : Install NGINX

The following command will do it all. It will also start the NGINX service and add it to the server startup.
[shell]apt-get install nginx[/shell]

Step 3 : Configure & optimise NGINX

The NGINX package from Dotdeb comes bundled with all the key modules. The configuration file is pretty good too. We’ll still need to make some changes as our cloud server instance is just 256MB. Open
[text]/etc/nginx/nginx.conf[/text] using your preferred editor. The following are some settings that you can change / add.
worker_processes 2
worker_connections 1024
server_tokens off;

# Timeout Settings

client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;

# Gzip Settings – For improving (SEO) page speed

gzip on;
gzip_static on;
gzip_comp_level 6;
gzip_disable “msie6”;
gzip_vary on;
gzip_types text/plain text/css text/xml text/javascript application/json application/x-javascript application/xml application/xml+rss;
gzip_proxied expired no-cache no-store private auth;
gzip_buffers 16 8k;
gzip_http_version 1.1;
The above are just a few critical ones. You can refer to the NGINX documentation if you would like to further optimise NGINX.

Step 4 : Create virtual hosts for multiple domains

Create the following folders to store the website’s files, scripts and logs. The third command will make NGINX (www-data user) own the website files.
mkdir -p /var/www/domain/httpdocs
mkdir /var/www/domain/logs
chown -R www-data:www-data /var/www/
Create a domain vhost configuration file at this location.
The filename can be anything. e.g. domainname.conf, domainname, domainname.tld, etc. Create a symlink to this domain’s vhost configuration file from [text]/etc/nginx/sites-enabled/[/text] using the following command.
[shell]ln -s /etc/nginx/sites-available/filename /etc/nginx/sites-enabled/filename[/shell]
The following content should go into the domain’s vhost configuration file.
server {
# This redirects the non-www version of the domain name to the www version
rewrite ^ $scheme://$request_uri? permanent;
server {
root /var/www/domain/httpdocs;
index index.html index.htm index.php;

access_log /var/www/domain/logs/access.log;
error_log /var/www/domain/logs/error.log;

location ~ \.php$ {
# The next two lines address a security flaw in NGINX.
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have “cgi.fix_pathinfo = 0;” in php.ini

include /etc/nginx/fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /var/www/domain/httpdocs$fastcgi_script_name;

# Disable index.php and make WordPress permalinks work
location / {
try_files $uri $uri/ /index.php?$args;

# Expires header to improve SEO (Google Page Speed)
location ~* \.(ico|css|js|gif|jpg|jpeg|png|xml|pdf)$ {
expires 1w;
add_header Pragma public;
add_header Cache-Control “public, must-revalidate, proxy-revalidate”;
log_not_found off;

location = /favicon.ico {
log_not_found off;
access_log off;

location = /robots.txt {
allow all;
log_not_found off;
access_log off;

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store
location ~ /\. {
deny all;
access_log off;
log_not_found off;

# Don’t log and deny access to files which end with ~, as these are usually backup files.
location ~ ~$ {
access_log off;
log_not_found off;
deny all;
The above settings should be sufficient to run a WordPress based website. We have also taken care of some key page speed improvements that Google recommends.

Step 5 : Restart NGINX

Once you have completed the above steps, you will have to restart NGINX for the new settings to take effect. You can use the following command to restart NGINX.
[shell]service nginx restart[/shell]

Step 6 : Point the domain’s A record to the server’s IP address

For the domain and the hosting to work together, you need to edit your domain’s DNS records and point the A records (@ and www) to your server’s IP address. Once the DNS change gets propagated around the web, you will be able to enter your domain name in the address bar of the browser and reach your website stored under the folder (/var/www/domain/httpdocs).