Serve websites with Nginx

Configure Nginx to serve simple websites and see how it’s a serious alternative to Apache


Nginx (pronounced Engine X) is a web server developed in Russia by Igor Sysoev back in 2002. In this article you will learn how to install and run Nginx on a Linux machine, how to configure it and how to install and use Joomla with Nginx.

The first two questions you might want to ask are “Is there a real need for another web server?” and “What’s wrong with Apache?”. The answer to the first question is that different web servers have different capabilities, so having multiple options is always a good thing. The answer to the second question has to do with the fact that Apache is a process-based server: when serving simultaneous connections, each connection requires its own dedicated thread. Nginx uses asynchronous sockets that allow it to handle more requests per process without spawning too many processes. As a result, fewer Nginx processes can serve larger amounts of HTTP requests compared to Apache. Also, the memory consumption of Nginx is very low when serving static pages and its configuration files are simpler to read, use and modify than the configuration files of Apache.

01 Install Nginx

Installing Nginx on a Debian 7 system is as simple as executing the following command with root privileges:

# apt-get install nginx

Debian 7 installs an older version of Nginx (1.2.1) but you can still do your job with it. You can manually install a new version of Nginx if you want though. The default root HTTP directory of Nginx on a Debian 7 machine is /usr/share/nginx/www, which comes with the following files inside it:

# ls -l /usr/share/nginx/www/
total 8
-rw-r--r-- 1 root root 383 Jul 7 2006 50x.html
-rw-r--r-- 1 root root 151 Oct 4 2004  index.html

02 Nginx configuration files

On a Debian 7 Linux system, the configuration files of Nginx are located inside /etc/nginx. The contents of /etc/nginx are similar to the contents of the directory where Apache puts its own configuration files (/etc/apache2). It is considered good practice to create a separate configuration file for each domain or subdomain you are going to serve and put them inside the sites-enabled directory.

Nginx comes with a sample configuration file, called default, that is located inside /etc/nginx/sites-enabled and can be used as a starting point when creating virtual hosts.

03 Serving your first site with Nginx

If you try to run Nginx on a machine where Apache is already running, it is very likely that you are going to get some error messages. The problem is that only a single server process can use a given TCP port and, as you can imagine, Apache is already using port number 80 for its own purposes; therefore you should change the default port number of Nginx. You can use any port number you want as long as it is not already in use by another process.

As you will no longer be using the default port number (80) of the HTTP service, you must manually include the selected port number at the end of the URL so that Nginx can know it.

Nginx uses worker process for serving HTTP requests and their total number is defined inside the nginx.conf file using the worker_processes variable:

# grep -i worker_processes nginx.conf worker_processes 4;

A good practice is to start with two worker processes and add more if you find out that two are not enough. Fewer worker processes means less memory used by Nginx.

04 Serve two different sites with Nginx

Although it looks like you will need to make changes to the nginx.conf file to configure Nginx, it is better to create two new files inside /etc/nginx/sites-enabled. All the contents of the files inside /etc/nginx/sites-enabled directory are automatically included in the nginx.conf file because of the following command found inside /etc/nginx/nginx.conf:

