← Back to Home

Powering the Blog

2025-11-02

So what better way to introduce my new blog than describing how I built it, all the way from the code to the deployment.

The Code

The blog itself is an insanely simply Flask application consisting of two routes. The first of which being an index page which displays all available posts in descending order by date, and the second being the view for a given post. Any styling is done via Vanilla CSS, and the templating is done by Jinja.

So how do I load the posts? It's really simple! On startup of the application I read a given posts/ directory which has posts in YYYY_MM_DD_<TITLE>.md format, I extract the metadata I need, order them and then cache them in memory. When a user makes a request to the index it simply iterates over those posts and renders them, when a user makes a request to a specific post it does a simple linear search for the given post. No need to overcomplicate it at all!

The code is then pushed to my self-hosted Gitea instance. Of which I have also setup the Act runner which on push to main builds a docker image for my code.

Simple right! I've not lost you yet.

The Deployment

Now we have the Docker image, how do I actually run the blog? Well all I do is have a Docker compose file on my VPS which I can simply bring up and down with the relevant commands. My compose file simply binds the ports to localhost.

The next question is, given how we bind the ports to localhost only how are you reading this blog. The simple answer is Cloudflare Tunnel this gives a safe and secure ingress into my VPS, and provides certificates and a whole array of other Cloudflare services all for free.

Long story short: Docker compose + Cloudflare.

The VPS

So how much am I paying for the VPS? It's a measly €15 from Netcup, which I was blown away with. I get 8 vCPUs, 500GB of disk, 16GB of RAM for that? Fantastic deal. Any other providers are valid for this though!

Other Notes

There are some other minor components I used, I'll list them here:

Whats next?

For my current use case, this stack is perfectly fine. I don't mind restarting a service manually when a write a post once in a blue moon. There are some thoughts I have on what to do next though: