Today I embarked on migrating my old HTML website to Hugo, encountering various challenges and learning valuable lessons about static site generation.
AppImages and GNOME desktop launchers
AppImages are how a lot of apps are distributed on Linux these days but there isn’t an established “install this AppImage so I can launch it” pattern.
Install this AppImage so I can launch it (GNOME edition)
- Download your favourite AppImage from a trusted publisher
- Move the file to
/opt/<my app>/<app>.AppImage
- Make the AppImage executable
chmod +x /opt/<my app>/<app>.AppImage
- Download an icon for your app, or extract the app icon from the AppImage
and put it in
/opt/<my app>/<app>.png
- Create a GNOME Desktop Launcher file in
~/.local/share/applications
[Desktop Entry] Name=My App Comment=A Description Exec=/opt/<my app>/<app>.AppImage --no-sandbox Icon=/opt/<my app>/<app>.png Terminal=false Type=Application Categories=Utility;
- Update GNOME’s desktop file entries:
sudo update-desktop-database
- Open your app
Continued; filtering Drupal comment spam using an LLM
A continuation of my previous post on Filtering Drupal comments for spam
Overview
- Old Drupal 5 blog with my old posts stuck in the Drupal
node
table - ~19k comments on my pages before I fixed spam filtering
- Keeping it local with Ollama
- Google Gemma3 was a good speed/quality for detecting spam
- Deepseek R1 takes way too long because it reasons for every comment
TLDR:
- I excluded a lot of spam comments with Gemma3 and boiled them down to a more manageable set
- Automating this process means I could easily miss comments due to false-positives
- Need to log the Drupal node ID so that I can link filtered comments back to my markdown blog posts
Certbot Renewal with Docker
A hacky way to get it done
docker-compose.yml
certbot:
image: certbot/certbot:latest
depends_on:
- nginx
command: >-
renew -v --webroot --webroot-path=/var/www/certbot --agree-tos --email "my-email"
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
Run:
docker compose up certbot
Filtering ancient Drupal comments for spam using an LLM
I have been meaning to resurrect my blog for a long time. I’ve written many versions of this post, whether on dev.to, wordpress.org, Obsidian Publish, etc. etc. etc. I have spent hundreds of dollars on the question “how do blog?!” and I’m back to “Pay $5/mo for a VPS, put HTML files on the internet.”
I have an old Drupal 5 blog from ~2014 which I migrated my ~2010 Drupal 4 blog posts from. I really liked the 2014 era content from when I first started experimenting with software defined radio and had some moderately well-commented posts on GQRX SDR and Linux gaming at the time.
Google Play Music & Gnome Shell Media Buttons
I have been trying to figure out how to use the media keys on my keyboard to control Google Play Music for a while. It turns out that Chrome is set up to listen for the media keys, but the X11/Gnome were capturing these events and not propagating them to the browser.
TLDR: Disable the Play/Pause, Next, and Previous keyboard shortcuts in the Gnome Keyboard controls.
Let’s Encrypt!
I’ve finally completed my goal of securing https://marcinkowski.ca and https://analytics.marcinkowski.ca using Let’s Encrypt. The process is easier than setting up the pretty URL rules for Drupal in nginx.
I followed Digital Ocean’s setup instructions found here: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-14-04
Setting up certificate renewals
See my next article about setting up automatic certificate renewals:
TLDR:
Prerequisites:
- Your user needs to have write access to your webroot
- I have installed
certbot-auto
in to/opt/certbot
- Get
certbot
from the EFF (https://certbot.eff.org/) - Configure nginx to allow access to
http(s)://domain.com/.well-known/*
:/etc/nginx/letsencrypt-authorization.conf: location ~ /.well-known { allow all; } /etc/nginx/enabled/domain.ca: include letsencrypt-authorization.conf
- Create a cert using
certbot-auto
script:/opt/certbot/certbot-auto certonly -a webroot --webroot-path=PATH/TO/WEBROOT -d domain.ca
- Add my new letsencrypt certificate and private key to the config file for this domain:
ssl_certificate /etc/letsencrypt/live/domain.ca/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/domain.ca/privkey.pem;
- Followed the rest of the Digital Ocean article:
a. Generate a Strong Diffie-Hellman Group:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
b. Add additional SSL params to use modern practises, including HSTS (Thanks Digital Ocean) ~~~
Let’s Encrypt Renewal
In my last article I TLDR’d how I got Let’s Encrypt set up for https://marcinkowski.ca and https://analytics.marcinkowski.ca.
Getting automatic renewals set up using certbot
is pretty straightforward. I collected the following from a couple of places, including the github:certbot/docs/using.rst#Renewal
Add a twice daily cron
entry for certbot
to check for renewals:
30 6/18 * * * /opt/certbot/certbot-auto -q renew --post-hook "service nginx reload"
The --post-hook "service nginx reload"
will reload Nginx’s config only if a certificate renewal is performed. You can check on this by adding -v
to the call to /opt/certbot/certbot-auto
and see the logging output stating that no renewals were attempted.
Captive portals and iOS CNA
And maybe Windows Phone CNA as well
Turning Drupal into a static site using HTTrack
I am currently running three blogs on one of my Linodes. This blog, one for my cousin Stef Marcinkowski and one for my brother Erik Marcinkowski.
Stef and I have made the decision to move to a simpler static portfolio site to showcase his incredible graphic design skills; something which I felt Drupal was getting in the way of. Drupal makes a lot of things unnecessarily difficult, and our new vision for Stef’s site is far less focused on blog entries and articles.