How to setup Nginx as a Web Server and Reverse Proxy for Apache.


A web server is a server software and hardware that uses HTTP (Hypertext Transfer Protocol) and several other related protocols to respond to client requests made over the World Wide Web. Web server is used to display website content through storing, processing, and delivering webpages to users.

According to Nginx, a reverse proxy server is a type of proxy server that typically sits behind the firewall in a private network and directs client requests to the appropriate backend server. A reverse proxy provides an additional level of abstraction and control to ensure the smooth flow of network traffic between clients and servers.

Apache and Nginx are two most widely used, free, and popular open-source web servers in the world. Apache is famous for its power and backend compatibility. Nginx is majorly known for its speed, also it provides features such as load balancing, security, and acceleration.

If you want to host multiple websites with different requirements on a virtual machine then using apache and Nginx could prove useful. One of the basic solution to run two servers on a system is to either use different port numbers or multiple IP addresses.

In this article, you will learn how to install and configure Nginx as a reverse proxy for Apache webserver.

Note: Make sure you are using Ubuntu 18.04 VPS.  

Depending on the web application, code changes might be required to keep Apache reverse-proxy-aware, especially when SSL sites are configured. To avoid this, you will install an Apache module called mod_rpaf which rewrites certain environment variables so it appears that Apache is directly handling requests from web clients.

In this tutorial, we will be hosting four domain names on one server. Two will be served by Nginx: (the default virtual host) and The remaining two, and, will be served by Apache. We’ll also configure Apache to serve PHP applications using PHP-FPM, which offers better performance over mod_php.


  • A configured Ubuntu 18.04 server VPS on Digital Ocean.
  • Four valid domain names configured to point to your server’s IP address. Use proper A records, if you host your domain names elsewhere.

Step 1: Installing and configuring Apache and PHP-FPM

The first step is to install Apache and PHP-FPM.

Additionally we will install the PHP FastCGI Apache module, libapache2-mod-fastcgi, to support FastCGI web applications.

Before installing Apache update your package list to ensure you have the latest packages.

sudo apt update

Once you have the latest packages, install Apache and PHP-FPM packages:

sudo apt install apache2 php-fpm

Note:  Download the FastCGI Apache module from as it is not available in Ubuntu’s repository. Install it using the dpkg command.

sudo dpkg -i libapache2-mod-fastcgi_2.4.7~0910052141-1.2_amd64.deb

Now it’s time to change Apache’s default configuration to use PHP-FPM.

In this step, we will change Apache’s port number to 8080 and configure it to work with PHP-FPM using the mod_fastcgi module.

Rename Apache’s ports.conf configuration file:

sudo mv /etc/apache2/ports.conf /etc/apache2/ports.conf.default

Create a new ports.conf file with the port set to 8080:

echo "Listen 8080" | sudo tee /etc/apache2/ports.conf

Note: By default, while configuring reverse proxy, Web servers are generally set to listen on  but doing so would set the value of PHP’s environment variable SERVER_ADDR to the loopback IP address instead of the server’s public IP. We will configure websites to listen on 8080 on all IP address as we don’t want apache server to see reverse proxy in front of it.

The next step is to create a virtual host file for Apache. Disable the default virtual host:

sudo a2dissite 000-default

Now, create a new virtual host file, using the existing default site:

sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/001-default.conf

Next step is to open the new configuration file:

sudo nano /etc/apache2/sites-available/001-default.conf

Change the listening port to 8080:

<VirtualHost *:8080>
    ServerAdmin [email protected]
    DocumentRoot /var/www/html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

Save the file and activate the new configuration file:

sudo a2ensite 001-default

Then reload Apache:

sudo systemctl reload apache2

Verify that Apache is now listening on 8080:

sudo netstat -tlpn

The output should look like the following example, with apache2 listening on 8080:


Active Internet connections (only servers)

Proto Recv-Q Send-Q Local Address     Foreign Address      State
PID/Program name
tcp        0      0*            LISTEN   1086/sshd
tcp6       0      0 :::8080           :::*                 LISTEN
tcp6       0      0 :::22             :::*                 LISTEN   1086/ssh

You can configure support for PHP and FastCGI once this is done.

Step 2: Apache Configuration to use mod_fastcgi

By default, Apache serves PHP using mod PHP, but it requires additional configuration to work with PHP-FPM. We will be adding a configuration block for mod_fastcgi which depends on mod_action. mod_action is disabled by default, so we first need to enable it:

sudo a2enmod actions

Now, rename the existing FastCGI configuration file:

sudo mv /etc/apache2/mods-enabled/fastcgi.conf /etc/apache2/mods-enabled/fastcgi.conf.default

The next step is to create a new configuration file:

sudo nano /etc/apache2/mods-enabled/fastcgi.conf

Add the following directives to the file to pass requests for .php files to the PHP-FPM UNIX socket:

