Managing multiple reverse proxies for one virtual host in apache2

16,520

I came up with a reasonable solution to this problem. Instead of mixing core js-host configuration with lots of reverse proxy configuration, I separated the two. js-host is now a standalone site that knows nothing about the other services. The key to this approach is to add a reverse proxy for '/' to the core js-host site below all the other reverse proxy config.

Even though there is still lots of reverse proxy config in one config file, the config file is only for reverse proxy config. Here's what it looks like:

/etc/apache2/sites-available/js-host

You must give the virtualhost acting as your proxy server the hostname you wish your users to use. Also, I found a more concise way to set up a reverse proxy using RewriteRule.

LoadModule proxy_module lib/httpd/mod_proxy.so
LoadModule proxy_http_module lib/httpd/mod_proxy_http.so

ProxyRequests off
<Proxy *>
    Order allow,deny
    Allow from all
</Proxy>

<VirtualHost *:80>
    ServerName    js-host.example.com
    RewriteEngine on

    # Create reverse proxies via RewriteRule with the 'P' flag.
    RewriteRule ^/serviceA/(.*)$ http://192.168.100.50/$1 [P]
    RewriteRule ^/serviceB/(.*)$ http://192.168.100.51/$1 [P]
    [...]
    RewriteRule ^/serviceZ/(.*)$ http://192.168.100.75/$1 [P]

    # This links '/*' (anything not handled above) to js-host-core.
    # '/' must come last, otherwise the reverse proxies above are ignored.
    ProxyPass        /  http://js-host-core.example.com:2000/
    ProxyPassReverse /  http://js-host-core.example.com:2000/
</VirtualHost>

The core site now has ServerName js-host-core.example.com. All other configuration is the same.

The reason this solution is OK is that I can add or remove RewriteRule lines easily with a script, and when I restart this instance of apache, it restarts very quickly, and my core site stays up and running, so I don't have to worry about cycle time, losing my cache, or any other negative effects related to site cycling.

Share:
16,520

Related videos on Youtube

user1506104
Author by

user1506104

Updated on September 18, 2022

Comments

  • user1506104
    user1506104 almost 2 years

    I have many reverse proxies defined for my js-host VirtualHost, like so:

    /etc/apache2/sites-available/js-host

    <VirtualHost *:80>
    ServerName js-host.example.com
    [...]
    ProxyPreserveHost On
    ProxyPass        /serviceA http://192.168.100.50/
    ProxyPassReverse /serviceA http://192.168.100.50/
    ProxyPass        /serviceB http://192.168.100.51/
    ProxyPassReverse /serviceB http://192.168.100.51/
    [...]
    ProxyPass        /serviceZ http://192.168.100.75/
    ProxyPassReverse /serviceZ http://192.168.100.75/
    </VirtualHost>
    

    The js-host site is acting as shared config for all of the reverse proxies. This works, but managing the proxies involves edits to the shared config, and an apache2 restart.

    Is there a way to manage individual proxies with a2ensite and a2dissite (or a better alternative)? My main objective is to isolate each proxy config as a separate file, and manage it via commands.

    First Attempt

    I tried making separate files with their own VirtualHost entries for each service:

    /etc/apache2/sites-available/js-host-serviceA

    <VirtualHost *:80>
    ServerName js-host.example.com
    [...]
    ProxyPass        /serviceA http://192.168.100.50/
    ProxyPassReverse /serviceA http://192.168.100.50/
    </VirtualHost>
    

    /etc/apache2/sites-available/js-host-serviceB

    <VirtualHost *:80>
    ServerName js-host.example.com
    [...]
    ProxyPass        /serviceB http://192.168.100.51/
    ProxyPassReverse /serviceB http://192.168.100.51/
    </VirtualHost>
    

    The problem with this is apache2 loads the first VirtualHost for a particular ServerName, and ignores the rest. They aren't "merged" somehow as I'd hoped.