Question

I am working on a particular set-up as follows:

  • Several applications in multiple hosts and different ports
  • A server (assume balancer.local) running nginx listening on port 8080 for localhost, which acts as a proxy/load balancer for the applications running on the previous hosts
  • An apache2 server running on the same machine as nginx, listening on port 80 (open to the public), serving some contents directly for some ServerName and forwarding some other ServerName to localhost:8080, to let nginx do the load balancing work

The problem I have is that the number of hostnames to be redirected to nginx is growing fast, and I have an annoying list of vhosts which is becoming hard to maintain.

So, the question is: Is there a way I can define a default vhost in apache, without ServerNames, and make it redirect all the traffic which has not matched any other vhost to localhost:8080?

I already tried removing the ServerName directive, but the problem I have is that then ProxyPassReverse inserts its hostname into the outgoing URL.

At the moment, the only thing I was able to do is to reduce the number of rows in each vhost to the minimum, but it's still too much.

Here you have some configuration examples:

Nginx:

upstream foo {
        server foo1.local:9999 max_fails=3 fail_timeout=30s;
        server foo2.local:9999 max_fails=3 fail_timeout=30s;
}

upstream bar {
        server bar1.local:8888 max_fails=3 fail_timeout=30s;
        server bar2.local:8888 max_fails=3 fail_timeout=30s;
}
server {
        listen *:8080;
        server_name  foo.public.com;
        access_log  /var/log/nginx/foo.public.com-access.log  proxy;
        error_log   /var/log/nginx/foo.public.com-error.log;
        location / {
                proxy_pass         http://foo/;
                include            /etc/nginx/proxy_app.conf;
        }
}
server {
        listen *:8080;
        server_name  bar.public.com;
        access_log  /var/log/nginx/bar.public.com-access.log  proxy;
        error_log   /var/log/nginx/bar.public.com-error.log;
        location / {
                proxy_pass         http://bar/;
                include            /etc/nginx/proxy_app.conf;
        }
}

Apache:

<VirtualHost *:80>
        ServerName foo.public.com
        ErrorLog /var/log/httpd/nginx-redirect.sis.service-error.log
        CustomLog /var/log/httpd/nginx-redirect.sis.service-access.log combined
        ProxyPreserveHost On
        ProxyPass               /       http://localhost:8080/
        ProxyPassReverse        /       http://%{HTTP_HOST}:8080/
</VirtualHost>
<VirtualHost *:80>
        ServerName bar.public.com
        ErrorLog /var/log/httpd/nginx-redirect.sis.service-error.log
        CustomLog /var/log/httpd/nginx-redirect.sis.service-access.log combined
        ProxyPreserveHost On
        ProxyPass               /       http://localhost:8080/
        ProxyPassReverse        /       http://%{HTTP_HOST}:8080/
</VirtualHost>
<VirtualHost *:80>
    ServerName baz.public.com
    DocumentRoot /some/local/path
    <Directory "/">
      some irrelevant options
    </Directory>
</VirtualHost>

In this example there are only two vhosts forwarded into nginx, but in my real set-up there's more than 30!

As I said, I already tried to use a single vhost without the ServerName tag to forward the traffic, but I ended up obtaining http://balancer.local/some/path in my redirections, which obviously didn't work.

I also tried to use a single ServerName and multiple ServerAlias, but in that case, ProxyPassReverse used always the ServerName in the response.

Any suggestion?

Was it helpful?

Solution

I also tried to use a single ServerName and multiple ServerAlias, but in that case, ProxyPassReverse used always the ServerName in the response.

Probably you have UseCanonicalName On somewhere in your Apache config.

Try to set it Off explicitly in your VirtualHost.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top