Apache mod_proxy: Multiple virtual hosts disable each other

13,882

You need to use a single virtual host to handle both!

Apache matches vhosts based on the HTTP Host header. Since the hostname is the same regardless of whether a client is accessing redmine or jenkins, both must in the same vhost.

What is happening with your current configuration is that Apache is determining which vhost to match as soon as it sees the Host header. Because 'j' comes before 'r' alphabetically, it is giving priority to your jenkins vhost file, even though both match.

You are trying to match based on the request URI, and proxy accordingly.

The <Proxy> directive already has this functionality built in!

You could use something like the following in a single vhost to accomplish your objective:

<VirtualHost *:80>
ServerAdmin [email protected]
ServerName sub.domain.com
ProxyRequests Off

<Proxy http://sub.domain.com/jenkins>

    Order deny,allow
    Allow from all

    ProxyPreserveHost off
    ProxyPass http://localhost:8080/jenkins
    ProxyPassReverse http://localhost:8080/jenkins

</Proxy>
<Proxy http://sub.domain.com/redmine>

    Order deny,allow
    Allow from all

    ProxyPreserveHost off
    ProxyPass http://localhost:8081/redmine
    ProxyPassReverse http://localhost:8081/redmine

</Proxy>

</VirtualHost>
Share:
13,882

Related videos on Youtube

Michael Joseph
Author by

Michael Joseph

Software Engineer and Open Source enthusiast.

Updated on September 18, 2022

Comments

  • Michael Joseph
    Michael Joseph over 1 year

    I have an Ubuntu 12.04 server, which had Redmine already installed on a stand-alone apache (everything under /opt/redmine). I wanted to install an instance of Jenkins on the same system, without modifying the existing set-up too much. I want the two services to be accessible under sub.domain.com/redmine and sub.domain.com/jenkins respectively.

    I changed Redmines apache to listen on port 8081 instead of 80, installed an additional apache via apt, and set up a virtual host that proxies '/redmine' to localhost:8081/redmine. Thus far everything worked fine. Redmine was accessible as before. However, when I set up Jenkins the same way, with tomcat listening on port 8080, the URL prefix 'jenkins' and a new virtual host, Redmine stops working, i.e. I get a 404. When I remove the Jenkins virtual host, Redmine works again.

    Here are the two files under /etc/apache2/sites-available, which I enable/disable via a2ensite/a2dissite.

    Redmine:

    <VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName sub.domain.com
        ProxyRequests Off
        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        ProxyPreserveHost off
        ProxyPass /redmine http://localhost:8081/redmine
        ProxyPassReverse /redmine http://localhost:8081/redmine
    </VirtualHost>
    

    Jenkins:

    <VirtualHost *:80>
        ServerAdmin [email protected]
        ServerName sub.domain.com
        ProxyRequests Off
        <Proxy *>
            Order deny,allow
            Allow from all
        </Proxy>
        ProxyPreserveHost off
        ProxyPass /jenkins http://localhost:8080/jenkins
        ProxyPassReverse /jenkins http://localhost:8080/jenkins
    </VirtualHost>
    

    I assume there is an issue with one or both of those files. I copied them from a Jenkins tutorial that assumed only a single virtual host. Wherever I look for mod_proxy solutions for multiple hosts, I find examples which map different ports to different domains, i.e. with different ServerNames. But that is not what I want. Do I have to use the RewriteEngine?

  • Michael Joseph
    Michael Joseph over 9 years
    Thanks for the explanation, it makes sense to me now. Unfortunately, my apache complains about another problem with your example vhost: 'ProxyPass|ProxyPassMatch can not have a path when defined in a location' Can this be fixed? httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass
  • Joe Sniderman
    Joe Sniderman over 9 years
    ok, so take the path part off the proxypass and proxypass reverse bits. makes sense, because the path is already specified by the location. Edited my answer to reflect this.