This website
Before I move on with writing more of what I planned, I need to write a few things down about how this website came to be.
A long time ago I used GitHub Actions for my blog. I didn't quite like because of how slow the feedback loop was: I had to wait sometimes 30+ seconds in order to see an update I pushed show up on a live website. 30 seconds is... well, it's too just slow for my taste. I decided my next website will on a hardware I own or, at the very least - rent :)
Today this website runs on:
-
a cpx11 machine type on Hetzner, with a monthly cost equivalent in price to roughly a single cup of coffee in Switzerland,
-
a NixOS 25.05,
-
Caddy 2.10 reverse proxy compiled with two modules, dynamicdns and dns.providers.cloudflare,
Declaratively compiling and installing caddy with select modules in NixOS became quite straightforward since November 2024 when this nixpkgs PR was merged.
My caddy configuration looks like this:
Caddyfile
(common-logging) {log {output file /var/log/caddy/access.log {mode 644roll_size 10MiBroll_keep 5roll_keep_for 90d}}}{dynamic_dns {provider cloudflare {env.CLOUDFLARE_API_TOKEN}domains {gmile.meievgenpyrogov.com}}}gmile.me {import common-loggingredir https://ievgenpyrogov.com}ievgenpyrogov.com {import common-loggingtls {dns cloudflare {env.CLOUDFLARE_API_TOKEN}}root * /var/lib/www/ievgenpyrogov.comfile_server} -
a bunch of good old static HTML and CSS produced by tableau, a static website generator written in Elixir.
Initial I was tempted to just use a plain HTML / CSS without any "site generation" step. However, I quickly learned there are a few things I am missing, such as to be able to write markdown (since writing articles in plain HTML gets old fast) and code highlighting.
For markdown rendering, tableau uses a state-of-the-art Elixir library called mdex, which in turn uses a library called autumnus for code highlighting. Kudos to Leandro Pereira for making both libs happen! Leandro kindly responded to my request about code highlighting for caddy and fish-shell syntaxes by adding support for it, so both code blocks in this post look beautifully colorized.
I am using goaccess to visualize HTTP access logs. I don't need anything sophisticated yet, so today I check the logs via this simple script:
show-access-logs.fish
#!/usr/bin/env fish
set access_log (mktemp)
echo $access_log
scp 128.135.95.176:/var/log/caddy/access.log $access_log
goaccess $access_log --log-format caddy
I might need to run goaccess as a NixOS service one day.
Fun fact: a little over 24h after configuring access logs in Caddy, the website was visited 6841 times from 115 unique visitors. Bots, of course. Someone wrote about this recently.
Might need to look into integrating fail2ban, anubis or the like into Caddy.
Finally, deploying this website is as simple as running the following two commands:
env MIX_ENV=prod mix tableau.build
rsync --archive --verbose --delete /Users/eugene/projects/website/output/ 128.135.95.176:/var/lib/www/ievgenpyrogov.com/
This way I can store the website's sources in a folder on my laptop, and make an update live in just a couple of seconds. This is a welcome improvement over "deploying" website using a GitHub Actions workflow and enables me want to make many small updates frequently.