This brings the forum down for about 5-15 minutes each time.
One of the sites is behind the cloudflare proxy, so serves their offline cache no worries. But the other one does not use cloudflare.
I am wondering if discourse could export a static site of just say the public threads for an anonymous user with interaction buttons disabled and a banner at the top saying “This website is currently in read-only mode as it is undergoing upgrades.”, then serve that while the forum is upgrading, then once the forum is back online, delete the static cache.
If the DNS is managed by Cloudflare (even if it doesn’t use the proxy), it usually updates within seconds. During the update, you could point the domain at another server (like a maintenance page on Netlify/Vercel/Firebase/Surge/etc. where all paths point at an index.html file).
I haven’t tried it yet, but it might be possible to temporarily serve another backend using resolveOverride in a Cloudflare Worker (“serverless” function).
Yeah, be it a DNS change, or booting a temporary docker ngnix container listening on the same port that serves something is the easy part.
Right now the most difficult part of this is a static export with interactivity disabled and a banner added, respecting topic, post, category, index pages (search can be down). Then streamlining this replacement into the upgrade process, however that is easy enough.
Searching the forums for static export, doesn’t really seem it is a thing. I’ve made a Discourse API client already for a prior project, so could code something up that doesn’t emulate the design I guess.
Another factor of serving a static export for this purpose would be ensuring that the static pages are not cached by browsers and not cached by search engines.
If you run a two container installation downtime is under a minute. Or if you’re willing to run a load balancer you can make it zero. That’s easier than what you’re describing.
Also find out about SKIP_POST_DEPLOYMENT_MIGRATIONS=1. Briefly, you set that when you rebuild the bed container to keep it from breaking the database for the existing one, then migrate again without it after you have the new one running.