Not-so-static blogging with blag, Nextcloud and systemd
I always wanted to write a blog, but I never really know what about to write. But most importantly, I never wanted to manage Wordpress or whatever on this machine.
I like the idea of static blogging, but yet, I like also to have a more friendly editor than a plain text editor.
During the years I created some stupid project that I worte about on my fediverse page under the title of “Departement of Unnecessary Projects”. Why don’t write about that on the blog?
And what’s better than a Unnecessary Project for the blog?
Stack
I’m already running Nextcloud on this same vps. I found myself sharing a quick “howto” via Nextcloud Notes. It was easy to write, easy to share and good looking.
So I thought: won’t be nice to have something which get markdown files from Notes and build a blog out of them?
Here is what I come up with:
- blag as static site generator
It’s the first thing came up searching for static site generators packaged in debian. It’s python (which is a plus) and is very simple. I know Pelican, but for a quick hack blag is more than enough.
Markdown with preview, each note in a .md
file, categories as folder on disk, upload an insert images and save while typing. I mean, what do you want more?
- systemd
For that added magic
- a web server
It’s a “web log” after all. Nginx here, but not so important. Everything was already configured, it’s just a subfolder in webroot
How things are connected
blag
reads content in markdown from folder /Notes/blog
of my Nextcloud account, directly from disk and write output to /var/www/html/blog
.
In Nextcloud I created two categories, blog
for live articles and pages, and blog-drafts
for things I’m still writting.
I like to keep things (almost) tidy, so I created /opt/blag
to put everything related to this thing.
First, I installed blag
# apt install blag
then, as per documentation:
# cd /opt/blag
# blag quickstart
This asked me some questions and created config.ini
file
I then created a bash script /opt/blag/build.sh
#!/bin/bash
set -e
HERE="$(dirname "$0")"
cd "$HERE"
rm -r /var/www/kirgroup.net/blog/*
blag build -i /path/to/nextcloud/fabrixxm/files/Notes/blog -o /var/www/html/blog/ || true
The script first cds into the folder, to allow blag to find its configuration, then cleanup output folder (it’s the fastest way to remove deleted pages/articles)
Now if I create a note in blog
category (with required metadata) and I run /opt/blag/build.sh
I get my blog.
But running build via ssh after editing is not what I want. So, let’s…
Automate the thing
Systemd can be configured to watch a folder or a file and start a service if something changes.
We need a path unit. So we now write /opt/blag/blag-rebuild.path
:
[Unit]
Description=Watch blog source for changes
[Path]
PathModified=/path/to/nextcloud/fabrixxm/files/Notes/blog
[Install]
WantedBy=multi-user.target
Now we need a service to run build.sh
.
If a .service
has the same name as the .path
unit, systemd knows what to do.
Here is /opt/blag/blag-rebuild.service
[Unit]
Description=Rebuild blog
After=network.target
[Service]
Type=oneshot
ExecStart=/opt/blag/build.sh
[Install]
RequiredBy=blag-rebuild.path
Eeasy-peasy.
Now we install the units and start the watching
# ln -s /opt/blag/blag-rebuild.service /etc/systemd/system
# ln -s /opt/blag/blag-rebuild.path /etc/systemd/system
# systemctl enable --now blag-rebuild.path
The attentive reader will have noticed that the blag build
command in the build.sh
script ends with || true
. That is because if build is triggered while we are editing something in Notes and it fails, the unit will be in ‘failed’ state and will not be triggered anymore. Could be this configured in the unit file? Maybe. It was faster just to swallow any error return value in the script. Output logs will be registered anyway by journald.
Conclusion
That’s it. Now I can write a Note and have it published in this blog. This is exactly how this post has been written:
I can also directly upload images!
Note
Some things weren’t so straight to set up:
blag
package in Debian 12 is a little old and doesn’t work correctly and doesn’t come with default theme templates and static files.
So I downloaded latest source code and run that instead.
I also copied out static files and templates into /opt/blag/static
and /opt/blag/templates
(as expected by the code) to fix some issues in templates (most of the links were absolute which is not good when your blog is in a subdirectory) and customize things around.
Sometimes Nextclouds saves the note too fast and the service unit fails with Failed with result 'start-limit-hit'.
. I need to find a fix for this.
I’m quite pleased with the results. Now I need to write more ๐
Update
2025-01-21 The build script has been updated
As someone noticed, the build script as it is will delete the blog before building it. But if the build fails, no more blog! Here is the updated version:
#!/bin/bash
set -e
SOURCE="/decrypted/nextclouddata/fabrixxm/files/Notes/blog"
DEST="/var/www/kirgroup.net/blog"
BUILDDIR="/tmp/blog"
HERE="$(dirname "$0")"
cd "$HERE"
rm -fr "$BUILDDIR"
if blag build -i "$SOURCE" -o "$BUILDDIR"
then
rm -fr "$DEST"
mv "$BUILDDIR" "$DEST"
fi
This will build the blog in a temp folder, and only if it builds successfully the blog folder is removed and replaced by the new version.