What the Sporks? How We Built a Reasonably Competent Blog

After being successfully up and running for over a year with very few major changes needed, now seems as good a time as ever to break down how sporks.space runs, what secret sauce we use to run it how we like it, and so forth.

The Blog Itself

The blog itself is, as we mention in the footer, proudly powered by WordPress. While there’s plenty of arguments that can be made for why a website should or should not use any specific CMS, during our initial setup we found WordPress to be a great solution due to:

  • Ease of editing. While most of the members of sporks.space are reasonably technical, and could be writing their posts in Markdown and dumping them into a git repository, not everyone is. Having a web-based WYSIWYG editor allows our less technical contributors to jump in easily, while the nerds in the group can get the hang of using WordPress with their preferred writing techniques pretty fast.
  • Flexibility for writing. Because of WordPress’ large range of plugins, we’re able to offer not just Gutenberg, the official WordPress block editor, but also the Classic Editor for contributors who prefer the old-school WordPress experience, and Iceberg for contributors who prefer a more “out of your face” editing experience, or who prefer editing with Markdown.
  • Built in comments. While other popular blog engines, like Ghost, support a fully WYSIWYG editor, it’s few and far between for these platforms to support comments. Ghost, for example, lets you embed an integration from a 3rd party service (e.g. Disqus) but does not support commenting natively. For sporks.space, we wanted readers to be able to comment on members’ posts, but we didn’t want to turn HackerNews/Lobsters/Reddit into our comments section, have to run additional services, or have to shell out commenting to a 3rd party. WordPress’ built-in commenting support is excellent, and with the addition of minimal anti-spam plugins, we’ve had an excellent experience with real comments going through and trash staying out.
  • Widely available existing tools. While many of the members of sporks.space are developers, some even focusing in web development, none of us really wanted to go out of our way to build the perfect blog engine from scratch. Stock WordPress is also not the perfect blog engine, but the engine’s flexibility and the existing network of tooling and plugins can, in my opinion, get it very close. The ability for a member to go “Hi I need $thing for a post, is there a way to get that?” and us adding it in minutes with essentially no time spent by us having to write/custom build $thing is great.

Below that, our WordPress instances runs using a PHP-FPM variant of the WordPress Docker image. This is proxied through an OpenResty instance with just a bit of tweaking for slight performance enhancements, improved SSL configurations, and so forth.

ssl_session_timeout 1d;
ssl_session_tickets off;

ssl_dhparam /etc/nginx/ssl/dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;

add_header Strict-Transport-Security "max-age=63072000" always;

ssl_stapling on;
ssl_stapling_verify on;

resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001]; # Cloudflare

How we’ve customized our SSL settings, copied almost entirely copied from Mozilla’s excellent SSL Configuration generator.

This SSL/TLS configuration also results in an A+ on SSL Labs!

Plugins, Themes, Etc.

For both speed and security purposes, we somewhat try to keep our plugin footprint small. That said, there’s a handful of plugins that are incredibly useful for keeping the blog running well and running how our members like it.

Authoring

Writing the Posts

Gutenberg is the de facto editor for WordPress these days; it’s a block-style editor, so think similar to a “Website builder” (e.g. Wix, SquareSpace, etc.) but compressed into “Make a blog post.” We run the development builds of Gutenberg, because I like to live a little on the edge.

Classic Editor is, well, the Classic Editor. While not a particularly useful plugin in general, supporting the classic WordPress editing environment makes some members pretty happy. 🙂

Iceberg Editor is a lovely take on an editor. It’s a Markdown/”terminal-ish” inspired editor that I find a joy to use. Especially for longer form content, where there’s less need for prim and polish and 30 Block Editor blocks and more need for just text, Iceberg’s customizable themes and ease on the eyes in general just make me, personally at least, enjoy writing.

Cleanup and Sharing

Enlighter Syntax Highlighter is a syntax highlighter. It’s fine. WordPress does not have syntax highlighting built in, and this solves the need fine.

Gallery & Image Block Lightbox is actually a new plugin added for this post. It allows embedded images in a post to open in full size in a lightbox, instead of just as a link to an image. Click on one of the images in this post to see it in action, it’s not particularly configurable but it does the one thing it does pretty well.

Public Post Preview does exactly what it says on the tin, but for a community like ours it’s super nice to have. Our group of contributors is made up of people who wanted a place to post for fun — this isn’t an office where we’ll only want one of our own members to look over a post. Without the functionality Public Post Preview gives, only logged in Editor-level users could look through someone else’s unpublished posts; enabling it lets our contributors write up their post, add a public preview, then send that preview link to anyone they want to.

Last on this part of the list is the tried and true SEO mallet, Yoast SEO. Frankly, we really don’t care too much about SEO — our blog is here because we want to talk, not always because we want people to listen. That said, it still gives the occasional nice suggestions, and functionality like on-post previews for how a post will look in Google, or being able to handle search engine verification through the WordPress admin panel is, well, neat.

Security

