I’ve recently revived my Arch Linux desktop — I use Arch, btw — and moved to Hyprland. If you just want the TL;DR, jump to the commands below . For a more in-depth walkthrough, my previous post is still mostly relevant. Screenshots About the setup Theme-wise, it's Catppuccin all the way — I fell in love, and now it’s hard to imagine using anything else. Catppuccin is life. I also borrowed a few…
I can never remember how to do various things with gpg , despite using it for encryption and signing git commits. This post is my documentation. Subkey management (keeping secret key safe) I like to keep my master key in a safe place and away from my laptop. For daily operations, I use subkeys instead. 1. Generate a New Key (If You Don't Have One) gpg --full-generate-key Choose RSA and RSA and set…
I have a Linux NAS/Plex server at home that serves as storage for backups and all my media. It's a behemoth of a machine: 30TB, spread over 8 or so drives, and powered by a Ryzen 1600 CPU. It consumes power, which is unnecessary while I'm at work or sleeping. That's why I automate the process of hibernating and waking the machine on a timed schedule using systemd. I've been doing this for the last…
I like to repurpose keys I never use, such as caps lock, into additional modifier keys, often referred to as Hyper or MEH keys. On MacOS, you can achieve this using an app called Karabiner . However, recently, I acquired a QMK firmware keyboard with VIA support. This allows me to customise it directly on the board. In this article, I'll cover both methods. I've often thought that my keyboard usage…
I recently embarked on a dotfiles cleanup journey. Part of that was bringing my Neovim configuration up to date by eliminating unused key bindings and plugins while incorporating new ones. As a fun experiment, I tried to figure out when I switched to Neovim from Vim. It turns out it was 2018 , six years ago. I've only been tracking my dotfiles for 12 years, so I'm unsure when I transitioned to…
For years, I've used this alias in my gitconfig: [alias] work = ! "git config user.email 'rich@workdomain.tld'" Whenever starting a new work project, I would run git work to set a local gitconfig for the project, and it worked well. However, since I don't frequently clone repositories at work, I would forgot to run it. During a recent dotfiles cleanup, I wondered if there was a better way to…
A sleek, low-profile, wireless 60% mechanical keyboard with hot-swappable switches! Featuring QMK/VIA firmware support, rapid wireless functionality (2.4GHz 1000Hz), a robust build, and an enjoyable typing experience. It's an excellent board, with a couple of minor niggles. I have a strong affinity for 60% keyboards and own several, including the Vortex Poker 3 and Ducky One 2 Mini. My poor Ducky…
Ngrok allows you to expose your local development port from behind NAT to the internet. However, it has rate limits and is not free. If you already have a public server, why not just use SSH to remote port-forward? It turns out that is a popular solution , but there are some additions we can add. Let's stop Google from ever indexing us. Secondly, let's add an optional way to password protect the…
So, you have an Array that you need to make unique in Javascript? But how? Given the following items: items = [ 'item1' , 'item2' , 'item3' , 'item3' , 'item4' , 'item4' , 'item4' ] Using ES6, we can use the unique nature of Set . const newItems = [ ... new Set ( items ) ] // [ 'item1', 'item2', 'item3', 'item4' ] Set creates a unique mapping, which we convert to a new Array using the spread…
At work, we came across a performance issue on one of our pages. When adding a scope to an existing query, page load times would jump to 5+ seconds, but only in production. Here is an example app highlighting the problem. Can you spot the issue? The models: class Store < ApplicationRecord has_many :books has_many :customers scope :with_books_in_stock , - > { distinct . joins ( :books ) . merge (…
For some reason, I never thought to check until now. But caching wasn't working for any of the assets on this site. You have to turn on the setting within the Netlify config. It doesn't just assume you want to cache things—it makes sense. Luckily it's easy, create a file called netlify.toml in the project root: [ [ headers ] ] for = "/assets/*" [ headers.values ] Cache-Control = "public,…
ZeroTier (ZT) lets you create lightweight and easy to set up peer-to-peer VPNs. It allows internet-connected devices to appear as part of the same virtual network, providing an excellent solution for accessing your home securely from anywhere. ZT is an open source platform. You can, if you wish, run the entire thing self-hosted. However, as clients send traffic directly to each other, you only…
TL;DR It turns out lots of bookmarks for remote servers slows things down. My Konsole was slow to create new windows, taking 5-10 seconds. It didn't happen all the time but frustrating nonetheless. Debugging was unsuccessful. I removed all my ZSH configs, disabled KDE window overrides. But, nothing. No answers on Google. Eventually, I realised it only happens when my fileserver is offline, so I…
We had an interesting bug this week at work. A component would load without an issue, but the second you navigated away, it errored. It had a subtle bug. import React , { useEffect } from 'react' import Api form 'helpers/api' const Teacher = ( { id } ) => { useEffect ( ( ) => getTeacher ( ) , [ id ] ) const getTeacher = ( ) => Api . getWithPromise ( ` /api/teachers/ ${ id } ` ) . then ( ... ) ...…
Today I was using Git blame trying to work out who changed a line of code. I kept hitting a wall because the last commit was actually a mass code formatting commit. I thought to myself—there must be a way to skip these commits. It turns out there is! Git has an option --ignore-rev <rev> . From the documentation: Ignore changes made by the revision when assigning blame, as if the change never…
On Friday, I reserved a Steam Deck . And I'm super excited about it. On the 15th of July, Valve announced the Steam Deck . A handheld gaming "console", very much like the Nintendo Switch, but for PC games. Spec-wise, it boasts an AMD Zen 2 4c/8t CPU with an RDNA 2 GPU unit, 16GB of DDR5 RAM and a 7" 1280x800 screen. It comes in 3 variants, with the only difference being storage (64GB, 256GB and…
This post is about the Linux pipe viewer command, or pv . It's the second part of my beginners series on useful backup command-line tools for Linux. Part 1: Linux tar Part 2: Linux pv Pipe viewer is a tool for monitoring the progress of data between Linux pipes. It's a powerful little command. It becomes more powerful when you combine it with other useful backup commands. Let's start with a simple…
This is a beginners guide on how to compress and uncompress using Linux's tar command. Part of a useful utility belt of commands for backups on Linux. Part 1: Linux tar Part 2: Linux pv Tar allows you to archive files or directories into a single file—think of it like a bag you store items in—its useful if you want to maintain the ownership and permissions of the files you archive. Creating an…
The other day I needed to extract some files from a raw disk backup; problem is I never remember the commands and always have to look them up. For future reference here is how to do it. Once you have the raw disk image create a loop device from it: sudo losetup -f -P rawdisk.img You should now have a loop device with all the partitions from the original raw disk: sudo lsblk -f .. . NAME FSTYPE…
👋 A 2025 Update While a lot of this guide is still relevant (I reference it from time to time), there are a few things I do differently now. I'm now a tiling window person (Hyprland), which means I use a few different tools / configurations. Rather than churn out the same post again, I've decided to create a TL;DR version for my new setup. My 2025 Hyprland Archlinux I've been a Linux user since…
Part two in a series of posts detailing the services we use at work . This post covers how we handle errors in our application. Part one covered continuous integration . Errors? Error handling is very important for any application; you want to know when things break right? Traditionally applications have used log files or emails, however, monitoring a log file is cumbersome and suddenly getting…
This post covers continuous integration for Rails and is part one of a series of posts that detail the services my team uses at work . Continuous integration Writing software is error prone and riddled with problems. This is often amplified when working in larger teams as you try to integrate each other's code. Continuous integration, or CI for short, is a development practice whereby team members…
Due to the recent OpenSSL issues ( Heartbleed ) I've been rekeying my SSL certificates and as part of that I've needed to update the Subsonic key. I never remember the steps for this, luckily they were still in my ZSH history. To save myself in future and to help others I've written the process down. Prerequisites You need to make sure openSSL is installed (and the latest patched version), you…
It's always a good idea to backup your data; it gives you protection from data loss and hardware failure. If you host sensitive data, or applications for customers, it's a good idea to encrypt the backups, ensuring their secure and can be safely kept just about anywhere. There are lots of backup scripts, solutions and services around: Rsync , s3sync , Rdiff-backup , Jungle Disk and Duplicity being…
I've written a simple backup script in Ruby that utilises Rsync I've made it public so feel free to fork, change and contribute! The backups are structured as such: /remote/location/current - The current folder contains the the latest clone of the intended backup folder. /remote/location/backup_dir - The backup directory, which by default is the current day (monday, tuesday, etc) contains the…
So the other day I decided to switch from using Apache to Nginx not because apache isn't any good, far from it. Nginx just uses much less ram and when you're on a fairly small slice, using up more ram just isn't good. I was going to benchmark speed and things between apache and nginx but I forgot to take some readings before stopping the apache service and installing nginx so we'll skip over that…
I went to integrate Syntaxhighlighter into the site tonight, something I'd forgotten to do in the redesign and I thought it would be nice if I could just click a button in tinymce and paste in the code, select a few options and click insert. Which of course is entirely possible so I've written a tinymce plugin to do just that. I did encounter one little bug writing the plugin. When inserting the…