Recent Changes of this Blog: Reverse-proxying Listed

21 Dec, 2019

As you may have noticed, this is not exactly the original en.typeblog.net blog. The original one has been deleted, and then recreated with most of the original posts and 301 redirections from the old URLs to the new ones.

I'm doing this partly to unify this blog with my main blog (zh_CN), typeblog.net, as part of a recent restructure of my hosting infrastructure for personal services. Previously, these two blogs were on completely different platforms: the main one was hosted with some spaghetti code I put together before I even entered university, while this English one (or rather, Random one), was simply a page on Listed, a blogging platform provided by my favourite note-taking application, Standard Notes.

The custom blogging software I made turned less and less maintainable as years went by. Most of the dependencies were outdated, and it was untested on newer version of Node.js (yes, it was based on Node), plus that CoffeeScript, the language I wrote it in, nearly went dead, once, during these years before recent revival. This is normally fine if I just leave it as-is, in the same way as

If it ain't broke, don't fix it

But if I somehow decide to move my hosting provider, then everything starts to break down. During the last migration of my main blog, I spent nearly a day just fixing compilation alone, not to mention all those issues after it could even run on its own. That program also depended heavily on GitHub: I have to push to a GitHub repository to add new posts to the blog, which was not exactly convenient for writing. I cannot just start writing anywhere because that there were little to none synchronization capability, except to push those unfinished posts to GitHub, in public, before they even go live.

In the past month I have initiated another "mass migration" of my personal services from the current provider to a new one for various reasons. At this point, the software the main blog ran on was mostly a pile of junk that I can't even bother to fix. This is when I made the decision that I should host both of my blogs on Listed, the platform that directly connects to my notes so that I can blog wherever I can access my notes.

Problems quickly emerged following that decision. First of all, it is not even possible to connect to multiple instances of Listed blogs from a single Standard Notes account. All SN plugins have to occupy a unique identifier, but all Listed blogs share the same identifier when added to SN, making it impossible for the SN client to distinguish between any two blogs. Secondly, Listed lacks some of the features I would really want to retain for my main blog. I didn't care that much for this random blog, but, as some examples, I'd really like to still have a naïve comment system, and I'd also like my inserted pictures scaled properly, with click-to-enlarge, instead of taking up a whole page just because it's high resolution.

Listed does allow customized CSS, but as far as I can tell this does not make it possible to implement a comment system or a click-to-enlarge picture. On the other hand, I'm not quite in the mood of reinventing the wheel again just yet, due to the trauma left on me from the last attempt. Listed, as a blogging service itself, does it pretty well and there seemed to be little reason I should rewrite the code; however I didn't want to bother the author with a bunch of feature requests that probably only I would like either. These "features" only make the software unnecessarily complicated, which was a big "no" to people at Standard Notes.

But I still want something as easy to maintain as possible for blogging, so that I could concentrate on writing, instead of configuring everything and making sure they do not break when I want to write. Trust me, after doing all of these, the "writing mood" would have long gone into the void. I am a self-hosting guy, but not for my blog. I want my blog to be available even during maintanence of my main server. I want to be able to write on it even while I am working to fix the server, or during boring server upgrade sessions. I even have some quick notes to myself that I would like to be able to access when the server is broken. The Standard Notes server software is a good example of something easy-to-maintain for self-hosting, plus that the writing aspect of the client software does not really need access to the server all the time (it only needs it for synchronization), making it "always available", and that's why I am thinking of writing everything with it. Forking Listed and running my own copy of it? That's some extra maintanence I would rather not get into right now -- basically it's not much different from maintaining the custom blogging system.

It then came to me that maybe I could just reverse-proxy my blog on Listed and insert some extra elements that I need to the page, instead of modifying Listed itself. This way, both Listed and my customizations can be kept very simple: none of them are re-inventing the wheel already done by the other. Listed would not have to care about my strange needs, and my customizations could have been just several lines of Nginx configuration, at least I thought it would be.

So I spent some time trying to use sub_filter of Nginx to replace the plugin identifier in the JSON response and also add styles and scripts to the page. Then I somehow stumbled upon HTMLRewriter of Cloudflare Worker, a "severless computing" provider. I'm not into any of those buzzwords though, but this API was really interesting to me because it made it quite easy to rewrite HTML documents. No more messing around with RegExp (which cannot really parse HTML), and I won't have to configure and maintain my own server for my blog, plus that it is JavaScript so JSON parsing and preprocessing is like a breeze. All I needed was to put together several lines of script and stuff it on their server, and I was good to go.

At this point, I could migrate my main blog to Listed successfully while retaining all of those features I want, with a simple reverse proxy in the front running on Cloudflare. I have also put toghether a simple comment system based on Cloudflare Workers, inserted to the page also via HTMLRewriter. No part of the blog itself needs my maintanence, and I can still stay comfortably in the ecosystem of Standard Notes. Of course, running everything on Cloudflare is a bad idea, but my blog is just for distributing public posts, and even user comments are nothing security-critical (it does not even need a password). I'm totally fine with it, especially if it can enable me to concentrate on writing, not blog software maintanence.

That's for my main blog, and after the successful migration, I thought I should apply the same thing to this English version too. After all, the picture problem I mentioned earlier was noticed entirely on this blog: I had an article with a picture from Wikipedia, and that single frickin' picture took up the entire screen. Unfortunately, the original English blog (the predecessor to this one) was bound to the en.typeblog.net domain via the official Listed server, and I could not remove it from the Listed control panel myself. Instead of sending an email and waiting for staff to remove that custom domain, I decided just to delete the original blog entirely and create a new one from scratch, with all the articles preserved and 301 redirections set on their respective URLs. This proved to be totally unnecessary: after deletion, the Listed server still accepts requests from en.typeblog.net, and will still try to request for HTTPS certificate for my domain when it needs to, only to find that it's no longer bound to it and ends up in errors. I still had to send them email to notify them about the removal. But hey, that's what I did and not reversible. And that is where we are now.

I'm not open-sourcing my reverse-proxy worker because, hey, that's not something valuable. It is so simple that anyone can probably put it together in around half an hour. I do not want people to start using it to work around the Extended limitation of custom domains on Listed either, though I'm literally doing that right now, except that I am actually an Extended subscriber, which kind of justifies it, at least for me. Since I write in multiple languages, it really does not make sense I cannot add multiple Listed blogs to one SN account...

Reflecting on the decision, it seemed that I was just offloading maintanence to others, like Cloudflare and Listed. It's not like anything is "serverless"; it's just that someone will fix things for me if it would ever go wrong. My scripts are so simple and maintanence-free only because I paid for someone (yes, I got the CF Worker paid plan, also Standard Notes Extended) to maintain a stable API and environment. I will most definitely still host security-critical systems myself, like the Standard Notes server itself and Mastodon. Blog is the one non-security-critical exception I would rather someone else host it for me, after so many years of frustration. I hope I could really start to write something, more frequently, from now on.