Last active
January 3, 2016 13:09
-
-
Save chinthakagodawita/8467303 to your computer and use it in GitHub Desktop.
Nginx config for a Drupal installation with Varnish.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Demonz default Varnish config. | |
# | |
# Modified from: | |
# https://fourkitchens.atlassian.net/wiki/display/TECH/Configure+Varnish+3+for+Drupal+7 | |
# | |
# Default backend definition. Set this to point to your content | |
# server. | |
backend default { | |
.host = "MYSERVER"; | |
.port = "80"; | |
} | |
sub vcl_recv { | |
# Set exact request client IP for authentication purposes. | |
if (req.http.X-Forwarded-Proto == "https") { | |
set req.http.X-Auth-IP = req.http.X-Real-IP; | |
} | |
else { | |
set req.http.X-Auth-IP = client.ip; | |
} | |
# Use anonymous, cached pages if all backends are down. | |
if (!req.backend.healthy) { | |
unset req.http.Cookie; | |
} | |
# Allow the backend to serve up stale content if it is responding slowly. | |
set req.grace = 6h; | |
# Do not cache these paths. | |
if (req.url ~ "^/status\.php$" || | |
req.url ~ "^/update\.php$" || | |
req.url ~ "^/cron\.php$" || | |
req.url ~ "^/admin$" || | |
req.url ~ "^/admin/.*$" || | |
req.url ~ "^/flag/.*$" || | |
req.url ~ "^/batch.*$" || | |
req.url ~ "^/batch/.*$" || | |
req.url ~ "^.*/ajax/.*$" || | |
req.url ~ "^/admin/build/features" || | |
req.url ~ "^.*/ahah/.*$") { | |
return (pass); | |
} | |
# Always cache the following file types for all users. This list of extensions | |
# appears twice, once here and again in vcl_fetch so make sure you edit both | |
# and keep them equal. | |
if (req.url ~ "(?i)\.(nrg|docx|xslx|pptx|zip|bmp|rtf|iso|mp3|wav|mp4|avi|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]+|has_js|session_api_available|SSESS[a-z0-9]+|NO_CACHE)=", "; \1="); | |
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|__utma_a2a|has_js|amfID|session_api_available|highContrast)=[^;]*", ""); | |
set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", ""); | |
set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", ""); | |
# Remove has_js and Google Analytics __* cookies. | |
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(__[a-z]+|has_js)=[^;]*", ""); | |
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); | |
} | |
} | |
# Authorization has already been checked in NGINX, removing the attribute here | |
# to avoid missing varnish cash. | |
if (req.http.Authorization) { | |
unset req.http.Authorization; | |
} | |
} | |
sub vcl_hash { | |
if (req.http.hash-input) { | |
hash_data(req.http.hash-input); | |
} | |
# Add the fact that we may be on HTTPS to the cache hash. | |
if (req.http.X-Forwarded-Proto) { | |
hash_data(req.http.X-Forwarded-Proto); | |
} | |
} | |
# Code determining what to do when serving items from the Apache servers. | |
# beresp == Back-end response from the web server. | |
sub vcl_fetch { | |
# We need this to cache 404s, 301s, 500s. Otherwise, depending on backend but | |
# definitely in Drupal's case these responses are not cacheable by default. | |
if (beresp.status == 404 || beresp.status == 301 || beresp.status == 500) { | |
set beresp.ttl = 10m; | |
} | |
# Don't allow static files to set cookies. | |
# (?i) denotes case insensitive in PCRE (perl compatible regular expressions). | |
# This list of extensions appears twice, once here and again in vcl_recv so | |
# make sure you edit both and keep them equal. | |
if (req.url ~ "(?i)\.(nrg|docx|xslx|pptx|zip|bmp|rtf|iso|mp3|wav|mp4|avi|pdf|asc|dat|txt|doc|xls|ppt|tgz|csv|png|gif|jpeg|jpg|ico|swf|css|js)(\?.*)?$") { | |
unset beresp.http.set-cookie; | |
} | |
# Allow items to be stale if needed. | |
set beresp.grace = 6h; | |
# Support ban lurker in the Drupal varnish module. | |
set beresp.http.x-url = req.url; | |
set beresp.http.x-host = req.http.host; | |
# Uncomment in order to debug cookie issues. | |
# set beresp.http.X-Varnish-Cookie-Debug = "Cleaned request cookie: " + req.http.Cookie; | |
} | |
sub vcl_deliver { | |
if (obj.hits > 0) { | |
set resp.http.X-Varnish-Cache = "HIT"; | |
} | |
else { | |
set resp.http.X-Varnish-Cache = "MISS"; | |
} | |
} | |
sub vcl_error { | |
set obj.http.Content-Type = "text/html; charset=utf-8"; | |
set obj.http.Retry-After = "5"; | |
synthetic {" | |
<!-- Add your custom error page here --> | |
<html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> | |
<title>Server under maintenance | MY SITE</title> | |
<meta name="viewport" content="width=device-width"> | |
<!-- Use inline CSS --> | |
<style type="text/css"> | |
</style> | |
</head> | |
<body> | |
<div class="centering"> | |
<div class="logo"> | |
<!-- Use base64-encoded images or images hosted off-site (e.g. Amazon S3). --> | |
<a href="http://mysite/" title="MY SITE"> | |
<img alt="" src="data:image/png;{BASE64LOGOIMAGE}" style="max-width:100%;" alt="MY SITE"/> | |
</a> | |
</div><!-- logo --> | |
<h1 class="intro">The server is currently down for maintenance.</h1> | |
<div id="comingsoon"> | |
<p>We are running some routine maintenance on the server so please check back soon,<br />if we are not back in 30 minutes, please contact us.</p> | |
<p><b>Phone number</b> {PHONE NUMBER}<br></p> | |
</div> | |
</div><!-- centering --> | |
</body></html> | |
"}; | |
return (deliver); | |
} | |
# ------------------------------------------------------------------------------ | |
# Below is a commented-out copy of the default VCL logic. If you | |
# redefine any of these subroutines, the built-in logic will be | |
# appended to your code. | |
# sub vcl_recv { | |
# if (req.restarts == 0) { | |
# if (req.http.x-forwarded-for) { | |
# set req.http.X-Forwarded-For = | |
# req.http.X-Forwarded-For + ", " + client.ip; | |
# } else { | |
# set req.http.X-Forwarded-For = client.ip; | |
# } | |
# } | |
# if (req.request != "GET" && | |
# req.request != "HEAD" && | |
# req.request != "PUT" && | |
# req.request != "POST" && | |
# req.request != "TRACE" && | |
# req.request != "OPTIONS" && | |
# req.request != "DELETE") { | |
# /* Non-RFC2616 or CONNECT which is weird. */ | |
# return (pipe); | |
# } | |
# if (req.request != "GET" && req.request != "HEAD") { | |
# /* We only deal with GET and HEAD by default */ | |
# return (pass); | |
# } | |
# if (req.http.Authorization || req.http.Cookie) { | |
# /* Not cacheable by default */ | |
# return (pass); | |
# } | |
# return (lookup); | |
# } | |
# | |
# sub vcl_pipe { | |
# # Note that only the first request to the backend will have | |
# # X-Forwarded-For set. If you use X-Forwarded-For and want to | |
# # have it set for all requests, make sure to have: | |
# # set bereq.http.connection = "close"; | |
# # here. It is not set by default as it might break some broken web | |
# # applications, like IIS with NTLM authentication. | |
# return (pipe); | |
# } | |
# | |
# sub vcl_pass { | |
# return (pass); | |
# } | |
# | |
# sub vcl_hash { | |
# hash_data(req.url); | |
# if (req.http.host) { | |
# hash_data(req.http.host); | |
# } else { | |
# hash_data(server.ip); | |
# } | |
# return (hash); | |
# } | |
# | |
# sub vcl_hit { | |
# return (deliver); | |
# } | |
# | |
# sub vcl_miss { | |
# return (fetch); | |
# } | |
# | |
# sub vcl_fetch { | |
# if (beresp.ttl <= 0s || | |
# beresp.http.Set-Cookie || | |
# beresp.http.Vary == "*") { | |
# /* | |
# * Mark as "Hit-For-Pass" for the next 2 minutes | |
# */ | |
# set beresp.ttl = 120 s; | |
# return (hit_for_pass); | |
# } | |
# return (deliver); | |
# } | |
# | |
# sub vcl_deliver { | |
# return (deliver); | |
# } | |
# | |
# sub vcl_error { | |
# set obj.http.Content-Type = "text/html; charset=utf-8"; | |
# set obj.http.Retry-After = "5"; | |
# synthetic {" | |
# <?xml version="1.0" encoding="utf-8"?> | |
# <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | |
# "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
# <html> | |
# <head> | |
# <title>"} + obj.status + " " + obj.response + {"</title> | |
# </head> | |
# <body> | |
# <h1>Error "} + obj.status + " " + obj.response + {"</h1> | |
# <p>"} + obj.response + {"</p> | |
# <h3>Guru Meditation:</h3> | |
# <p>XID: "} + req.xid + {"</p> | |
# <hr> | |
# <p>Varnish cache server</p> | |
# </body> | |
# </html> | |
# "}; | |
# return (deliver); | |
# } | |
# | |
# sub vcl_init { | |
# return (ok); | |
# } | |
# | |
# sub vcl_fini { | |
# return (ok); | |
# } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Demonz default nginx config. | |
# HTTPS server | |
server { | |
listen 443; | |
server_tokens off; | |
ssl on; | |
# Update these to match your certificate locations. | |
ssl_certificate /etc/nginx/ssl/server.crt; | |
ssl_certificate_key /etc/nginx/ssl/server.key; | |
ssl_trusted_certificate /etc/nginx/ssl/bundle.crt; | |
# Enable OCSP stapling to reduce First-Byte-Time. | |
ssl_stapling on; | |
ssl_stapling_verify on; | |
ssl_session_cache shared:SSL:10m; | |
ssl_session_timeout 10m; | |
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; | |
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5:!DSS; | |
ssl_prefer_server_ciphers on; | |
# Update this to match your maximum POST/upload size. | |
client_max_body_size 128M; | |
location @proxy { | |
proxy_set_header X-Real-IP $remote_addr; | |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | |
proxy_set_header Host $host; | |
# Update this to point to your Varnish/HTTP server | |
proxy_pass http://127.0.0.1:80; | |
proxy_set_header X-Forwarded-Proto $scheme; | |
add_header Front-End-Https on; | |
# Enable HSTS | |
add_header Strict-Transport-Security max-age=157680000; | |
# By default we don't want to redirect this request | |
proxy_redirect off; | |
# Force timeouts if one of the backends has died | |
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; | |
} | |
location / { | |
try_files $uri @proxy; | |
} | |
# Allow long expires for static assets. | |
location ~* \.(js|css|woff|eot|svg|ttf|otf|png|jpg|jpeg|gif|ico)$ { | |
expires max; | |
try_files $uri @proxy; | |
} | |
# Advagg support. | |
location ~* files/advagg_(?:css|js)/ { | |
gzip_static on; | |
access_log off; | |
expires max; | |
add_header ETag ""; | |
add_header Cache-Control "max-age=290304000, no-transform, public"; | |
try_files $uri @proxy; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment