DEV Community

x-t
x-t

Posted on • Originally published at blog.zxyz.gay on

Hosting a guestbook, how hard can it be?

Ah, the good old internet. Geocities, GIFs, banners, view counters and one of my favorite things - guestbooks. Things that undeniably, died out. And no real wonder, the barrier to overcome for web development has gotten higher, the amount of people on the web increased by several orders of magnitude, many introduced in the late 2000s with touchscreen devices that couldn't be used for any kind of development. Social media took the place to provide a polished, easy experience for anyone's internet presence, without having to worry about code, hosting, scaling, design, accessibility or anything else.

The design of social media doesn't allow these old tropes to exist. Geocities was made for the older internet, failing to scale to the new one for billions more users. GIFs couldn't be plastered anywhere anymore, as they looked terrible, companies got good at design and not triggering epileptic seizures from anyone daring enough to double-click the Internet Explorer icon. View counters don't make sense anymore, while analytics for pages exist, it is unquestionably inflated by the fact that clicking a profile is easier than finding a page. And guestbooks, well, have been replaced with just posts. Twitter, Facebook, Reddit and everything else is structured into posts and replies. A guestbook in a Twitter profile would really just be a simple reply.

But the beautiful thing about being a web developer is you can make whatever you want. And while guestbooks nowadays are more popular in just coding demos, there are groups of people that specifically want to bring back the old web. And you could say, I'm in one of them. I made a guestbook afterall.

It's actually pretty simple

A guestbook is a really primitive form of user interactivity.

Graph: A form that allows anyone to post in your database ↔️ Database with all your posts

It's definitely simpler than a comment section, it's just some logic and a database. And for the old web, as well as my old website, it worked pretty well.

A screenshot of the 2018 guestbook.

This is the first generation of the guestbook from 2018. The amazing front-end design aside, the structure was rather simple.

Graph: DigitalOcean (at the top), MySQL ↔️ PHP

This is what nowadays we'd call server-side rendering. A single DigitalOcean VPS, running Debian with a MySQL process and a PHP-FPM server running on Nginx. The source code is as simple as the infrastructure. (Source code uses JSON files instead of a MySQL database, the actual code used on the server was in private git repositories and lost to time.)

comments);
foreach ($arr_cmts as $comment) {
    echo "[" . $comment->time . "] " . htmlspecialchars($comment->name) . ": " . htmlspecialchars($comment->data) . "\n";
}
?>
Enter fullscreen mode Exit fullscreen mode

The fact that it was a full server meant that I had quite little to worry about the usage of the database and PHP. Things like compute and bandwidth costs wouldn't need to be accounted for, it's just a flat $5/mo for the virtual machine and some usage quota, that's it.

As there was barely any traffic, the server was also used for a multitude of other things, like a Quake 3 server, my friend's website, an analytics engine that tracked essentially nothing but search engine bots, it was quite a lot to learn.

When money strikes

But all good things must come to an end, and this DigitalOcean VPS was one of those. I had a $50 credit from the GitHub Student Developer Pack, which ended in less than a year. And I wasn't gonna start paying that much for a server that wasn't actually used a whole lot for anything else than learning, so for the lack of any users for the site, I nuked it. Moved the site to GitHub Pages. For more about the actual move, you can read the blog post from 2018.

Jamstack

Nowadays it's easier to get a back-end site host for free. Vercel has many Javascript server-side frameworks supported, all with the help of AWS Lambda. And if you're still thinking of learning LAMP, the shady market of things like Infinityfree will get you a full LAMP stack for free, with some limits.

However, a few years back, I decided to go with GitHub Pages, as the backend offerings I wasn't that interested in and I could get a free github.io subdomain, plus it would be hosted straight from a GitHub repo, without the need of a website like Neocities. This meant that I embarked on the Jamstack journey, even if I didn't know what it meant back then. And while Jamstack has many advantages, such as speed, any server content becomes exponentially more difficult. Thus the guestbook was abandoned for quite a couple of years before trying again.

A redesign that prompted new ideas

In 2021, I totally redesigned my site from the ground up using the styling of the very old internet, aided with Claris Home Page.

The homepage of the Claris Home Page-designed website.

This meant that I could redo with the old internet tropes. Serif fonts, banners, GIFs, bad HTML and something that I knew I'd be able to do now - a guestbook.

Of course, I would not move the site out of GitHub Pages, which meant that I was stuck on Jamstack and couldn't just plop it back in with the same PHP code, so, ideas had to be made.

Welcome to Azure

Graph: Azure Cosmos DB ↔️ Azure Functions ↔️ GitHub Pages

