Glitch-free deployment of static sites

Deploying a static site is not trivial. Here are four approaches, in increasing order of correctness:

  1. Sync and deleting during transfer. This is straightforward, but can lead to a situation where a not-yet-uploaded HTML page is loaded in the browser, referencing CSS/image assets that have been deleted (replaced) during the upload.

  2. Sync and delete after transfer. This is an improvement over the previous approach, but can still lead to inconsistencies while navigating the site, as some pages might have been updates while others have not yet.

  3. Instantaneous deploy, by decoupling upload from deployment. This can be done by switching a symlink (very fast) or a git checkout. Of course, this requires purging any caches.

  4. Split assets upload. This involves cache-busting assets by adding the content hash to the filename, and uploading those first. As a second step, the HTML files can be uploaded and instantaneously deployed. The third and last step involves deleting stale assets, which should be done after a small delay, about the duration of the longest reasonable full request (30s?).

The last approach is the only one that prevents glitchy site behavior during deployment.

This also explains why deploying static sites as a (Docker) container is generally a bad idea, unless you explicitly enable session affinity/sticky sessions.

What this means for web apps

SPAs, which are web apps that typically don’t reload after being loaded for the first time, won’t be able to make use of the newly deployed code.

Perhaps a good approach would be to regularly poke a version file on the server to compare with, and show a notification when a new version has become available, with a button to suggest reloading (and perhaps a link to the release notes).

But hey, I don’t have much experience with this as I’ve not ever worked on update mechanisms for web apps.

Note last edited January 2022.