<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .fcgi
  FastCgiIpcDir /var/lib/apache2/fastcgi
  AddType application/x-httpd-fastphp .php
  Action application/x-httpd-fastphp /php-fcgi
  Alias /php-fcgi /usr/lib/cgi-bin/php-fcgi
  FastCgiExternalServer /usr/lib/cgi-bin/php-fcgi -socket /run/php/php7.2-fpm.sock -pass-        header Authorization
  <Directory /usr/lib/cgi-bin>
    Require all granted

Save the changes and do a configuration test:

sudo apachectl -t

Reload Apache if Syntax OK is displayed:

sudo systemctl reload apache2

Note: If you see the warning Could not reliably determine the server’s fully qualified domain name, using Set the ‘ServerName’ directive globally to suppress this message., you can safely ignore it for now. We’ll configure server names later.

Step 3: PHP Verification Functionality

In this step, we make sure that PHP is working properly by creating a phpinfo() file and accessing it from a web browser.

First, create the file /var/www/html/info.php which contains a call to the phpinfo function:

echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/info.php

To see the file in a browser, go to http://your_server_ip:8080/info.php. This will give you a list of the configuration settings PHP is using. Check that whether Server API says FPM/FastCGI. Also check if the PHP Variables section tells you the SERVER_SOFTWARE is Apache on Ubuntu. These confirm that mod_fastcgi is active and Apache is using PHP-FPM to process PHP files.

Step 4: Creating Virtual Hosts for Apache

In this step, create Apache virtual host files for the domains and

Create the document root directories:

sudo mkdir -v /var/www/ /var/www/

Now, create an index file for each site:

echo "<h1 style='color: green;'>Foo Bar</h1>" | sudo tee /var/www/
echo "<h1 style='color: red;'>Test IO</h1>" | sudo tee /var/www/

Now, create a phpinfo() file for each site so we can test that PHP is configured properly.

echo "<?php phpinfo(); ?>" | sudo tee /var/www/

echo "<?php phpinfo(); ?>" | sudo tee /var/www/

Now create the virtual host file for the domain:

sudo nano /etc/apache2/sites-available/

Add the following code to the file to define the host:

    <VirtualHost *:8080>
        DocumentRoot /var/www/
        <Directory /var/www/>
            AllowOverride All

The line AllowOverride All enables .htaccess support.

Save and close the file.

Now, create a similar configuration for First create the file:

sudo nano /etc/apache2/sites-available/

Add the configuration to the file:

    <VirtualHost *:8080>
        DocumentRoot /var/www/
        <Directory /var/www/>
            AllowOverride All

Save the file and exit the editor.

Now that both Apache virtual hosts are set up, enable the sites using the a2ensite command. This creates a symbolic link to the virtual host file in the sites-enabled directory:

sudo a2ensite
sudo a2ensite

Check Apache for configuration errors again:

sudo apachectl -t

Syntax OK message will be displayed if there are no errors. If you see anything else, review the configuration and try again. Reload Apache once all your errors are resolved.

sudo systemctl reload apache2

To confirm the sites are working, open and in your browser and verify that each site displays its index.html file. You also need to ensure that PHP is working. This can be done by accessing the info.php files for each site. Visit and in your browser. We now have two websites hosted on Apache at port 8080. Let’s configure Nginx next.

Step 5: Installing and Configuring Nginx

In this step, you will install Nginx and configure the domains and as Nginx’s virtual hosts.

First, install Nginx using the package manager:

sudo apt install nginx

Remove the default virtual host’s symlink

sudo rm /etc/nginx/sites-enabled/default

