Nginx or engine X is a free and open-source web server, reverse proxying, load balancer, caching, and more. Apache isn’t the only web server for hosting web content (although, it is the most used), Nginx is also very powerful and stable.
In this guide, you’ll learn how to configure Nginx as a reverse proxy for apache on multiple websites…
Let’s get to installing Nginx (make sure apache is already installed):
sudo apt update
sudo apt install nginx
Verify Nginx is running:
systemctl status nginx
* nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-06-29 19:18:04 UTC; 1 day 4h ago ……………
You’ll see active (running), and also enabled in the vendor preset option, meaning when you restart your server, Nginx gonna boot up automatically.
If you see inactive (dead), use the following command:
sudo systemctl start nginx
If that does not work, reboot your server, and restart. Now, check the status if all is in place.
If you are hosting multiple domains, it is ideal to have a separate config for each domain, but since this is just for reverse proxy, I see no reason to create a separate config, If you have multiple domains, you can manage them in one config file, this way, you won’t have to go back and forth.
Nginx comes with a default server block (virtual host), let’s remove the symlink to avoid conflicts:
sudo unlink /etc/nginx/sites-enabled/default
This removes the symlink from the etc enabled folder, although it exists in the etc default folder, it is just no longer active.
Create a new default server block in sites-available:
sudo nano /etc/nginx/sites-available/allwebsites
Note: The below config is for multiple websites, so, if you want to create a config for one website, stop at the END First website line below:
## START First Website
server {
server_name www.firstwebsite.com firstwebsite.com;
root var/www/firstwebsite/;
access_log off;
# 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)$ {
expires max;
}
# Dynamic content, forward to Apache
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
## END First Website
## START Second Website
server {
server_name www.secondwebsite.com secondwebsite.com;
root var/www/secondwebsite/;
access_log off;
# 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)$ {
expires max;
}
# Dynamic content, forward to Apache
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:8080;
}
}
## END Second Website
Let me briefly summarize the above config structure:
- server { } - Starting a block declarative, which is going to contain a set of simple declarative
- server_name - The name of the website
- root - The Document Root to the directory that will store the files for the website. You might want to change this to your site root directory
- access_log off; - switch off access log for the website, you can use the global access log if needed
- # Static contents - the location would match and serve all the static content, and
- # Dynamic content, forward to Apache - this would forward the dynamic content to apache (e.g PHP) and pass the request header, e.g php
Create a symlink to enable it
ln -s /etc/nginx/sites-available/allwebsites /etc/nginx/sites-enabled/allwebsites
Open apache config:
sudo nano /etc/apache2/ports.conf
Change
Listen 80
To
Listen 8080
Reload Apache2 & Nginx
systemctl reload apache2
systemctl reload nginx
Configure mod_remoteip
An issue you would come across when using Nginx as a front-end proxy is that apache won’t log the original requester’s IP address, it would only log the address of the localhost (127.0.0.1). This is common in WordPress when a user leaves a comment, it won’t show the user's original IP. (I had so many challenges figuring this out)
To fix this, we use a module called “mod_remoteip” which is easy as bean cake to install and configure, the good thing is that the module is already available out of the box in apache, so, all we have to do is enable it, use the following command:
sudo a2enmod remoteip
Once it is enabled, open the config file:
sudo nano /etc/apache2/apache2.conf
Add the following at the bottom:
#Show Real REMOTE IP RemoteIPHeader X-Forwarded-For
Don’t close the file yet, find this line:
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
replace the ‘h’ with ‘a’ as shown below
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
Restart Apache:
sudo systemctl reload apache2
You are good to go!