I'd like to see how to configure Nginx and Varnish.

I'm running several PHP sites and Rack-Sinatra sites as virtual hosts across two IP's. I'd like to prevent Nginx from having to serve static files, since I'm noticing some delays.

Edit: I've changed to Nginx, but the answer provided is pretty easy to port over to nginx.

2 Answers 2


Apache will still serve static files, but it will only serve them once. Perhaps the easiest way is to configure varnish to listen on all IP addresses for port 80, and configure Apache to listen to on localhost:8000 for example. Then you configure varnish to forward all requests it receives to localhost:8000 for Apache to handle.

I would go with a varnish configuration of:

# have varnish listen on port 80 (all addresses)
varnishd -a

Now within your vcl file:

backend default {
  .host = "localhost";
  .port = "8000";

sub vcl_recv {
  # add a unique header containing the client IP address
  set req.http.X-Orig-Forwarded-For = client.ip;

  # we're only handling static content for now so remove any
  # Cookie that was sent in the request as that makes caching
  # impossible.
  if (req.url ~ "\.(jpe?g|png|gif|ico|js|css)(\?.*|)$") {
    unset req.http.cookie;

vcl_fetch {
  # if the backend server adds a cookie to all responses,
  # remove it from static content so that it can be cached.
  if (req.url ~ "\.(jpe?g|png|gif|ico|js|css)(\?.*|)$") {
    unset obj.http.set-cookie;

Now within your Apache httpd.conf configuration, you want Apache to listen on localhost:8000 and define your virtual hosts on the same address:port


For each website, create a <VirtualHost> stanza. Within that stanza you need to tell Apache to set the Expires and cache-control headers on all static content so varnish knows to cache it.

  ServerName www.our-example-domain.com

  # Set expires and cache-control headers on static content and
  # tell caches that the static content is valid for two years
  ExpiresActive on

  <FilesMatch "\.(js|css|ico|gif|png|jpe?g)$">
    ExpiresDefault "access plus 2 year"
    Header append Cache-Control "public"

  # ... the rest of your web site configuration ...

I hope this helps.

  • dude — this looks awesome! I'm at work right now, but I'll try this and accept it when I get home.
    – arbales
    Nov 11, 2010 at 21:38
  • Although I no longer use Apache — nginx is the way to go!
    – arbales
    Nov 11, 2010 at 21:38

For the benefit of future readers, for the VCL example provides by rjk:

  • I'd use "remove" instead of "unset" for the HTTP cookie variable.
  • The subroutine declaration 'vcl_fetch {' should be written as 'sub vcl_fetch {', too.

Otherwise, spot on. :)

  • why is remove better than unset — does unset send a blank cookie or something?
    – arbales
    Jan 10, 2011 at 19:09
  • Because unset isn't supported anymore AFAIK.
    – sgerrand
    Jan 14, 2011 at 5:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .