When it comes to web hosting, we are familiar with the two webservers Apache and Nginx, and usually we always think we need to use one over the other. In this post, I’m going to show you how you can configure your system such that you can use both of them, with Nginx as your reverse proxy, and Apache as your application server
Overview
- Nginx running on port 80 (or 443)
- Apache running on a different port (8080), and only accepts incoming request from local sockets
- The backend application remains unchanged, and connects to Apache with CGI
Configuring Apache
Navigating to /etc/httpd/conf
or /etc/apache2/
, we need to change the original listening port of the Apache from 80/443 to some other port, 8080 for example. We also need to set it to deny all request from all IP addresses, and to only allow connections from localhost, or the server where you Nginx is if its installed on a separate server.
<VirtualHost A.B.C.D:80>
ServerName example.com
ServerAlias www.example.com
[...]
</VirtualHost>
<VirtualHost A.B.C.D:8080>
ServerName example.com:8080
ServerAlias www.example.com
[...]
order deny,allow
allow from 127.0.0.1
allow from 192.168.0.1
deny all
</VirtualHost>
Configuring Nginx
We use Nginx as a proxy to forward the requests to the Apache webserver. We can further optimize it by only sending requests for dynamic content to the Apache webserver, and for Nginx to process static files.
upstream apache {
server 192.168.0.1:8080;
server 192.168.0.2:8080;
server 192.168.0.3:8080 weight=2;
server 192.168.0.4:8080 backup;
}
server {
server_name .example.com;
root /home/example.com/www;
[...]
location / {
# If the requested file extension ends with .php,
# forward the query to Apache
if ($request_filename ~* .php.$) {
break; # prevents further rewrites
proxy_pass http://apache;
}
# If the requested file does not exist,
# forward the query to Apache
if (!-f $request_filename) {
break; # prevents further rewrites
proxy_pass http://apache;
}
# Your static files are served here
expires 30d;
}
}
Forwarding Correct IP Address
In the setup above, because Apache sits behind Nginx and listens to localhost, all request would seem to come from localhost. To rectify this, we need to properly forward the actual requesting IP to Apache.
In /etc/httpd/conf
:
LoadModule remoteip_module modules/mod_remoteip.so
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1
In /etc/nginx/conf
:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Leave a Reply