I thought I’d put a quick post here in the hope that I save someone a bit of frustration.
I was testing a new Drupal 7 site and I noticed that while the static files (JS, CSS, images, etc.) were all showing the proper cache lifetime, the nodes themselves were being sent back with a max-age=0, causing a reverse proxy cache miss on eminently-cacheable content. A bit of digging turned up the culprit: the mostly-hidden variable ‘page_cache_invoke_hooks’.
When running Drupal 7 behind a Varnish reverse proxy cache, make sure to include the following lines (suitably edited) in your settings.php:
# Tell Drupal it's behind a proxy
$conf['reverse_proxy'] = TRUE;
# Tell Drupal what addresses the proxy server(s) use
$conf['reverse_proxy_addresses'] = array('127.0.0.1','192.168.0.2');
# Bypass Drupal bootstrap for anonymous users so that Drupal sets max-age > 0
$conf['page_cache_invoke_hooks'] = FALSE;
Without the last variable, anonymous users will get nodes/pages with the max-age=0 and the proxy won’t cache it. Setting it to false allows the node to be sent with the max-age set to the cache lifetime set in the admin UI.