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

Deploying with Confidence

Deploying with Confidence

João Cardoso presented about how to deploy web apps and assets without zero downtime confidently.

Presented at ReactJS Community Meetup on September 13th, 2018

Finitec Meetups

September 13, 2018
Tweet

More Decks by Finitec Meetups

Other Decks in Technology

Transcript

  1. The Problem You’re working on a web application, and deploy

    often. You want to make sure updates are efficient for your users, and that no downtime/problems occur during deployments.
  2. index.html app.e9fda6ac1b27.js styles.543c2ad2230c.css Use content hashes • Based on file

    contents • Immutable • [contenthash] in webpack1 • Allows for long lived caches 1 https://webpack.js.org/guides/caching/#output-filenames
  3. index.html app.2eb2864b4e18.js vendor.6b06b7df03fa.js styles.543c2ad2230c.css Multiple bundles • Not all code

    changes as often • 3rd party dependencies are a good candidate for a separate bundle • Minimize the amount of code that needs to be re-downloaded https://webpack.js.org/guides/caching/#extracting-boilerplate
  4. ETag • Uniquely identifies a specific version of a resource

    • If the resource changes, the ETag value must also change • You can use a hash function to generate the ETag value based on the resource contents • Allows the browser to skip loading the resource if it hasn’t changed
  5. Cache-Control • Controls who can cache the response, under which

    conditions, and for how long • “public” or “private”: browsers will cache either, but intermediary caches such as CDNs will not cache private • “max-age”: number of seconds the response can be re- used from the time of the request • “no-cache”: always revalidate by checking first with server • “no-store”: never store the response data https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching
  6. index.html app.2eb2864b4e18.js vendor.6b06b7df03fa.js styles.543c2ad2230c.css Recommendations • Allow browsers and CDNs

    to cache immutable files for a really long time • Cache-Control: max-age=31536000
  7. index.html app.2eb2864b4e18.js vendor.6b06b7df03fa.js styles.543c2ad2230c.css Recommendations • Allow browsers to store

    the entrypoint to your application (i.e. HTML), but make them revalidate the stored response against the server • Cache-Control: no-cache
  8. 87% of users that encounter a page like that will

    never return* *Made up statistic. Real value is somewhere between 0% and 100%.
  9. app.2eb2864b4e18.js index.html styles.543c2ad2230c.css vendor.6b06b7df03fa.js Deployment is done by copying file

    by file, and fails halfway or request happens before all files are available
  10. app.2eb2864b4e18.js index.html styles.543c2ad2230c.css vendor.6b06b7df03fa.js If you’re deploying to multiple origins

    (e.g. servers) and requests are spread out, it can be even worse app.2eb2864b4e18.js index.html styles.543c2ad2230c.css vendor.6b06b7df03fa.js Origin 1 Origin 2
  11. app.a597e620d0d9.js index.html styles.0cbba5f5c5d6.css vendor.6b06b7df03fa.js A client may still try to

    request an older version of a resource app.2eb2864b4e18.js index.html styles.543c2ad2230c.css vendor.6b06b7df03fa.js v1 v2 Not all origins get the same deployment at the exact same time +
  12. app.2eb2864b4e18.js styles.543c2ad2230c.css vendor.6b06b7df03fa.js index.html Make sure every other file is

    successfully deployed before the entrypoint to the application (e.g. index.html)
  13. app.2eb2864b4e18.js styles.543c2ad2230c.css vendor.6b06b7df03fa.js Multiple origins? Deploy in stages, and wait

    for all origins to finish before moving to next stage. app.2eb2864b4e18.js styles.543c2ad2230c.css vendor.6b06b7df03fa.js Origin 1 Origin 2 Stage 1 index.html index.html Origin 1 Origin 2 Stage 2
  14. Keeping old files – the easy way If your origin

    is something like Amazon S3 or Google Cloud Storage, great! Just copy new files and don’t delete the old ones (at least not right away).
  15. Keeping old files – the hard way If your deployment

    is something akin to a docker container, here’s a working solution: • Before the actual deploy, copy all the files to some object storage (e.g. Amazon S3 or Google Cloud Storage). • If a request comes in for a file in the current deployment, great, we have it. • If we don’t have the file we can fallback to the object store.
  16. nginx example # Any route containing a file extension location

    ~ ^.+\..+$ { try_files $uri @fallback; add_header Cache-Control "public, max-age=31536000"; } location @fallback { proxy_pass https://storage.googleapis.com/my-bucket/$request_uri; proxy_intercept_errors on; add_header Cache-Control "public, max-age=31536000"; error_page 403 =404 @404; }
  17. app.js?2eb2864b4e18 styles.css?543c2ad2230c vendor.js?6b06b7df03fa index.html While today’s intermediary caches should have

    no caching problems with these, using it as an alternative may lead to unexpected behaviour if the wrong version of the file is loaded, because the file on disk may not match the version in the query string