4 ms·
Immutable JavaScript/CSS/Blobs/etc. We have a very typical [web] codebase, server-side code (e.g. business rules, database access, etc), server-side Html gener
by Someone1234 7y ago
Immutable JavaScript/CSS/Blobs/etc.
We have a very typical [web] codebase, server-side code (e.g. business rules, database access, etc), server-side Html generation, and JavaScript/CSS/Images/Fonts/etc stored elsewhere. Two repositories (content and code).
So the obvious question is: How do you manage deployment? Two repositories means two deployments, which means potential timing problems/issues/rollback difficulties.
The solution we use is painfully simple: We define the JavaScript/CSS/etc as immutable (cannot edit, cannot delete) and version it. If you want to bug fix example.js then it becomes example.js 1.0.1, 1.0.2, etc. You then need to re-point to the new version. The old versions will still exist and old/outdated references will continue to function.
This also allows our cache policy to be aggressive. We don't have to worry about browsers or intermediate proxies caching our resources for "too" long. We've never found editing files in-place, regardless of cache policy, to be reliable anyway. Some browsers seemingly ignore it (Chrome!).
We always deploy the "content" repository ahead of the "code" repository. But if we needed to rollback "code," it wouldn't matter because the old versions of "content" was never deleted or altered.
There's never a situation where we'd rollback "content" because you add, you don't edit or delete. If you added a bad version/bug, just up the version number and add the fix (or reference the older version until a fix is in "content," the old version will still be there).
- zawerf 7y agoI have recently been struggling with versioning(and learning devops in general) myself so I would love to hear more on this topic. For example if you rollback a deployment (or if you just have browsers who haven't refreshed yet), how do you make sure browser clients are talking to the right api backend version? How do you force them to upgrade or rollback? Will they even be routed to the same api server on multiple calls? This is especially bad with long-lived single page apps. (I already use immutable static files auto generated/hashed by create react app. I rely on cloudflare to cache them forever rather than never deleting from the build though)
- Someone1234 7y ago> how do you make sure browser clients are talking to the right api backend version? We version the URL itself. > How do you force them to upgrade or rollback? We don't use it often but we can embed an "obsolete" tag into the HTTP/AJAX response header which a global AJAX hook (jQuery) will read and bring up a prompt/force a page reload. We use it infrequently but it was added for just such an occasion. It is a bad user experience but it is a useful tool.
- mattmanser 7y agoA much easier way than this is to append a hash of the file instead of 'versioning' it. Some people add it as a query string, some add it into the filename. Been doing this for years with infinite (well, practically) cache settings. These days it's built into most js compression tools afaik.
- benologist 7y agoThis is the official way to do that I think - https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity https://developer.mozilla.org/en-US/docs/Web/Security/Subres...
- Someone1234 7y agoThat doesn't work, because no one file exists in isolation. If you're using version 32.14 of this, you want version 32.14 of that, and this other thing. Versioned directories make this kind of grouping natural and easy, co-mingled hashes do not (and you could do both but you have the downsides of both and no real upsides). Plus semantic versioning can help cross-team communication, there's no human understanding of raw hashes.
- diggan 7y agoYou don't necessary need to use a hash based on randomness. Either using the git commit as the version/hash or a hash based on the content of the file itself works. So as long as your entrypoint and it's references are versioning, everything follows from that. So if I load version A of index.html, it also points to version A of the scripts/styles. If you load version B, you get version B of the scripts/styles, since everything is versioned the same way.
- mattmanser 7y agoGit commit is a bad solution, you want to use the file hash so you can have multiple bundles that version automatically. Also, if you pushed a change to even some comments or something not related to code, your bundle will change. Often you have a bundle of library code that you rarely ever push changes to, and you don't want your clients to download each time you make minor changes.
- gitgud 7y agoThat's a great solution, and I think that's what a lot of webpack build systems do. In Angular, if a src file changes, then the corresponding build file hash changes. They call it cache-busting as it breaks the cache. What kind of web stack are you running?
- Someone1234 7y agoWe have Java and .Net Core (trying as a replacement) internet facing and Node.js for internal APIs. All on Linux. Some of this is due to organizational reasons, not technical. As for the "content" side, it is pretty stereotypical: Sass, TypeScript, AngularJS 1.xx (not a typo!), and too many npm dependencies. But there's too much NIH[0] between teams, which is why our structure is so important in other ways. [0] https://en.wikipedia.org/wiki/Not_invented_here https://en.wikipedia.org/wiki/Not_invented_here