Hosting Ghost on K8S

That's it, I've been bitten, or rather possessed, by Ghost. And for good reason! I was previously hosting my personal blog on Github using their "Pages" service. Due to my own lack of judgement, I wasn't using a static site generator so every page still there is "hand-made" HTML. Story aside, I really like Ghost, so have decided to put my website here. Also it becomes less of a chore to write new stuff, so hopefully I'll be more morivated to write. Well, this is the story of how I got Ghost installed on my K3S cluster at home!

K3S Cluster in question, with 7 Pine64 SoPine modules

An easy way of installing apps on a K8S cluster is through Helm Charts. One command, more or less, and your app is up and running! It's an extremely practical way of doing things, borderline cheating. So of course, that's what I did!
I started off with a Helm Chart provisioned by Bitnami, a company which makes and shares Helm charts, as well as Docker containers. Setup was simple, which it should be.

Yet, there were errors. Firstly the MySQL database was missing a folder for startup scripts. I then "forked" the image, made the folder, then shared the image to the cluster. Problems didn't stop there, as then the MySQL database was yet again causing trouble as it could not open the file "mysql.ibd". Fed up with these errors, I went ahead and used the official MySQL server. If you wonder why I didn't start with that, it never occured to me, as Bitnami is a Verified Publisher on DockerHub, so I believed it was just a standard issue of some sort.

After swapping the image to the official MySQL one, the database was up and running! Yet, I could not access Ghost through the service created, which kept timing out. I therefore had to write my own service manifest file, except that it now had a different IP. As Ghost uses absolute addressing, all the links were broken. However, even after matching the IPs between Ghost and the service, the connection kept timing out...

At this point, I completely gave up with Bitnami's chart. I made my own manifest files for the MySQL server, and Ghost, as well as 2 persistent volume claims for storage of the database and Ghost's content. All in all, it took me 3 days to troubleshoot and attempt to fix Bitnami's mess, but half a day to make it from scratch. My deployment is still a bit unpolished, but I'll clean it up and maybe drop it on my Github!

I would say that this article is not slander to Bitnami, but that would be lying. I don't exactly understand why they are still around nor what they are supposed to accomplish other than wasting people's time. On the plus side though, I owe them thanks for making me learn a lot more about writing my own Kubernetes manifests!

Part 2

I hadn't expected to make a Part 2 to this, but it's just a short bit on making Ghost accessible to the internet. Starting off with buying the domain, then configuring the DNS entries. Afterwards, I setup DNS-o-Matic since my IP is dynamic, and it updates the DNS records whenever it changes. This runs as a pod on my Kubernetes cluster as well! Afterwards, I setup nginx reverse proxy on my OpenSUSE server (not part of the cluster) to handle the SSL certificates, which I afterwards generated using certbot (Let's Encrypt).

After a little more tweaking, my website was up and running on the internet! Just to clarify, Ghost comes with functionality to generate certs and setup nginx automatically for you. However, I was much more likely to break something by doing it manually, and you can't learn anything without breaking stuff first! [Flashbacks to me choosing Bitnami for supposedly giving the easy way of installing Ghost]

This was fun :D