The way the Jamstack infrastructure works is it consists of 3 layers:

  • The database, to hold all guestbook posts
  • The API layer, to allow safe insertions/retrievals of guestbook data
  • The frontend, to render all the guestbook data

The database was held up by Azure Cosmos DB, a free MongoDB/SQL-compatible database, I used MongoDB for it, which worked pretty well. However, it was really slow, unsure why.

The API layer was a Go serverless application written primarily by me, running on the Azure Functions serverless runtime on Windows.

For the front-end, a new HTML file was created, which would download the JSON from the API and display all posts, with some clever local caching strategy to cut down on the amount of API requests sent by every visitor. Also, since it's Jamstack, it used a client-side form, since there was no real backend server to just hand off the form to.

It was slow

A fetch would be fast if it took 7 seconds, more often than not it'd be a cold start which would take anywhere from 12 to 30 seconds to actually see the content. It was completely free, so I didn't complain that much.

Google Cloud - old friends return

Graph: (Group: Google Cloud Compute Engine, Go (golang), PostgreSQL) ↔️GitHub Pages

I decided to take out the free trial of Google Cloud, and instead of doing something useful with its' offerings, I just spun up a Compute Engine VM with RHEL. While the guestbook Go code was made to work on serverless and MongoDB, I migrated it over to Postgres and ran it as a systemd socket. The frontend stayed on GitHub Pages, so while the backend structure almost looked similar to the one before, it wasn't the same. Still, this showed me how it'd be great to not have vendor lock-in for your projects.

The fact that it was written in Go and not in JavaScript with a weird Azure library meant that I was able to just run the same code without a rewrite. In fact, if I had hosted a MongoDB database instead of Postgres, it'd be a drop-in replacement.

But the credits, just like on DigitalOcean, would end, and I'd return back to the Azure solution.

Free tiers galore

Graph: GitHub Pages ↔️ (Fly.io ➡️ Supabase) Graph: GitHub Pages ↔️ (Fly.io ➡️ Nhost)

The beautiful thing about startups is the venture capital investments. This means less money they need to stay afloat from the users, which ends in some truly spectacular free tiers. I ended up splitting the infrastructure in two, one way for fetching and another for making posts.

For the fetching, I first used Supabase, which is a Firebase alternative, but then I ended up with the problem that 7 days of inactivity would just freeze the database, so I migrated to Nhost, which provides a free Postgres database backed by Hasura.

For the posting, I needed some custom logic, such as an hCaptcha checker, so that was replaced with a client-side form and a Fly container.

This sped things up significantly. Not as fast as the GCP solution, but still significantly faster. At this point I also migrated from the Go project to a Typescript/Express stack inside a monorepo, which would be much easier to maintain than the aging Go code.

But, startups aren't perfect

Nhost, while working perfectly fine, had a major flaw when I was migrating the site from a really awful vanilla JS frontend to the Alpine framework. The uptime.

I'm unsure if they were just freezing the containers like a serverless cold start or the servers just keep going down, several times I wouldn't be able to fetch any messages. Sometimes it'd return with a "Service temporarily down", other times it'd just hold the HTTP connection and provide the guestbook JSON 5 minutes later. Considering I don't monitor the uptime, and it was happening constantly while I was just developing the site, I just took a random guess that when I'm not developing on it, the database would be down just as much, so I decided to migrate.

Good timing

Graph: Fly.io ↔️ GitHub Pages

Just as I was trying to find suitable alternatives to host the guestbook on, Fly announced that they'd be making 3 GB of volume data free, thus meaning that running a PostgreSQL database for free was now possible.

Both the database and the backend API now run on Fly, both cost $0, are always-on, have significantly better uptime than Nhost and are crazy fast. With a simple hack like:

allows the frontend to fetch the guestbook as it is loading the Javascript to render it at the same time. It's faster than anything before, and even when all of the above solutions cost $0, this one might be the cheapest as you get the most.

While it is lacking in resources (128MB RAM, 1GB disk), you get 100GB+ of free bandwidth, a full unrestricted VM (not just an user) with Postgres, so while it is a little more effort to administrate, it's actually more powerful than Nhost or even Supabase.

Conclusion

However simple a guestbook is in schema, in the modern age of the web it is actually quite some effort to host. And mind you, I am not even doing things properly. It's just two VMs in Europe - one with the Express server, another with Postgres. There's no high-availability, no edge, nothing fancy. These things cost money, and I want the guestbook to stay free. And through many design iterations, I found Fly to have the best solution for hosting a Jamstack guestbook in terms of free allowance, speed and control.

A simple Twitter profile looks like a way simpler investment now, doesn't it?

Top comments (0)