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

Reverse caching proxies: Varnish or Nginx? - Te...

Reverse caching proxies: Varnish or Nginx? - Techorama 2014

Slides for my Varnish vs Nginx talk at Techorama 2014

Avatar for Thijs Feryn

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