include /etc/nginx/sites-enabled/*;

For our example, the two subdomains will be named and respectively. You should also update your DNS records in order to create the two new subdomains.

05 The Nginx configuration explained

Two files were created inside /etc/nginx/sites-enabled, named lud1 and lud2, that hold the configuration for each subdomain.The supported subdomains are defined using two different server blocks, and alhough they have different access and error log files, both of them still use the same IP address as defined by their DNS records.

As you can see, both sites listen to port number 8084 (the value of the listen variable) although it is not necessary to use the same port number. You now need to create two index.html or index.htm files, one inside /srv/www/lud1/public_html and another inside /srv/www/lud2/public_html and you are done!

As you may understand, both lud1 and lud2 configuration files contain a minimalistic configuration for a static HTML site; therefore if you try to run a PHP script using the aforementioned configuration files, your web browser will try to save the PHP file instead of executing it.

06 Nginx rewrite rules

Nginx does not support .htaccess files! The functionality of a .htaccess file is embedded in the configuration file of each individual virtual domain or subdomain. The good thing is that the equivalent rewrite rules in Nginx are usually fewer and less complex than the ones used in an Apache .htaccess file.

Although converting an .htaccess file into the equivalent Nginx format looks like a lot of work, you only have to do it once. As you become more experienced with rewrite rules, you will appreciate Nginx rules and stop thinking about .htaccess files.

07 Using Nginx and PHP

Nginx does not support PHP by default. You will have to install a module to get PHP support (but Apache does the same with PHP support anyway). You should install the php5-fpm package, configure it (if needed) and run the php5-fpm server process for PHP to work.

The most important setting is the php5-fpm socket value because you will use it in your Nginx configuration file – PHP support will not work without a correct php5-fpm socket value. It is defined inside /etc/php5/fpm/pool.d/www.conf:

# grep php5-fpm /etc/php5/fpm/pool.d/ www.conf
listen = /var/run/php5-fpm.sock

If there is an error with your php5-fpm socket configuration, the error messages generated by Nginx will be similar to the following:

2014/03/24 12:53:27 [crit] 7938#0: *1 connect() to unix:/tmp/phpfpm.sock failed (2: No such file or directory) while connecting to upstream, client:, server:, request: “GET /install.php HTTP/1.1”, upstream: “fastcgi://unix:/tmp/phpfpm.sock:”, host: “”

08 Install Joomla!

The configuration file for the Joomla installation is named joo.conf and it will use the subdomain for hosting the Joomla site. Its files will be located in the /srv/www/joo directory.

Before continuing with the rest of the article, make sure that the directories mentioned in your joo.conf configuration file are created and have the correct UNIX permissions. Usually, a running nginx process uses the same UNIX user and group as Apache: www-data and root respectively. Also, make sure that you have your DBMS up and running.

If the configuration file is correct and the Joomla installation begins, it means that everything with your Nginx setup is okay. You only need to have the database related information nearby in order to finish your Joomla installation.

If you want to check the syntactical correctness, validity and integrity of your current Nginx configuration, you should run the following command:

# nginx -t

In case of an error, you will get a helpful error message:

nginx: [emerg] unknown log format “ma” in /etc/nginx/sites-enabled/lud1:7
nginx: configuration file /etc/nginx/ nginx.conf test failed

If your nginx.conf file or one of the included configuration files has multiple errors, the output of “nginx -t” will only show the first one. You have to correct the first error and rerun the command to make sure that no additional errors exist.

09 Nginx Log files

You can define you own log file format as follows:

log_format  FORMATNAME ‘$remote_addr - $remote_user [$time_local] “$request” ’
‘$status $body_bytes_sent “$http_referer” ’
 ‘“$http_user_agent” “$http_x_forwarded_for”’;

The error_log directive defines the name, the location and the logging level for the error log whereas the access_log directory defines the name, the location and the preferred format for the access log file. By default, the error log works globally; if you want to override this, place the error_log directive in the main context.

10 More about Nginx rewrite rules

You will now learn how to convert the single most useful set of Apache rules into the equal Nginx setup. The Apache rules are the following:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L]

The above rules dictate that when the filename specified in the URI is neither a file nor a directory that is physically on disk, the request is passed to index.php. This is a very popular technique as it is being used by most Content Management Systems. All three Apache rules can be translated into just one Nginx rule:

try_files $uri $uri/ /index.php?q=$uri;

If you want to deny access to all ASP and JSP pages, you will have to use the following Nginx rule that uses regular expressions:

if ($request_filename ~* .(aspx|jsp)$) {
return 404;

Usually, Nginx rules are easier to read and understand than Apache rules, but you need to train yourself in order to be able to fully translate an .htaccess file.

11 Nginx versus Apache

The only reason for Nginx to use multiple processes is to make full use of multi-core, multi-CPU and hyper-threading systems. On the other hand, as Apache uses synchronous I/O, it is obligatory to serve each request using a separate thread in order to avoid blocking.

What you should also remember is that a process-based server requires more RAM to operate, especially when trying to serve thousands of simultaneous requests whereas an asynchronous server such as Nginx is event-driven and handles requests using as few threads as possible.

If you are thinking of building a site from scratch, then you should definitely consider using Nginx because building a new site gives you more time for experimentation and learning, but for an existing site it is safer to leave it as it is.

Nginx FAQ

Here’s a simple breakdown of some of the key terms you’ll encounter with Nginx:


Event-driven means that notifications or signals are used to mark the initiation or completion of a process; therefore resources can be used by other processes until a process initiation event is triggered. As a result, memory and CPU usage are optimised with Nginx-served sites.


Asynchronous means that threads are running concurrently and do not block each other while serving many requests, meaning Nginx can handle a lot more.


Single threaded means that a single worker process can server multiple clients because the resources are not blocked. It does this asynchronously with one thread, rather than multi-threaded programming.