Nginx reverse proxy

By:    Updated: January 26,2017

According to Netcraft reports, apache still stay ahead on the webserver market. It serves 28.30% busiest sites. Due to the massive amount of modules and other components that Apache loads in memory (for each HTTP request that it receives), your server may rapidly clutter when massive influxes of requests come in at the same time. In practice, this results in excessive memory and CPU overhead. Oppositely, Nginx has proven to be both lightweight and stable while serving a larger amount of requests (using lesser RAM and CPU time in comparison to Apache).But for the following reasons, some people may not switch to Nginx completely:

  • When you already have Apache installed with complex configuration files that can hardly be ported to Nginx, or if you do not have the time to completely switch to Nginx
  • When your system operates a frontend system management panel such as cPanel (Generally speaking, it's common used on the Shared hosting), or other solutions that generate automatically Apache configuration files
  • When a functionality that your project or architecture requires is available with Apache but not with Nginx

 

They may also have another reasons, so using Nginx running as reverse proxy server to communicate with Apache may be good choice.

The Nginx reverse proxy mechanism

Somewhat like the FastCGI architecture, we are going to be running Nginx as a frontend server. In other words, it will be in direct communication with the outside world whereas Apache will be running as a backend server and will only exchange data with Nginx:

Nginx reverse proxy mechanism

There are now two web servers running and processing requests:

  • Nginx positioned as a frontend server (reverse proxy server), receives all the requests from the outside world. It filters them, either serving static files directly
  • Apache runs as a backend server and it only communicates with Nginx. It may be hosted on the same computer as the frontend, in which case, the listening port must be edited to leave port 80 available to Nginx.

Advantages and disadvantages

  • Overall speed: A great amount of requests coming from clients are for static files, and static files are served much faster by Nginx.
  • Security: The latest stable versions of Nginx hava less security issues.
  • Easy to set up: You nearly have no modification to make when it comes to Apache configuration. All it requires is a simple port change, but that isn't even necessary if you set up Nginx and Apache on different servers.
  • Slower than Nginx + FastCGI: It is slower than Nginx + FastCGI most of the time. The optimal solution would be to completely switch to Nginx and leave out Apache.
  • Confusion for Nginx: Since Nginx that is installed as the frontend, it implies that it receives raw requests from users. This implies that the URI comes in its original form, which can lead to confusion for Nginx as it will not be able to make the difference between static and dynamic content. You have two choices to solve this issue. You can either port your rewrite rules to Nginx or redirect any request that results in a 404 error to the Apache backend.
  • Issues with control panel software: These panels are very useful for administrators, as they automate some of the most bothersome tasks like adding virtual hosts to the Apache configuration, and many more. But they only offer Apache compatibility.

 

After understanding the mechaism, it's now time to put all these principles into practice. There are basically two main parts involved in the configuration, one relating to Apache and one relating to Nginx.

Reconfiguring Apache

There are three main elements you need to change and/or add  in your Apache configuration:

  • The Listen directive is set to listen on port 80 by default. You will have to replace that port by another such as 8080.
  • Change NameVirtualHost *:80 to NameVirtualHost *:8080.
  • Accepting local requests and Nginx requests only.

 

#Listen 80
Listen 8080
#<VirtualHost *:80>
#DocumentRoot "/home/webroot/valinv.com/www.valinv.com"
#ServerName www.valinv.com
#</Virtualhost>

#change port
<VirtualHost *:8080>
DocumentRoot "/home/webroot/valinv.com/www.valinv.com"
ServerName www.valinv.com

#add permission: Accepting local requests and Nginx requests only
<Directory />
    Require ip 127.0.0.1 #localhost
    Require ip 192.168.12.25 #Nginx ip
</Directory>

</Virtualhost>

Configuring Nginx as reverse proxy via proxy_pass

server {
    listen       80;
    server_name  www.valinv.com;

    #....

    # for dynamic contents
    location ~* \.php.$ {
        # proxy all requests with an URI ending with .php*
        proxy_pass   http://192.168.12.25:8080;
    }

    # for static files
    location / {          
        expires 24h;
    }
}

For URL rewriting

Most websites now use URL rewriting to improve SEO. When building a reverse proxy configuration, you have two options:

  • Migrate your Apache rewrite rules to Nginx, in order for Nginx to know the actual file extension of the request and proxy it to Apache correctly.
  • If you do not wish to migrate your Apache rewrite rules, the default behavior shown by Nginx is to return 404 errors for such requests. However, you can alter this behavior in multiple ways, for example, by handling 404 requests with the error_page directive, or by testing the existence of files before serving them.

 

server {
    listen       80;
    server_name  www.valinv.com;

    #....

    location @proxy {
        proxy_pass   http://192.168.12.25:8080;
    }

    location / {          
        expires 24h;

        # for 404 errors, submit the query to the @proxy
        error_page 404 @proxy;
    }
}

Alternatively, making use of the if directive from the rewrite module:

server {
    listen       80;
    server_name  www.valinv.com;

    #....

    location / {  
        # If the requested file extension ends with .php, forward the query to Apache 
        if ($request_filename ~* \.php.$) {           
            proxy_pass http://192.168.12.25:8080;
            break; 
        }

        # If the requested file does not exist, forward the query to Apache
        if (!-f $request_filename) {
            proxy_pass http://192.168.12.25:8080;
            break;
        }

        #for static files      
        expires 24h;
    }
}

According to the above codes, you will find that "Migrate your Apache rewrite rules to Nginx" may be a better choice.

More in Development Center
New on Valinv
Related Articles
Sponsored Links