Proxying Apache Server Through Nginx

Published on
6 mins read
––– views
thumbnail-image

Challenge

Before delving into the process of proxying an Apache web server through Nginx, it's important to understand the reasons that led me to this point (or might lead you here). This consideration stems from the fact that both Apache and Nginx are capable of serving as web servers and proxies. However, through personal experience, I came to realize that these two solutions don't execute all tasks with equal efficiency, and configuring them for specific tasks can be rather intricate.

Apache serves excellently as a web server, boasting ease of configuration and a wealth of accumulated experience over the years, particularly when dealing with websites that utilize PHP for backend functionality. Similarly, Nginx excels as a reverse proxy, consistently delivering reliable performance across a range of scenarios. Not too long ago, I found myself installing a Nextcloud instance on my server with the intention of making it accessible over the internet. A straightforward solution emerged: utilizing Apache as the server, as recommended by the Nextcloud documentation. The initial phase of setting up my cloud storage through Apache was remarkably smooth, resulting in a functional cloud storage solution within a matter of minutes. However, as my requirements expanded to accommodate more applications within the same server, complications arose. Many of these applications necessitated the implementation of a proxy to manage incoming traffic. I opted to use Apache as my proxy, although this approach introduced challenges. Certain applications failed to function correctly when routed through Apache's proxy.

Having significant experience with Nginx, my preferred proxy server, exacerbated the situation. I was well-aware of the straightforward process and potential performance benefits of proxying traffic through Nginx. It became evident that Nginx had advantages in this domain. Additionally, the realization dawned that I could deploy Nginx for both proxying and serving Nextcloud files.

Consequently, I resolved to transition entirely to Nginx. I halted the Apache service and initiated the Nginx service. The subsequent phase involved transferring configurations to Nginx. Managing the proxies was relatively uncomplicated, given the simplicity of Nginx's proxy configuration settings. I successfully transferred the proxy configurations and rigorously tested all services to ensure they operated as intended. The next step was to transfer the Nextcloud server. I was new to this I looked up a tutorial on this and came accross NextCloud Nginx configuration tutorial. However, to cut the story short, I encountered several arrers, ranging from too many redirects to error 503. I had to find a more reliable option that was easy and guaranteed to work without much hickups. Thats when it occured to me that I can just use apache as the server (this already worked) and proxy the trafic to apache using Nginx, which I also know how works. Now lets have a look at the process of doing so.

This steps will assume that you dont have Nginx or Apache installed.

Nginx

We can install Nginx using apt package manager in Ubuntu using the following command.

 sudo apt update && apt update && apt install nginx 

After the installation, the Nginx service can be started using the following command

sudo systemctl restart nginx.service 

Now you can create a new configuration file in the sites available file located at /etc/nginx/sites-available

Lets say we our domain is cloud.example.com. We can create a configuration file at the location using this command.

sudo nano /etc/nginx/sites-available/cloud.example.com

We can use the following sample configuration.

server {
    listen 80;
    server_name cloud.example.com;
    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

This configuration tells nginx to listen at port 80 and when it sees the address cloud.example.com it should send the traffic to port 8080.

Note that this configuration will proxy our traffic to port 8080. You can change the port as you wish as long as the port is not used by other applications.

Before moving on, we need to enable the condiguration by creating a simulink for the config file to /etc/nginx/sites-enabled using the following command:

sudo ln -s /etc/nginx/sites-available/cloud.example.com /etc/nginx/sites-enabled/

Apache

Now we can install Apache. Apache is configured to listen on port 80, which Nginx will take up. So we need to listed at a different port, specifically the port we are proxying our traffic to (8080 in this case). To do so we can modify the ports located at /etc/apache2/ports.conf.

sudo nano /etc/apache2/ports.conf

Now change the port to 8080.

Listen 8080

Now we can add the configuration for Apache webserver.

sudo nano /etc/apache2/sites-available/nextcloud.conf

Add the configuration for virtual host.

<VirtualHost *:8080>
  DocumentRoot /var/www/nextcloud/
  ServerName  your.server.com

  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off
    </IfModule>

  </Directory>
</VirtualHost>

Enable the configuration file

a2ensite nextcloud.conf

Enable mod_rpaf

Now to ensure that Apache appropriately interpret the headers containing the user IP address we need to install mod_rpaf.

When you check for Apache log files, you will get your IP address as the requests are being proxies from the local server. In order to correctly identify the IP addresses of clients making requests, you should enable the mod_rpaf module in Apache. This module allows Apache to correctly interpret the X-Real-IP and X-Forwarded-For headers set by Nginx.

To install and run the mod_rpaf run the following command.

sudo apt-get install libapache2-mod-rpaf

Restarting Nginx and Apache

You can restrt the apache and nginx services to apply the changes made.

sudo systemctl restart nginx.service 
sudo systemctl restart apache2.service

You can check the configurations by visiting the url. If you encounter any error, you can check the apache or nginx logs for details.

Conclusion

This set up is not only expected to make the configuration process simple (every service does what they are good at) but also expected to improve the performance and scalability of the services.