How to Setup NGINX Reverse Proxy Over Apache on Ubuntu 16.04

Try it in our public cloud & Get $5 Credit
CLAIM NOW

Nginx and Apache are the most popular open source web servers, and each has distinct characteristics. Nginx is often lighter and faster, but this comes at a cost since it does not automatically support PHP and other common web technologies. Apache, on the other hand, uses more resources and is more complicated to configure. In contrast to Nginx, it can run PHP and other scripting languages via its integrated module system.

Most webmasters run PHP in a separate FPM process behind Nginx, but there are advantages to proxying PHP requests to Apache. First, you can access the .htaccess files shipped with most PHP apps, without building custom rules. You can also use an app’s Apache configuration directly without having to map directives to Nginx. Nginx can continue serving static files, something it does amazingly well. You can also add other modules to Apache later, letting it handle scripts while Nginx serves everything else.

Getting Started

To complete this guide, you will need the following:
• 1 Node (Cloud Server or Dedicated Server) with a plain Ubuntu 16.04.

When we’re done, you’ll have an Nginx web server proxying PHP requests to Apache. While out of scope for this tutorial, much of it can be used to run other scripting languages in Apache as well.

Tutorial

Let’s go. First we’ll update our Apt cache and installed packages. This not only patches known current security vulnerabilities, but it also ensures that we won’t receive errors about missing packages later.

apt-get update && apt-get upgrade -y && shutdown -r now

Next let’s install the standard apache2 package.

apt-get install apache2 -y
apt-get install php libapache2-mod-php php-mcrypt -y

We must now tweak Apache’s port, since it will now be a proxy behind Nginx and can’t conflict.

nano /etc/apache2/ports.conf

Change the line:

Listen 80

to:

Listen 8080

Save this file and exit.

Since Apache will be handling our PHP scripts, we need to enable its PHP module.

nano /etc/apache2/mods-enabled/dir.conf

Find this block:

<IfModule mod_dir.c>
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

Place index.php at the front.

<IfModule mod_dir.c>
DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

Save and exit.

To test our setup, we’ll create a phpinfo page. This will display lots of diagnostics about your current installation.

<?php
phpinfo();
?>

Enter the document root directory and create a page called index.php.

cd /var/www/html
nano index.php

Save and exit. Visit http://your_main_ip:8080/ to see if this page works.

Now we need to install Nginx, which will be proxying all of your PHP web traffic. Static resources will be served directly by Nginx.

apt-get install nginx -y

To save bandwidth and increase transfer speed, we’ll now enable Gzip compression on the server. Gzip will compress text and other resources to speed up downloads.

nano /etc/nginx/nginx.conf
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

Under the gzip_types line, add these two:

# Proxy Cache Settings
proxy_cache_path /var/cache levels=1:2 keys_zone=reverse_cache:60m inactive=90m max_size=1000m;

Save and exit. We’ll next need to modify the Nginx virtual host so it proxies PHP requests to Apache.

nano /etc/nginx/sites-enabled/default

Find this block of text:

# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;

Add index.php as shown:

# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;

Next, after this block:

server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}

add:

# Reverse Proxy and Proxy Cache Configuration
location ~ \.php$ {proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;# Cache configuration
proxy_cache reverse_cache;
proxy_cache_valid 3s;
proxy_no_cache $cookie_PHPSESSID;
proxy_cache_bypass $cookie_PHPSESSID;
proxy_cache_key "$scheme$host$request_uri";
add_header X-Cache $upstream_cache_status;
}
# Enable Cache the file 30 days
location ~* .(jpg|png|gif|jpeg|css|mp3|wav|swf|mov|doc|pdf|xls|ppt|docx|pptx|xlsx)$ {
proxy_cache_valid 200 120m;
expires 30d;
proxy_cache reverse_cache;
access_log off;
}
# Disable Cache for the file type html, json
location ~* .(?:manifest|appcache|html?|xml|json)$ {
expires -1;
}
location ~ /\.ht {
deny all;
}

Save and exit. You will need to restart the service, to apply changes. Now the same phpinfo page is available at http://your_main_ip.

Conclusion

You’re now routing PHP traffic through Nginx to Apache. This setup gives the best of both worlds a light, efficient server for static files, and a robust PHP environment for running PHP scripts. If this guide was helpful to you, kindly share it with others who may also be interested.

  • Diego Ortega

    Hi, Thanks for sharing, in section “To save bandwidth and increase transfer speed, we’ll now enable Gzip
    compression on the server. Gzip will compress text and other resources
    to speed up downloads.

    $ nano /etc/nginx.conf” maybe must will be say $nano /etc/nginx/nginx.conf otherwise is a empty file and doesn’t exist .

    Following the command sudo /etc/init.d/nginx restart, result is failed, checking the message -> systemctl status nginx.service, i noticed up the file i edit was the incorrect

    by the way editing the correct all works like a charm !
    Greetings

    • ptalbot

      Hi Diego, Thank you very much for your feedback. We made the change to the command.
      Regards,