Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Reverse caching proxies: Varnish or Nginx? - Techorama 2014

Reverse caching proxies: Varnish or Nginx? - Techorama 2014

Slides for my Varnish vs Nginx talk at Techorama 2014

Thijs Feryn

May 27, 2014
Tweet

More Decks by Thijs Feryn

Other Decks in Technology

Transcript

  1. Why? ✓ Hide origin server ✓ SSL termination ✓ Load

    balancing ✓ Caching ✓ Compression
  2. What’s not cacheable ✓HTTP POST, PUT, DELETE ✓ Cookie &

    Set-Cookie headers ✓ Authorization ✓ TTL == 0
  3. Varnish ✓Poul-Henning Kamp ✓Verdens Gang AS ✓Redpill Linpro ✓Varnish software

    ✓Reverse proxy only ✓2005: ideas @ Verdens Gang ✓2006 : development & v1 ✓2008: v2 ✓2011: v3 ✓2014: v4 (April 29th)
  4. Nginx ✓Igor Sysoev ✓2002: development ✓2004: first release ✓15% of

    the internet ✓CK10 problem ✓Event driven, async ✓$3M Series A funding ✓$10M Series B funding ✓Webserver & reverse proxy
  5. curl  http://repo.varnish-­‐cache.org/debian/GPG-­‐key.txt  |  sudo  apt-­‐ key  add  -­‐   echo

     "deb  http://repo.varnish-­‐cache.org/ubuntu/  trusty   varnish-­‐3.0"  |  sudo  tee  -­‐a  /etc/apt/sources.list   sudo  apt-­‐get  update   sudo  apt-­‐get  install  varnish curl  http://repo.varnish-­‐cache.org/debian/GPG-­‐key.txt  |  sudo  apt-­‐ key  add  -­‐   echo  "deb  http://repo.varnish-­‐cache.org/debian/  wheezy   varnish-­‐3.0"  |  sudo  tee  -­‐a  /etc/apt/sources.list   sudo  apt-­‐get  update   sudo  apt-­‐get  install  varnish
  6. deb  http://nginx.org/packages/ubuntu/  trusty  nginx   deb-­‐src  http://nginx.org/packages/ubuntu/  trusty  nginx deb

     http://nginx.org/packages/debian/  wheezy  nginx   deb-­‐src  http://nginx.org/packages/debian/  wheezy  nginx Go  to  h&p://wiki.nginx.org/Pgp  for  PGP  signature   Go  to  h&p://wiki.nginx.org/Install  for  more  info
  7. DAEMON_OPTS="-­‐a  :80  \   -­‐T  localhost:6082  \   -­‐f  /etc/varnish/default.vcl

     \   -­‐S  /etc/varnish/secret  \   -­‐s  malloc,256m" In  “/etc/default/varnish”
  8. backend  default  {              .host

     =  "127.0.0.1";              .port  =  "8080";   } In  “/etc/varnish/default.vcl”
  9. server  {      listen          

       80;      server_name    host-­‐name.dev;      access_log      /var/log/nginx/access.log;      error_log      /var/log/nginx/error.log;   !    location  /  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;   proxy_cache_key  "$scheme://$host $request_uri";   proxy_cache_valid      200  302    1h;   }   } In  “/etc/nginx/sites-­‐enabled”
  10. server  {   listen            

     80;   server_name    nginx-­‐proxy.dev;      root      /home/data/www;      access_log    /var/log/nginx/access.log;      access_log    /var/log/nginx/error.log;      location  /  {      index    index.php;      }   location  ~  \.php$  {   fastcgi_split_path_info  ^(.+\.php)(/.+)$;   fastcgi_pass  127.0.0.1:9000;   fastcgi_index  index.php;   include  fastcgi_params;   fastcgi_param    SCRIPT_FILENAME      $request_filename;   fastcgi_cache      fastcgi-­‐cache;   fastcgi_cache_valid      200  302    1h;   fastcgi_cache_key  "$scheme://$host$request_uri";      }   } 38
  11. ✓POST, DELETE & PUT ✓cookies & auth headers ✓set-cookie headers

    ✓cache ttl <= 0 (< v4) ✓“no-cache", "no-store", „private” in v4 Varnish wil not cache
  12. set  $bypass  0;   if  ($http_cookie)  {   set  $bypass

     1;   }   fastcgi_cache_bypass  $bypass;   fastcgi_no_cache  $bypass; Nginx caches cookies by default
  13. 4+05:26:25   Hitrate  ratio:            

     10            100            254   Hitrate  avg:          0.8486      0.7619      0.7285   !          1760818                  6.99                  4.82  client_conn  -­‐  Client  connections  accepted          11088687                25.96                30.36  client_req  -­‐  Client  requests  received            8042715                11.98                22.02  cache_hit  -­‐  Cache  hits            2609561                11.98                  7.15  cache_miss  -­‐  Cache  misses                47104                  1.00                  0.13  backend_conn  -­‐  Backend  conn.  success                    610                  0.00                  0.00  backend_fail  -­‐  Backend  conn.  failures            2998265                12.98                  8.21  backend_reuse  -­‐  Backend  conn.  reuses                12081                  0.00                  0.03  backend_toolate  -­‐  Backend  conn.  was  closed            3010356                13.98                  8.24  backend_recycle  -­‐  Backend  conn.  recycles                      13                  0.00                  0.00  backend_retry  -­‐  Backend  conn.  retry                    520                  0.00                  0.00  fetch_head  -­‐  Fetch  head            2857965                11.98                  7.83  fetch_length  -­‐  Fetch  with  Length              151309                  2.00                  0.41  fetch_chunked  -­‐  Fetch  chunked                  4404                  0.00                  0.01  fetch_close  -­‐  Fetch  wanted  close                    676                  0.00                  0.00  fetch_failed  -­‐  Fetch  failed                31164                  0.00                  0.09  fetch_304  -­‐  Fetch  no  body  (304)                    220                    .                        .      n_sess_mem  -­‐  N  struct  sess_mem                      53                    .                        .      n_sess  -­‐  N  struct  sess                29540                    .                        .      n_object  -­‐  N  struct  object                29561                    .                        .      n_objectcore  -­‐  N  struct  objectcore                  5058                    .                        .      n_objecthead  -­‐  N  struct  objecthead                  2613                    .                        .      n_waitinglist  -­‐  N  struct  waitinglist                        3                    .                        .      n_vbc  -­‐  N  struct  vbc                      22                    .                        .      n_wrk  -­‐  N  worker  threads                  1789                  0.00                  0.00  n_wrk_create  -­‐  N  worker  threads  created  
  14.      11  SessionOpen    c  12.12.12.1  53727  :80  

         11  ReqStart          c  12.12.12.1  53727  1401010767        11  RxRequest        c  GET        11  RxURL                c  /        11  RxProtocol      c  HTTP/1.1        11  RxHeader          c  Host:  12.12.12.6        11  RxHeader          c  User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.8;  rv:17.0)   Gecko/20100101  Firefox/17.0        11  RxHeader          c  Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8        11  RxHeader          c  Accept-­‐Language:  nl,en;q=0.7,fr-­‐be;q=0.3        11  RxHeader          c  Accept-­‐Encoding:  gzip,  deflate        11  RxHeader          c  Connection:  keep-­‐alive        11  VCL_call          c  recv  lookup        11  VCL_call          c  hash        11  Hash                  c  /        11  Hash                  c  12.12.12.6        11  VCL_return      c  hash        11  VCL_call          c  miss  fetch        11  Backend            c  13  default  default        11  TTL                    c  1401010767  RFC  0  -­‐1  -­‐1  1357920021  0  1357920020  0  0        11  VCL_call          c  fetch        11  TTL                    c  1401010767  VCL  120  -­‐1  -­‐1  1357920021  -­‐0        11  VCL_return      c  hit_for_pass        11  ObjProtocol    c  HTTP/1.1        11  ObjResponse    c  OK        11  ObjHeader        c  Date:  Fri,  11  Jan  2013  16:00:20  GMT        11  ObjHeader        c  Server:  Apache        11  ObjHeader        c  X-­‐Powered-­‐By:  PHP/5.3.2-­‐1ubuntu4.18        11  ObjHeader        c  Cache-­‐Control:  no-­‐cache,  no-­‐store,  max-­‐age=0   Client  
  15.      11  VCL_return      c  hit_for_pass    

       11  ObjProtocol    c  HTTP/1.1        11  ObjResponse    c  OK        11  ObjHeader        c  Date:  Fri,  11  Jan  2013  16:00:20  GMT        11  ObjHeader        c  Server:  Apache        11  ObjHeader        c  X-­‐Powered-­‐By:  PHP/5.3.2-­‐1ubuntu4.18        11  ObjHeader        c  Cache-­‐Control:  no-­‐cache,  no-­‐store,  max-­‐age=0        11  ObjHeader        c  Vary:  Accept-­‐Encoding        11  ObjHeader        c  Content-­‐Encoding:  gzip        11  ObjHeader        c  Content-­‐Length:  119        11  ObjHeader        c  Content-­‐Type:  text/html        11  Gzip                  c  u  F  -­‐  119  336  80  80  887        11  VCL_call          c  deliver  deliver        11  TxProtocol      c  HTTP/1.1        11  TxStatus          c  200        11  TxResponse      c  OK        11  TxHeader          c  Server:  Apache        11  TxHeader          c  X-­‐Powered-­‐By:  PHP/5.3.2-­‐1ubuntu4.18        11  TxHeader          c  Cache-­‐Control:  no-­‐cache,  no-­‐store,  max-­‐age=0        11  TxHeader          c  Vary:  Accept-­‐Encoding        11  TxHeader          c  Content-­‐Encoding:  gzip        11  TxHeader          c  Content-­‐Type:  text/html        11  TxHeader          c  Content-­‐Length:  119        11  TxHeader          c  Accept-­‐Ranges:  bytes        11  TxHeader          c  Date:  Fri,  11  Jan  2013  16:00:20  GMT        11  TxHeader          c  X-­‐Varnish:  1401010767        11  TxHeader          c  Age:  0        11  TxHeader          c  Via:  1.1  varnish        11  TxHeader          c  Connection:  keep-­‐alive        11  Length              c  119        11  ReqEnd              c  1401010767  1357920020.712090731  1357920020.727306366  0.000087738   Client  
  16.      13  BackendClose  -­‐  default        13

     BackendOpen    b  default  127.0.0.1  51597  127.0.0.1  8080        13  TxRequest        b  GET        13  TxURL                b  /        13  TxProtocol      b  HTTP/1.1        13  TxHeader          b  Host:  12.12.12.6        13  TxHeader          b  User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.8;  rv:17.0)   Gecko/20100101  Firefox/17.0        13  TxHeader          b  Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8        13  TxHeader          b  Accept-­‐Language:  nl,en;q=0.7,fr-­‐be;q=0.3        13  TxHeader          b  X-­‐Forwarded-­‐For:  12.12.12.1        13  TxHeader          b  X-­‐Varnish:  1401010767        13  TxHeader          b  Accept-­‐Encoding:  gzip        13  RxProtocol      b  HTTP/1.1        13  RxStatus          b  200        13  RxResponse      b  OK        13  RxHeader          b  Date:  Fri,  11  Jan  2013  16:00:20  GMT        13  RxHeader          b  Server:  Apache        13  RxHeader          b  X-­‐Powered-­‐By:  PHP/5.3.2-­‐1ubuntu4.18        13  RxHeader          b  Cache-­‐Control:  no-­‐cache,  no-­‐store,  max-­‐age=0        13  RxHeader          b  Vary:  Accept-­‐Encoding        13  RxHeader          b  Content-­‐Encoding:  gzip        13  RxHeader          b  Content-­‐Length:  119        13  RxHeader          b  Content-­‐Type:  text/html        13  Fetch_Body      b  4(length)  cls  0  mklen  1        13  Length              b  119        13  BackendReuse  b  default   Backend  
  17. Varnishlog examples varnishlog  -­‐c  -­‐m"VCL_call:hit"  |  grep  RxURL varnishlog  -­‐c

     -­‐m"VCL_call:miss"  |  grep  RxURL varnishlog  -­‐a  -­‐w  /tmp/varnish.log varnishlog  -­‐r  /tmp/varnish.log varnishlog  -­‐i  RxHeader  -­‐I  Cookie
  18. list  length  20   !      107.57  RxHeader  

               User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W      101.96  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        82.49  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          69.90  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  MSIE          64.04  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        43.74  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          22.01  RxHeader              User-­‐Agent:  Mozilla/5.0  (iPod;  U;  CPU  iPho        21.43  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE          19.86  RxHeader              User-­‐Agent:  Mozilla/5.0  (X11;  Linux  x86_64        15.47  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W        12.96  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W          4.87  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;  MSIE            2.97  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  MSIE            2.75  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  W          2.56  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows  NT  6.1;  r          0.97  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows;  U;  Windo          0.86  RxHeader              User-­‐Agent:  Mozilla/5.0  (iPhone;  CPU  iPhon          0.83  RxHeader              User-­‐Agent:  Mozilla/5.0  (Windows;  U;  Windo          0.53  RxHeader              User-­‐Agent:  Mozilla/5.0  (compatible;  Googl          0.44  RxHeader              User-­‐Agent:  Mozilla/4.0  (compatible;)   !
  19. Varnishtop examples varnishtop  -­‐i  RxHeader  -­‐I  \^User-­‐Agent varnishtop  -­‐i  RxRequest

    varnishtop  -­‐i  RxHeader  -­‐I  \^Host varnishtop  -­‐i  RxHeader  -­‐I  Cookie
  20. 1

  21. 2

  22. 3

  23.      11  SessionOpen    c  12.12.12.1  53727  :80  

         11  ReqStart          c  12.12.12.1  53727  1401010767        11  RxRequest        c  GET        11  RxURL                c  /        11  RxProtocol      c  HTTP/1.1        11  RxHeader          c  Host:  12.12.12.6        11  RxHeader          c  User-­‐Agent:  Mozilla/5.0  (Macintosh;  Intel  Mac  OS  X  10.8;  rv:17.0)   Gecko/20100101  Firefox/17.0        11  RxHeader          c  Accept:  text/html,application/xhtml+xml,application/xml;q=0.9,*/ *;q=0.8        11  RxHeader          c  Accept-­‐Language:  nl,en;q=0.7,fr-­‐be;q=0.3        11  RxHeader          c  Accept-­‐Encoding:  gzip,  deflate        11  RxHeader          c  Connection:  keep-­‐alive        11  VCL_call          c  recv  lookup        11  VCL_call          c  hash        11  Hash                  c  /        11  Hash                  c  12.12.12.6        11  VCL_return      c  hash        11  VCL_call          c  miss  fetch        11  Backend            c  13  default  default        11  TTL                    c  1401010767  RFC  0  -­‐1  -­‐1  1357920021  0  1357920020  0  0        11  VCL_call          c  fetch        11  TTL                    c  1401010767  VCL  120  -­‐1  -­‐1  1357920021  -­‐0        11  VCL_return      c  hit_for_pass        11  ObjProtocol    c  HTTP/1.1        11  ObjResponse    c  OK        11  ObjHeader        c  Date:  Fri,  11  Jan  2013  16:00:20  GMT        11  ObjHeader        c  Server:  Apache        11  ObjHeader        c  X-­‐Powered-­‐By:  PHP/5.3.2-­‐1ubuntu4.18        11  ObjHeader        c  Cache-­‐Control:  no-­‐cache,  no-­‐store,  max-­‐age=0   Got it?
  24. Cache key sub  vcl_hash  {   hash_data(req.url);   if  (req.http.host)

     {   hash_data(req.http.host);   }  else  {   hash_data(server.ip);   }   return  (hash);   }
  25. Hashing cookies sub  vcl_hash  {   if(req.http.Cookie  ~  "country"){  

    hash_data(regsuball(req.http.Cookie,   "^.+;?  ?country=([a-­‐zA-­‐Z0-­‐9]+) (  |;|  ;).*$","\1"));      }   }
  26. Hashing cookies set  $key  "$scheme://$host$request_uri";   if  ($http_cookie  ~*  "country=([^;]+)(?:;|

    $)"){   set  $key  "$scheme://$host$request_uri $1";   }   proxy_cache_key  $key;   fastcgi_cache_key  $key;
  27. sub  vcl_recv  {              

       if  (req.request  ==  "PURGE")  {                                  return  (lookup);                  }   }   sub  vcl_hit  {                  if  (req.request  ==  "PURGE")  {                                  purge;                                  error  200  "Purged";                  }   }   sub  vcl_miss  {                  if  (req.request  ==  "PURGE")  {                                  error  404  "Not  in  cache";                  }   } Purge config
  28. sub  vcl_recv  {              

       if  (req.request  ==  "PURGE")  {                          ban("req.http.host  ==  "  +  req.http.host  +   "  &&  req.url  ~  "  +  req.url);   error  200  "Banned";                  }   } sub  vcl_recv  {                  if  (req.request  ==  "PURGE")  {   ban("req.http.host  ==  "  +  req.http.host  +  "  &&   req.url  ==  "  +  req.url);   error  200  "Banned";                  }   } Ban config Ban  URL Ban  URL   pattern
  29. sub  vcl_recv  {              

       if  (req.request  ==  "PURGE")  {                          ban("obj.http.x-­‐host  ==  "  +  req.http.host  +   "  &&  obj.http.x-­‐url  ==  "  +  req.url);                          error  200  "Banned";                  }   }   sub  vcl_fetch  {                  set  beresp.http.x-­‐url  =  req.url;                  set  beresp.http.x-­‐host  =  req.http.host;   }   ! sub  vcl_deliver  {                  unset  resp.http.x-­‐url;                  unset  resp.http.x-­‐host;   } „Smart” bans
  30. h&ps://github.com/FRiCKLE/ngx_cache_purge    location  /  {          

           index    index.php;                  error_page  477  =  @purge;                  if  ($request_method  =  PURGE)  {                                  return  477;                  }      }      location  @purge  {              access_log  /var/log/nginx/caching.purge.log;              fastcgi_cache_purge  fastcgi-­‐cache  "$scheme://$host $request_uri";      } Purge config
  31. h&ps://github.com/FRiCKLE/ngx_cache_purge    location  /  {          

           index    index.php;                  error_page  477  =  @purge;                  if  ($request_method  =  PURGE)  {                                  return  477;                  }      }      location  @purge  {              access_log  /var/log/nginx/caching.purge.log;              proxy_cache_purge  proxy-­‐cache  "$scheme://$host $request_uri";      } Purge config
  32. probe healthcheck {! .url = "/status.php";! .interval = 60s;! .timeout

    = 0.3 s;! .window = 8;! .threshold = 3;! .initial = 3;! .expected_response = 200;! }! ! backend www {! .host = "www.example.com";! .port = "http";! .probe = healthcheck;! } Health probes
  33. server {! ...! location / {! proxy_pass http://backend;! health_check match=welcome;!

    }! }! ! match welcome {! status 200;! header Content-Type = text/html;! body ~ "Welcome to nginx!";! } Health probes
  34. backend  one  {        .host  =  “localhost”;  

         .port  =  “80”;   }   ! backend  two  {        .host  =  “127.0.0.1”;        .port  =  “81”;   }   ! director  localhosts  random  {          {  .backend  =  one;  .weight=4;}          {  .backend  =  two;  .weight=6;}          {  .backend  =  {  
                        .host  =  “localhost”;  
                        .port  =  “82”;                    }            }   }   ! sub  vcl_recv  {          set  req.backend  =  localhosts;   } Random
  35. Fallback director  localhosts  fallback  {          {

     .backend  =  one;}          {  .backend  =  two;}   }   sub  vcl_recv  {          set  req.backend  =  localhosts;   } Picks  first   healthy   backend Order   matters
  36. director  localhosts  client  {          {  .backend

     =  one;  .weight=1;  }          {  .backend  =  two;  .weight=1;  }   }   sub  vcl_recv  {          set  req.backend  =  localhosts;          //Load  balance  by  client  IP,  this  is  the  default            set  client.identity  =  client.ip;   } IP hash Uses   client.identity
  37. upstream backend {! server backend1.example.com;! server backend2.example.com backup;! }! !

    server {! location / {! proxy_pass http://backend;! }! } Fallback
  38. upstream backend {! ip_hash;! server backend1.example.com weight=2;! server backend2.example.com;! server

    backend3.example.com down;! server backend4.example.com;! }! ! server {! location / {! proxy_pass http://backend;! }! } IP hash
  39. sub  vcl_deliver  {      if  (obj.hits  >  0)  {

             set  resp.http.X-­‐Cache  =  "HIT";      }      else  {          set  resp.http.X-­‐Cache  =  "MISS";      }   } HIT/MISS marker
  40. ✓MISS ✓EXPIRED ➡expired, request was passed to backend ✓UPDATING ➡expired,

    stale response was used due to proxy/ fastcgi_cache_use_stale updating ✓STALE ➡expired, stale response was used due to proxy/ fastcgi_cache_use_stale ✓HIT HIT/MISS marker add_header  X-­‐Cache  $upstream_cache_status;  
  41. sub  vcl_fetch  {          if(req.url  ~  "^/bla")

     {                  set  beresp.ttl  =  10s;          }  else  {                  set  beresp.ttl  =  3600s;          }   } Force TTL
  42. location  /  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;

      proxy_cache_key  "$scheme://$host$request_uri";   proxy_cache_valid      200  302    1h;   }   location  ~  /bla  {   proxy_pass    http://localhost:8080;   proxy_cache  proxy-­‐cache;   proxy_cache_key  "$scheme://$host$request_uri";   proxy_cache_valid      200  302    10s;   } Force TTL
  43. <html>! <body>! <table>! <tr>! <td colspan="2" >! <?php include('header.php') ?>!

    </td>! </tr>! <tr>! <td><?php include('menu.php') ?></td>! <td><?php include('main.php') ?></td>! </tr> ! <tr>! <td colspan="2" > ! <?php include('footer.php') ?>! </td>! </tr> ! </table>! </body>! </html>
  44. <html>! <body>! <table>! <tr>! <td colspan="2" >! <esi:include src="/header.php" />!

    </td>! </tr>! <tr>! <td><esi:include src="/menu.php" /></td>! <td><esi:include src="/main.php" /></td>! </tr> ! <tr>! <td colspan="2" > ! <esi:include src="/footer.php" /> ! ! </td>! </tr> ! </table>! </body>! </html>
  45. sub  vcl_recv  {      set  req.http.Surrogate-­‐Capability=”key=ESI/ 1.0";   }

      sub  vcl_fetch  {      if(beresp.http.Surrogate-­‐Control~"ESI/1.0")  {          unset  beresp.http.Surrogate-­‐Control;      set  beresp.do_esi=true;          }   }  
  46. <html>! <body>! <table>! <tr>! <td colspan="2" >! <!--# include virtual="/header.php"

    -->! </td>! </tr>! <tr>! <td> <!--# include virtual="/menu.php" --> </td>! <td> <!--# include virtual="/main.php" --> </td>! </tr> ! <tr>! <td colspan="2" > ! <!--# include virtual="/footer.php" --> ! ! </td>! </tr> ! </table>! </body>! </html> Highest  TTL   is  used
  47. server  {      listen  443;      ssl  on;

           ssl_certificate  /path/to/ssl.crt;      ssl_certificate_key    /path/to/ssl.key;      server_name    hostname.dev;      access_log    /var/log/nginx/access.log;      error_log    /var/log/nginx/error.log;   !    location  /  {              proxy_pass  http://localhost:80;     proxy_set_header    X-­‐Real-­‐IP    $remote_addr;     proxy_cache      proxy-­‐cache;     proxy_cache_key  "$scheme://$host$request_uri";     proxy_cache_valid      200  302    1h;      }   } SSL