Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a server hosting 3 subdomains of the same domain, each with it's own IP. I need to setup varnish in front of apache for the reason that I server A LOT of small images and varnish works miracles.

Since the server is not named yet (the DNS point to the old one), I do the comparison with IPs (I do not know if this is the reason I get garbage)....

I've set apache on port 0.0.0.0:81 from cPanel and made backends on the default.vcl like so:

backend name1 {
        .host = "x1.y2.z3.w4";
        .port = "81";
}

backend name2 {
        .host = "x5.y6.z7.w8";
        .port = "81";
}

and so on, for all the subdomains

All the examples are saying :
put :

if (req.http.host ~ "x1.y2.z3.w4") {
        set req.backend = name1;
} else {
        set req.backend = name2;
}

which I add to a new vcl_recv subroutine definition like so:

sub vcl_recv {
 if (req.http.host ~ "x1.y2.z3.w4") {
            set req.backend = name1;
    } else {
            set req.backend = name2;
    }
return(lookup);
}

The result is that I get something only if I put specifically the x5.y6.z7.w8 IP (the exception to the above rule) and everything else redirects me to the default website cpanel page in error that it does not find anything.

the daemon options definition in the sysconfig/varnish file is:

DAEMON_OPTS="-a 0.0.0.0:80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -u varnish -g varnish \
             -s malloc,7G \
             -p thread_pool_add_delay=1 \
             -p thread_pools=4 \
             -p thread_pool_min=200 \
             -p thread_pool_max=4000 \
             -p session_linger=50 \
"

Needless to say that both ips work when I access them through apache's port 81.

Any ideas of what may go wrong? I am a total n00b in varnish VCL and any help or pointer is most welcome!

THANKS

share|improve this question
    
I am not sure varnish will get this right without using named hosts. –  coredump Apr 14 '11 at 13:18
add comment

1 Answer

up vote 1 down vote accepted

Found it!

backend domain1 {
        .host = "x1.y1.z1.w1";
        .port = "81";
}

backend domain2 {
        .host = "x2.y2.z2.w2";
        .port = "81";
}

and override the sub vcl_recv {

with:

sub vcl_recv {
        if ((server.ip == "x1.y1.z1.w1")) {
                set req.backend = domain1;
        } else if((server.ip == "x2.y2.z2.w2") || (req.http.host ~ "domain2.site.com")) {
                set req.backend = domain2;
        } else {
                set req.backend = domain3;
        }
        if (req.request == "GET" && req.url ~ "\.(css|gif|jpg|jpeg|bmp|png|ico|img|tga|wmf)$") {
                remove req.http.cookie;
                return(lookup);
        }
}

What I needed in the comparison was the server.ip variable

Just have in mind (I didn't and paid for it) that now you have the proxy server in front of you, the PHP $_SERVER['REMOTE_ADDR']; is no longer valid. It returns the address of the proxy (thus the site address). You will have to use _SERVER["HTTP_X_FORWARDED_FOR"] instead or make a surefire function to check them all:

function getIP()
{
    if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
    {
      $ip=$_SERVER['HTTP_CLIENT_IP'];
    }
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    {
      $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
    }
    else
    {
      $ip=$_SERVER['REMOTE_ADDR'];
    }
    return $ip;
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.