Apache + Varnish : having both on port 80

Events happening in the community are now at Drupal community events on www.drupal.org.
ralt's picture

Hi,

Turned out I can't replicate the problem defined down there, but I guess it would've been solved thanks to Advagg. I now have an entirely different problem.

I have several virtualhosts on Apache, some of them will not be served with Varnish, but all listen to port 80.

So, the question is, how can I have Apache listening on port 80 for some virtualhosts, and Varnish listening on port 80 for other virtualhosts?

I'm having a weird problem and I can't get to solve it.

Firstly, here is the setup :

  • Debian Squeeze
  • Apache 2.2.16
  • PHP5-fpm
  • Varnish 3.0.2
  • Pressflow 6

I have a Drupal setup with a vhost correctly configured on port 80. I've used the default.vcl file from lullabot (available here) with the status.php file. I had to make a little change to the default.vcl file because of a syntax error (changes from 2.x versions to 3.x).

I changed this line :

<?php
set req
.http.Cookie = ";" req.http.Cookie;
?>

To :

<?php
set req
.http.Cookie = ";" + req.http.Cookie;
?>

Otherwise, I get this error when launching Varnish :

<?php
Message from VCC
-compiler:
Expected ';' got 'req.http.Cookie'
(program line 174), at
('input' Line 108 Pos 31)
   
set req.http.Cookie = ";" req.http.Cookie;
------------------------------
###############-

Running VCC-compiler failed, exit 1

VCL compilation failed
?>

Anyway, when I launch Varnish on port 8080, or anything else than 80, it works perfectly. I can get to http://www.domain.com:8080 and everything loads fast. I can also see with varnishlog that it's working correctly.

The problem is when I change the port of my Drupal setup to 8080 (I've also tried 81). I also change Varnish to listen on port 80, and it gets weird.

I can access the website on port 80, but the css/js files don't get loaded because of 404 errors. Also, varnishlog doesn't output anything.

I really don't get what's going on... Any help would be greatly appreciated :)

P.S. : I'm using the Varnish module for Drupal, On the administration page, Varnish answers correctly.

Comments

You could add another IP,

lotyrin's picture

You could add another IP, have certain hosts go to certain IPs (based on use of varnish or not) then have each process listen on port 80 only for their IP.

Other than that, you just don't.

I don't know if you'd really need to do that though, Varnish is simple and fast enough that I'd probably just let it know to ignore the set of hosts you want it to ignore, just pass through to apache.

This makes testing the VCL on the additional hosts and then enabling cache for them in the future a simple VCL change.

Bind apache to port 80 on the

alanmackenzie's picture

Bind apache to port 80 on the loopback interface. i.e. localhost/127.0.0.1

Bind varnish to port 80 on your Internet facing interface. e.g. 123.456.789.100

Write some VCL that uses pipe directive in your recv() function to force varnish to 'bit shuffle' data back and forth unmolested for certain hosts.

Assuming you use a Debian derivative:

In /etc/apache2/ports.conf:

NameVirtualHost 127.0.0.1:80
Listen 80

In /etc/default/varnish:

Change the -a flag on the DAEMON_OPTS variable to match your Internet facing interface e.g. -a 123.456.789.100:80

For more info read: man varnishd

I don't think this is what he

lotyrin's picture

I don't think this is what he meant (I think the idea was that both daemons were somehow listening on external 80), but I do tend to run this sort of setup instead of moving apache to a different port on the external interface.

Except that I prefer to have my VirtualHosts be IP agnostic:

NameVirtualHost *:80
Listen 127.0.0.1:80

the reason why You cannot use

Jānis Bebrītis's picture

the reason why You cannot use both webservers on same IP port 80 is because TCP stack does not allow doing that. What You can do is open socket on different port or IP address and pipe requests from one service (varnish) to another (apache).

You just should note that varnish is using HTTP/1.1 while stock drupal 6 answers using HTTP/1.0 headers. If You use varnish as frontend, You should use pressflow for drupal 6.