How I Write and Publish my Blog

Alex McKenzie published on
6 min, 1009 words

I thought it would be useful to document how I publish my website, how I author content, and all the technologies I'm using. This is mostly for my own benefit, though it might serve as a nice reference in case anyone's ever wondering.

I believe I've arrived at a setup which has a few nice characteristics:

  • It has a nice balance between internal note-taking or sense-making, and external blog publishing. This is useful for blogs (like mine) which are often used as a means of enabling the author to think coherently and clearly.
  • Zero hosting costs
  • No vendor or tool lock-in
  • It's easy to read or write drafts at any stage of development
  • It's clean and simple (at least for me)

Here's how it all works:

  1. My blog posts start life as a markdown file in my Obsidian vault. Usually I intend to eventually publish them as a blog post, but they are deeply embedded in my Zettelkasten-ish network of notes
  2. When a blog post is approaching ready for primetime, I copy it to my website repo, which is a static site generated by Zola
  3. I edit the blog post to make it suitable for my public-facing website
  4. Finally, I publish a new version of my website using Netlify.

Both the notes and the website are git repos, hosted on Gitlab. The website repo is public (you can find it here), but the notes are private. My domain is registered with Namecheap, and I use Cloudflare for DNS, DDoS protection, and caching.

Writing Drafts as Notes

I'll start with my drafts, which live in my notes repository. This won't be for everyone, but for me it's handy to be able to link blog posts to other, private notes, deepening my understanding and helping me to set the blog post in the context of the rest of my notes.

Very broadly, I'm following the Zettelkasten method for note-taking, but very informally. As much as I love having lots of small, atomic notes corresponding to concepts, I also love being able to write longer notes which link richly to these concepts. Some of these longer notes are rambling and unstructured, written as I work through a problem or thought in real time.

Storing Notes in Obsidian

Obsidian stores my notes as plain markdown files, which makes it easy to use git for syncing my notes across different devices. For Windows and Mac, Obsidian's app has a neat plugin obsidian-git which makes git syncing almost seamless. On Android, this plugin doesn't work, which necessitates a slightly more complex solution. I broadly follow the approach of this great post, with some minor tweaks to the script:

#!/data/data/com.termux/files/usr/bin/env bash

cd /data/data/com.termux/files/home/storage/shared/documents/notes

git stash --include-untracked
git pull
git stash pop

CHANGES_EXIST="$(git status --porcelain | wc -l)"
if [ "$CHANGES_EXIST" -eq 0 ]; then
	exit 0
fi

git add .
git commit -q -m "Last Sync: $(date +"%Y-%m-%d %H:%M:%S") (Mobile)"
git push -q

This script is a little more robust to dirty repository states.

Copying from Notes to Blog

Although it involves some duplication, I really like copying the blog posts from my notes repo to my blog repo. I remove links to my internal notes, and add pictures. This provides a natural point at which to add polish to the post, and make it more self-contained.

Generating with Zola

Having tried Jekyll and Hugo, I like the simplicity of Zola. My needs are not complex, and Zola scales right down to a very simple folder structure. Zola is just a single binary, and I find the only commands I need are zola build and zola serve --drafts.

Using a static site generator decouples content authoring from content publishing. I've tried various CMSs, from Wordpress to headless CMSs such as Forestry and Netlify, and while I can appreciate the streamlined workflow for me there's just nothing like using whatever text editor I feel like and writing my own git commit messages (with however much or little information as I care to add).

In the future, I hope to figure out how to embed mini javascript apps, which I suspect is simple.

.
├── config.toml
├── content
│   ├── _index.md
│   └── posts
│       ├── _index.md
│       ├── ...
├── netlify.toml
├── static
│   ├── cv.pdf
│   ├── icons
│   │   ├── about.txt
│   │   ├── favicon.ico
│   │   └── <platform-specific favicons>
│   └── images
│       └── avatar.png
└── themes
    └── DeepThought <submodule>

The folder structure of my blog

Deploying with Netlify

Netlify is extremely simple to deploy static sites to, and (for a small website like mine) it's totally free. The config file is tiny; it would be enough to have as little as:

[build]
publish = "public"
command = "zola build"

[build.environment]
ZOLA_VERSION = "0.13.0"

Deploying is as simple as pushing to the main branch, then after about 2 minutes my website is freshly deployed.

Domain & Caching

Hosting my domain on Namecheap ensure I get privacy and a guaranteed low price.

On Cloudflare I've created a few (free) page rules, which provide me with:

  • HTTPS redirects
  • www subdomain redirects
  • Caching at the edge (since my website is fully static, I cache everything)

Cloudflare also provides some basic analytics, which is enough for me now.

One minor downside of caching using cloudflare is that I have to manually invalidate the cache, or else wait 4 hours (the cache TTL) before changes to my websites are fully reflected for all internet users.

Tool and Vendor Independence

Lastly, I want to talk briefly about how every component of my publishing workflow can be replaced with another tool or provider:

  • Instead of Zola, it would be trivial to re-organise the folder structure and use a different static site generator
  • Instead of Netlify, it would be easy to use any other Continuous Deployment provider, such as Gitlab CI or Github Actions
  • Instead of Namecheap, any other domain registrar could be used

Conclusion

I hope this has given you, the reader, some ideas for simple, effective blog publishing.