You will create your own default site later (

Now let’s create virtual hosts for Nginx First step is to create document root directories for both the websites:

sudo mkdir -v /usr/share/nginx/ /usr/share/nginx/

The next step is to create index and phpinfo() files for testing after setup is complete:

echo "<h1 style='color: green;'></h1>" | sudo tee /usr/share/nginx/

echo "<h1 style='color: red;'></h1>" | sudo tee /usr/share/nginx/

echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/

echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/

Create a virtual host file for the domain

sudo nano /etc/nginx/sites-available/

Nginx calls server {. . .} areas of a configuration file server blocks. Create a server block for the primary virtual host,

server {
    listen 80 default_server;

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

    location / {
        try_files $uri $uri/ /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        include snippets/fastcgi-php.conf;

Copy, Save and close the file.

Now let’s create a virtual host file for Nginx’s second domain,

sudo nano etc/nginx/sites-available/

Add the following to the file:

server {
    root /usr/share/nginx/;
    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php;

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.2-fpm.sock;
        include snippets/fastcgi-php.conf;

Copy, Save and close the file.

Now, enable both sites by creating symbolic links to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

sudo ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/

Test the Nginx configuration for erros.

sudo nginx -t

Reload Nginx if there are no errors:

sudo systemctl reload nginx

Now access the phpinfo() file of your Nginx virtual hosts in a web browser by visiting and In PHP Variables sections, [“SERVER_SOFTWARE”] should say nginx, and  [“DOCUMENT_ROOT”] should point to the directory you created earlier in this step for each Nginx site.

Until now you have installed Nginx and created two virtual hosts. The next step is to configure Nginx to proxy requests meant for domains hosted on Apache.

Step 6: Configuring Nginx for Apache’s Virtual Host.

In this step you will create an additional Nginx virtual host with multiple domain names in the server_name directives. Requests for these domain names will be proxied to Apache.

First, ceate a new Nginx virtual host file to forward requests to Apache:

sudo nano /etc/nginx/sites-available/apache

Add the following code block. Remember to use the public IP address in proxy_pass:

server {
    listen 80;

    location / {
        proxy_pass http://your_server_ip:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

Copy and Save the file. Enable this new virtual host by creating a symbolic link:

sudo ln -s /etc/nginx/sites-available/apache /etc/nginx/sites-enabled/apache

Test the configuration to ensure there are no errors:

sudo nginx -t

Reload Nginx, if there are no errors:

sudo systemctl reload nginx

Open the browser and access the URL in your browser. Scroll down to the PHP Variables section and check the values displayed.

The variable SERVER_SOFTWARE should show “Apache” and DOCUMENT_ROOT should show “/var/”. This confirms that the request was handled by Apache. Nginx adds variables HTTP_X_REAL_IP and HTTP_X_FORWARDED_FOR. They should show the public IP address of the computer you’re using to access the URL.

You have successfully set up Nginx to proxy requests for specific domains to Apache. The next step is to configure Apache to set the REMOTE_ADDR variable.

Step 7: Installing and Configuring mod_rpaf

In this step you will install an mod\_rpaf  Apache module. This module rewrites the values of REMOTE_ADDRHTTPS and HTTP_PORT based on the values provided by a reverse proxy. Without this module, some PHP applications would require code changes to work seamlessly from behind a proxy.

This module is present in Ubuntu’s repository as libapache2-mod-rpaf but is outdated and doesn’t support certain configuration directives. Instead, we recommend you to install it from source.

The first step is to install the packages needed to build the module:

sudo apt install unzip build-essential apache2-dev

Now, download the latest stable release from GitHub:


Now, Extract the downloaded file:


The next step is to change into the new directory containing the files:

cd mod_rpaf-stable

Compile and install the module:

sudo make install

Create a file in the mods-available directory which will load the rpaf module:

sudo nano /etc/apache2/mods-available/rpaf.load

Add the following code to the file to load the module:

LoadModule rpaf_module /usr/lib/apache2/modules/

Save the file and exit the editor.

Now, create another file in this directory called rpaf.conf. It will contain the configuration directives for mod_rpaf:

sudo nano /etc/apache2/mods-available/rpaf.conf

Add the following code to configure mod_rpaf.  Specify the IP address of your server.

<IfModule mod_rpaf.c>
        RPAF_Enable             On
        RPAF_Header             X-Real-Ip
        RPAF_ProxyIPs           your_server_ip 
        RPAF_SetHostName        On
        RPAF_SetHTTPS           On
        RPAF_SetPort            On

Save rpaf.conf and enable the module:

sudo a2enmod rpaf

This creates symbolic links of the files rpaf.load and rpaf.conf in the mods-enabled directory. Now do a configuration test:

sudo apachectl -t

Reload Apache if there are no errors:

sudo systemctl reload apache2

Now, access the phpinfo() pages and in your browser and check the PHP Variables section. The REMOTE_ADDR variable will now show your local computer’s public IP address.


Congratulations! You have successfully installed and configured Nginx as a reverse proxy for Apache webserver.  This article was written with reference to the Digital Ocean “How To Configure Nginx as a Web Server and Reverse Proxy for Apache on One Ubuntu 18.04 Server”. Visit Digital Ocean VPS pricing page to find a hosting package that’s right for you.

We hope this article helps you to clear you doubts. Please drop your queries in the comment section.

Also, if you want us to cover a specific topic, you can drop that into the comment section as well.

Recent Articles

Best Audiobook Apps for iPhone and iPad to Use in 2020

Ours is an age of transformation and nothing is an exception from the rule. When I say nothing, I mean it as...

Apps that Every Digital Nomad needs in 2020

The life of every digital nomad revolves around their laptop while they revolve around the world. With no problems of a confined...

How to Add Popups in WordPress?

Do you want to increase your website's conversion rate? Popup is an effective marketing tool for generating leads and it has a...

Airdrop on Android Finally Made Possible Through These Apps

Android vs IOs is an age-old battle. While the users of both segments swear by their love for their operating system, there...

What is Facebook Marketplace and How to use it for maximum benefit?

Facebook is the most versatile social media website ever. There is nothing you can’t do on the site and buying and selling...

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here