Client-side caching for the nginx file server that is serving the assets for ui could be improved further:
Make sure index.html is never being served from cache without validating it is up to date
When we change the Vue application, a new bundles for JS and CSS are created. Once shipped, browsers should immediately pick up a new index.html document, referencing the new bundles.
Currently, this does not seem to work reliably. We do send ETag and Last-Modified headers with the root document, but there is no Cache-Control header, leaving it up to browsers to decide whether they are allowed to reuse a previously cached response. To trigger the behavior we want, Cache-Control: no-cache needs to be added to such responses. This means, the browser will only ever use a previously cached asset if the server returned a 304 Not Modified response.
Another option considering the small size of the index.html document would be using Cache-Control: no-store, forcing the browser to fetch the document on every reload.
Add harder caching for revisioned assets
JS and CSS bundles are revisioned by the build system. However, we do not send a Cache-Control header here either. As these files will never change after being created (as opposed to index.html), we can set "hard" cache control values to make sure users will never have to redownload the same bundle twice. Something like Cache-Control: max-age: 31536000, immutable should work well.
Bonus question
Serving a single page app like this is common practice. We could also try to find out if there is a "best-practices" nginx config or even Docker image that can do all of the above for us, and we can think about more important things.