title: Set up Varnish + Drupal on Docker
body: <p>I have three docker containers, one is running php5+apache with Drupal installed, and the other one is running varnish 4.1, and the last one is running MySQL. Here's my docker-compose.yml</p>
  
  <pre><code>version: "2"
  services:
    app:
      container_name: drupal.app
      build: .build/php5-apache
      working_dir: "/var/www/html/"
      ports:
        - "8080:80"
      volumes:
        - ".:/var/www/html/"
      restart: always
      networks:
        vpcbr:
          ipv4_address: 10.5.0.5
      links:
        - db
    db:
      container_name: drupal.db
      #image: mysql:5.5
      build: .build/mysql
      ports:
        - "3306:3306"
      environment:
        MYSQL_ROOT_PASSWORD: dskjfskjhfnksdnf
      volumes:
        - ./data/mysql:/var/lib/mysql
      networks:
        vpcbr:
          ipv4_address: 10.5.0.4
      restart: always
    varnish:
      container_name: drupal.varnish
      build: .build/varnish
      ports:
        - "80:80"
      networks:
        vpcbr:
          ipv4_address: 10.5.0.3
      restart: always
      tty: true
  networks:
    vpcbr:
      driver: bridge
      ipam:
       config:
         - subnet: 10.5.0.0/16
           gateway: 10.5.0.1
  </code></pre>
  
  <p>And here's the default.vcl for the varnish</p>
  
  <pre><code>#
  # This is an example VCL file for Varnish.
  #
  # It does not do anything by default, delegating control to the
  # builtin VCL. The builtin VCL is called when there is no explicit
  # return statement.
  #
  # See the VCL chapters in the Users Guide at https://www.varnish-cache.org/docs/
  # and https://www.varnish-cache.org/trac/wiki/VCLExamples for more examples.
  
  # Marker to tell the VCL compiler that this VCL has been adapted to the
  # new 4.0 format.
  vcl 4.0;
  
  # Default backend definition. Set this to point to your content server.
  backend default {
      .host = "10.5.0.5";
      .port = "80";
  }
  
  sub vcl_recv {
      # Happens before we check if we have this in cache already.
      #
      # Typically you clean up the request here, removing cookies you don't need,
      # rewriting the request, etc.
  
    set req.backend_hint = bar.backend();
  
    # Do not cache these paths.
    if (req.url ~ "^/status\.php$" ||
        req.url ~ "^/update\.php" ||
        req.url ~ "^/install\.php" ||
        req.url ~ "^/apc\.php$" ||
        req.url ~ "^/admin" ||
        req.url ~ "^/admin/.*$" ||
        req.url ~ "^/user" ||
        req.url ~ "^/user/.*$" ||
        req.url ~ "^/users/.*$" ||
        req.url ~ "^/info/.*$" ||
        req.url ~ "^/flag/.*$" ||
        req.url ~ "^.*/ajax/.*$" ||
        req.url ~ "^.*/ahah/.*$" ||
        req.url ~ "^/system/files/.*$") {
  
      return (pass);
    }
  
    # Always cache the following file types for all users. This list of extensions
    # appears twice, once here and again in vcl_backend_response so make sure you edit both
    # and keep them equal.
    if (req.url ~ "(?i)\.(pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") {
      unset req.http.Cookie;
    }
  
    # Remove all cookies that Drupal doesn't need to know about. We explicitly
    # list the ones that Drupal does need, the SESS and NO_CACHE. If, after
    # running this code we find that either of these two cookies remains, we
    # will pass as the page cannot be cached.
    if (req.http.Cookie) {
      # 1. Append a semi-colon to the front of the cookie string.
      # 2. Remove all spaces that appear after semi-colons.
      # 3. Match the cookies we want to keep, adding the space we removed
      #    previously back. (\1) is first matching group in the regsuball.
      # 4. Remove all other cookies, identifying them by the fact that they have
      #    no space after the preceding semi-colon.
      # 5. Remove all spaces and semi-colons from the beginning and end of the
      #    cookie string.
      set req.http.Cookie = ";" + req.http.Cookie;
      set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
      set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|SSESS[a-z0-9]+|NO_CACHE)=", "; \1=");
      set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
      set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
  
      if (req.http.Cookie == "") {
        # If there are no remaining cookies, remove the cookie header. If there
        # aren't any cookie headers, Varnish's default behavior will be to cache
        # the page.
        unset req.http.Cookie;
      }
      else {
        # If there is any cookies left (a session or NO_CACHE cookie), do not
        # cache the page. Pass it on to Apache directly.
        return (pass);
      }
    }
  }
  
  sub vcl_backend_response {
      # Happens after we have read the response headers from the backend.
      #
      # Here you clean the response headers, removing silly Set-Cookie headers
      # and other mistakes your backend does.
  }
  
  sub vcl_deliver {
      # Happens when we have all the pieces we need, and are about to send the
      # response to the client.
      #
      # You can do accounting or modifying the final object here.
  }
  </code></pre>
  
  <p>I have used curl to test if the varnish server can connect to the drupal server through the ip 10.5.0.5 and the result is positive.</p>
  
  <p>However, whenever I try to access the web through <a href="http://localhost/" rel="nofollow noreferrer">http://localhost/</a> the varnish always gives me 503 error and can't fetch the Backend. </p>
  
  <p>Can anyone tell me is there something wrong with my default.vcl setting or the docker-compose setting.</p>