Nginx and Apache (Ubuntu 12.04 LTS)
This article is part of our Academy Course titled Introduction to Nginx.
This course will introduce you to the magic of nginx. You will learn to install and configure nginx for a variety of software platforms and how to integrate it with Apache. Additionally, you will get involved with more advanced concepts like Load Balancing, SSL configuration and Websockets proxying. Check it out here!
Table Of Contents
1. Introduction
Nginx and Apache can certainly work together, not necessarily replacing each other as our web server of choice. This solution offers many advantages and solves the issues that most system administrators are familiar with, such as slowdowns and complex configurations. You can just take a look at the Apache configuration file and chances are you’ll probably agree with me!
2. Nginx as reverse proxy
A reverse proxy is a device or service placed between a client and a server in a network infrastructure. Incoming requests are handled by the proxy, which interacts on behalf of the client with the desired server or service residing on the server1. In this case, Nginx will act as reverse proxy between the client (your computer, for example) and Apache, the backend web server (see Fig. 1).
In this above diagram, Nginx acts as reverse proxy (or in other words, as frontend server) and receives all requests from the outside world. At this point those requests can be filtered or “delivered” to Apache (acting as HTTP client) in the backend. These two services can even be hosted in the same physical server with the caution to use different listening ports for each of them. This whole operation is handled by the proxy module of Nginx.
The main purpose of setting up Nginx as a frontend server and giving Apache a simple backend role is to improve the serving speed, given the fact that great amount of requests coming from clients are for static files (html pages, cascading style sheets, regular images, and so on), and static files are served much faster by Nginx. The overall performance sharply improves both on the client side and server side.
3. Nginx proxy module
Fortunately, the proxy module is enabled by default during the installation of Nginx. The main directives of the module can be seen in Table 1.
The best scenario is to limit to the extent possible the number of requests that are forwarded to the backend server. To that end, the proxy module comes with a group of directives that will help us build a caching system as well as control buffering options and the way Nginx deals with temporary files (see Table 2 for more information on most of these directives).
There are even more directives that let you define the behavior of Nginx in the case of timeouts or other limitations regarding communications with the backend server (see Table 3):
4. A note on variables
The proxy module comes with the following variables that can be used as arguments for the directives listed above:
$proxy_host:
the hostname of the backend server.$proxy_port:
the port of the backend server.$proxy_add_x_forwarded_for:
Contains client request-header “X-Forwarded-For” with separated by comma $remote_addr. If there is no X-Forwarded-For request-header, than $proxy_add_x_forwarded_for is equal to $remote_addr.$proxy_internal_body_length:
Length of the request body (set with theproxy_set_body
directive or 0).
5. Configuring Apache
By default, web servers are configured to listen on tcp port 80. So the first thing that we need to do is to change the settings of Apache in order to avoid conflicts with Nginx (which will be running as the frontend server).
In Ubuntu 12.04, the main configuration file for Apache is located in /etc/apache2
under the name ports.conf
(see Fig. 2).
There are 3 main elements that need to be replaced in our Apache configuration (see Fig. 3a and 3b):
1) The Listen directive must be changed to a port other than 80, such as 8080.
2) The following configuration directive is present in the main configuration file:
NameVirtualHost A.B.C.D:8080
where A.B.C.D is the IP address of the main network interface on which server communications (between the frontend and the backend servers) go through. In this case, we use the loopback interface and its IP address since both Apache and Nginx are installed in the same physical server. If you do not host Apache on the same server, you will need to specify the IP address of the network interface that can communicate with the server hosting Nginx.
3) The port that was just selected must be reported in all our virtual hosts configuration sections (in /etc/apache2/sites-available/default
).
After restarting Apache, we can open a web browser and confirm that it is listening on port 8080 (see Fig. 4):
As a extra security measure, we can tell Apache to only serve requests coming from the frontend server. This can be performed in 2 ways: 1) system wide or by 2) establishing per-virtual-host restrictions.
1) As discussed earlier, the Listen directive of Apache lets you specify a port, but also an IP address. However, by default, no IP address is selected which results in communications coming from all interfaces. All you have to do is replace the Listen *:8080
directive by Listen 127.0.0.1:8080
, Apache should then only listen on the local IP address.
2) Using the allow and deny Apache directives we can define which IP addresses will be able to access each virtual host.
Once the changes are made, Apache must be restarted (or its configuration reloaded) in order to reflect the changes that we have just made.
6. Configuring Nginx
The first directive that we will use in the process of enabling proxy options is proxy_pass. Since it can’t be used at the http or server level, we will include it in every single place that we want to be forwarded. As a preliminary example, we will have all requests made to the restricted folder be forwarded to the Apache web directory (/var/www). See Figs. 5a and 5b, 6a and 6b:
7. Separating content
In order to take better advantage of this Nginx-Apache setting, we can separate the content that each one will deliver upon request.
Apache will serve dynamic files, that is, files that require some sort of processing before being sent to the client, such as php files, Python scripts, and so on.
Nginx will serve static files – all other content that does not require additional processing (html pages, cascading style sheets, images, media, and so on).
To do this, add the following blocks in the nginx.conf file (see Fig. 7):
When we restart Nginx, we may run into the following issue (see Fig. 8):
We will go ahead and install the PCRE library that is available in the libpcre3-dev
package (refer to tutorial 1: Nginx installation on Linux). See Fig. 9 for details on this package. Once installed, we will have to recompile Nginx.
Let’s create a sample php file in /var/www
(see Fig. 10):
Now we will point our web browser to http://localhost/test.php
. Please note that localhost per se points to the frontend server, so when it receives a request for a php file, it will forward the request to Apache (see Fig. 11)
8. Download the configuration files
Here you can download the configuration files used in this tutorial: Config_files.zip