Akismet Spam Protection is great. With literally nothing else, Akismet has kept the spam problem every comment section/form/etc. has essentially nonexistent.

Sucuri Scanner is a minimal “security” plugin that essentially fits what I want from one. I’m pretty confident in the (comparatively) small attack surface on sporks.space and in the security of the system itself; as such, I don’t feel like a full app-level firewall (e.g. WordFence) is quite necessary. However, there’s definitely a bit of peace of mind that comes with at least having something monitoring the site to go “Huh that’s funky” if something unusual occurs. The Sucuri Scanner plugin’s file integrity checker (Are the WordPress files all still stock WordPress? Are there any weird files popping up in places where there shouldn’t be weird files?) and activity auditing (Did a new plugin get activated? Was a new user added?) cover that well enough for me.

Also on the topic of security, Two-Factor is another plugin we use which, well, does exactly what you’d think it does. This plugin adds 2FA to WordPress via TOTP or U2F. For whatever reason, this isn’t built into stock WordPress yet, so it’s a nice way to just cover that base.

Backend Bits

bunny.net is pretty convenient. While we don’t serve a ton of multimedia or static content, having a CDN which serves that content globally still speeds up loading a bit, and is another level of content offloaded to keep the site itself speedy and performant. The plugin itself allows clearing the cache from within WordPress and also handles automatically rewriting URLs to static content to pass through the CDN instead — something WordPress can’t do by itself.

Easy WP SMTP is another super convenient plugin, and one I use on almost every WordPress site I manage. Easy WP SMTP allows me to easily (through WordPress’ administrative dashboard) manage connection details to pass all outgoing email through a 3rd party vendor. Previously I’ve ran websites on hosting infrastructure where the IPs were pretty cursed — sending outgoing email directly from them was basically guaranteed to get your email marked as spam. While sporks.space is ran on Linode, who generally has good IP reputation, letting all of the headache involved with that be managed by a 3rd party is still nice, and Easy WP SMTP makes connecting WordPress to that a breeze.

There’s not a ton to say about IndexNow. It integrates with Bing and Yandex’s IndexNow platform to automatically submit new URLs to those engines. Maybe one day Google will support the IndexNow platform too, but ¯\_(ツ)_/¯

MainWP is, as the site’s administrator, one of my favorite tools. I run or maintain around 5-6 WordPress sites at any one time; not quite enough to be worth paying for a multi-site management solution, but enough that having one dashboard to go into to check site status, handle updates, etc. is very convenient. MainWP is another tool I load onto basically every WordPress site I touch — on the sporks.space side, we use the MainWP Child plugin and it’s essentially invisible, but on my admin side it gives me a great, convenient way of making sure sporks.space is running how I want it to.

Plausible Analytics is the official WordPress plugin from Plausible, our on-site analytics provider. We’ll talk a little more about how we use Plausible further down, but to talk about the plugin, it’s very convenient. It gives us the flexibility to hook Plausible’s analytics script into WordPress where we want it (e.g. obviously we’re going to be on the site when we’re writing, so having a button to exclude logged-in users helps to keep the stats clear) and generally stays out of the way once it’s set up.

UpdraftPlus handles our backups. We take a lot of backups — manual backups stored locally, daily full backups of the entire VPS through Linode and daily backups of WordPress itself (database, media, plugins/themes, etc.) stored off-site. For the last backup on that list, we use the UpdraftPlus plugin which allows for automatic daily backups to a number of different storage platforms; in our case, we use Linode’s Object Storage for these.

Theming

For a theme, we use Plane by Automattic. While hunting down a good theme was pretty difficult at first — so many are just painfully over-engineered — we settled on Plane as it looked nice and was readable while also, essentially, staying out of everyone’s way. It’s a nice theme that I recommend for blogs who just want a traditional blog, and want a theme that leaves content first and doesn’t care much about anything else.

Infrastructure

Being a blog and not some excessively complicated web platform, we have a pretty minimal list of infrastructure.

Currently sporks.space is run entirely off of a single 2GB Linode VPS and even when some of our most popular posts came out, bringing in thousands of readers in the scope of a few days, we’ve never seen an issue. We also use Linode for handling object storage, which is where we dump our daily website backups.

For email, we have two services. Migadu for personal emails (which we provide to our members; does anyone actually use their @sporks.space email? ¯\_(ツ)_/¯) and Mailgun for automatic emails (password resets, notifications, and so forth). Both services have been very reliable for us, and keep things smooth without making me need to use more of my few remaining brain cells than necessary.

As mentioned earlier, for analytics we use Plausible. They’re a small business offering their own open-source analytics platform as a service — less terrifying and data hungry than Google Analytics, but still gives us an easy way to see how many people decided to read our posts. It’s neat.

Lastly, as we also mentioned, we use Bunny.net as a CDN. While it’s a little superfluous, it’s a nice way to hopefully make the handful of more media-heavy posts load just a touch faster for folks. Plus bunnies are cute.

Leave a Reply

Your email address will not be published. Required fields are marked *