0

Use Apache Alongside Nginx Without Requiring a Subdomain

Posted in Linux, PHP

I’ve been looking for ways to speed up my site recently and came across this interesting article on seamlessly integrating nginx with Apache to handle asset files without requiring a CDN subdomain. This works by checking the requests file extension for .js, .jpg, .pdf etc and if not found, proxies the request to Apache and serves the results. Here’s what you need:

Install/Configure nginx

sudo apt-get install nginx
sudo nano/etc/nginx/sites-available/default

Here’s what my Debian 6 config file looks like (Ubuntu should be the same):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# You may add here your
# server {
#	...
# }
# statements for each of your virtual hosts
 
server {
 
	listen   80; ## listen for ipv4
	listen   [::]:80 default ipv6only=on; ## listen for ipv6
 
	server_name  localhost;
	root /var/www/; 
	access_log  /var/log/nginx/localhost.access.log;
 
	# Static Contents
	location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {		access_log off;
		expires 30d;
	}
 
	# Dydamic Content forward to Apache
	location / {
        	proxy_set_header X-Real-IP  $remote_addr;
	        proxy_set_header Host $host;
        	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	        proxy_pass http://127.0.0.1:8080;	}
}
 
###############################################################################
# virtualhost
###############################################################################
 
#server {
#    server_name www.example.com example.com;
#    root /var/www/example.com/html/;
#
#    # Static Contents
#    location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
#        access_log off;
#        expires 30d;
#    }
#
#    # Dydamic Content forward to Apache
#    location / {
#        proxy_set_header X-Real-IP  $remote_addr;
#        proxy_set_header Host $host;
#        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#        proxy_pass http://127.0.0.1:8080;
#    }
#}

Above you should tweak the highlighted lines to your liking. You’ll notice I’m running apache on port 8080, so let’s update apache.

 

Apache Configuration

# log correct IP address for forwarded requests 
sudo apt-get install libapache2-mod-rpaf
 
# update the port Apache will be running on. Change the following lines from 80 to 8080:
# NameVirtualHost *:8080
# Listen 8080
sudo nano /etc/apache2/ports.conf
 
# do the same in your desired site. Change 80 to 8080:
# <virtualhost :8080=""> sudo nano /etc/apache2/sites-enabled/000-default </virtualhost>

 

Restart your servers

sudo service apache2 restart
sudo service nginx restart

 

Benefits

You won’t need to modify all your pages/posts updating asset locations to point to a subdomain! Everything will ‘just work’.

 

Issues/Drawbacks

There are 2 issues I’ve found with this setup:

  • Because Apache is now running on port 8080, your mod_rewrite redirects will now redirect to that port. You won’t be able to use RedirectMatch anymore, however below is the solution I came up with:
    RewriteEngine on
    RewriteRule ^foo\.php$ http://%{HTTP_HOST}:80/bar.php [R=301,L]
  • You can no longer use .htaccess redirects for any asset files nginx is serving. Instead, use nginx redirects. Below is an example:
    rewrite ^\/foo\.jpg$ http://173.255.221.210/bar.jpg permanent;

    For more information on nginx redirects, see the official documentation.