Software & Servers
Self-hosting and everyday tooling: a home NAS, Tailscale, git and the setups behind my devices.
2026
- Migrating from Pixel 7a to Pixel 11
Setting up a new phone always takes longer than it should, usually with at least one app or account causing grief along the way. This one didn’t, which felt almost suspicious.
- Running a Tailscale exit node in a local VM
I run Tailscale on my laptops, phone and NAS, and wanted to add an exit node so I could route traffic through my own connection when I’m out and about. The obvious place to put it was the NAS, since it’s already always on, but the NAS also holds everything I’d least like exposed if something went wrong. Making it double up as an exit node, with every device’s outbound traffic flowing through it, didn’t sit right. What I wanted instead was a disposable, isolated VM living on the same machine doing that job, leaving the NAS untouched.
- Merge Commits Are Just Noise
Run git log --graph on most team projects and you’ll see the problem. Parallel lines everywhere, merge commits that just say “Merge branch ‘feature/x’ into develop”. None of it useful. It’s noise. I’ve been using a rebase-based workflow for years to avoid this. The history stays linear and the diffs stay readable. This post covers both the argument and the specific branch structure I use for team feature work.
- Pulling Google Takeout straight to a NAS
I’ve been having a bit of a think about data I’ve left entirely in someone else’s hands. Specifically Google Photos, which has photos going back to 2011 and no local copy anywhere. I’m not going anywhere dramatic with it, but having a backup I actually control felt overdue.
- Building a Home NAS from Mostly Spare Parts
I’ve had a SNUNMU GK3 mini-PC kicking about since early-2023, barely used. An impulse buy that ended up on a shelf, alongside a drawer full of old drives from various machines and NAS attempts that never quite came together. Picking up a 5-bay USB enclosure finally gave me a reason to use all of it. It’s not polished and it’s not redundant, but it’s simple, flexible, and entirely under my control.
- Using split view in Chrome
Chrome’s split view tabs is one of those features that silently arrived and slipped into my workflow. I’ve found myself using it more and more over the past couple of weeks since it rolled out at the end of 2025. It’s as intuitive as tab grouping (hold shift when selecting multiple tabs), and genuinely useful. The kind of feature that slots in and makes me wonder how I managed without it.
2025
- Replacing the macOS audio switcher with SwiftBar
The built-in audio output menu in macOS has always felt a bit limited. The icons aren’t very helpful, the device names can’t be customised, and if you’ve got a few different outputs, it becomes tricky to quickly tell what’s what.
2022
- Using a Raspberry Pi to Host a local Visual Studio Code Server
I tend to work on this blog from multiple machines in my home. These include a desktop PC running Windows, a MacBook Pro running macOS, and a Chromebook with the Linux environment enabled. Across all of these machines I primarily use Visual Studio Code.
2018
- Some Notes About Android Virtual Devices
Running AVD emulator from the Windows command line/Powershell/mingw32 This assumes you’ve got Android Studio installed. First you need to have the tools path in your $PATH variable, to do this edit Path in Windows’ Environment variables to include for example: C:\Users\Max\AppData\Local\Android\Sdk\tools Then you can use emulator.exe from anywhere. The Android Studio docs fail to mention this. $ emulator -no-boot-anim -accel auto -writable-system -no-snapshot -gpu host -avd K10_API_22 Installing Google Play Services I’ve been messing around with older device profiles, and trying to run things in Chrome on Android 5.0 (API level 21). You’ll need to sideload the Google Play services system APKs (from a gapps package for your target system, e.g. for Android 5.0, but you might find that the /system partition is full. No problem, you can sideload to /sdcard and symlink: $ adb remount # Fails... $ adb push .\GmsCore.apk /system/priv-app $ adb: error: failed to copy '.\GmsCore.apk' to '/system/priv-app/GmsCore.apk': No space left on device # Works... $ adb push .\GmsCore.apk /sdcard/system/priv-app $ adb push .\GoogleLoginService.apk /sdcard/system/priv-app $ adb push .\GoogleServicesFramework.apk /sdcard/system/priv-app $ adb push .\Phonesky.apk /sdcard/system/priv-app # Symlink them $ adb shell ln -s /sdcard/system/priv-app/GmsCore.apk /system/priv-app/GmsCore.apk $ adb shell ln -s /sdcard/system/priv-app/GoogleLoginService.apk /system/priv-app/GoogleLoginService.apk $ adb shell ln -s /sdcard/system/priv-app/GoogleServicesFramework.apk /system/priv-app/GoogleServicesFramework.apk $ adb shell ln -s /sdcard/system/priv-app/Phonesky.apk /system/priv-app/Phonesky.apk $ adb shell stop $ adb shell start Messing around with /etc/hosts It’s trivial to edit the /etc/hosts on your AVD, but it only works if you have blank new line at the end of the hosts file. $ adb pull /etc/hosts hosts $ nano hosts # make your changes to the hosts file locally... $ adb push hosts /etc/hosts
2017
- VPN Connection Indication on Windows
As of tomorrow I’m going to be switching to working remotely. Same job, just from the comfort of my home office (and without 2-3 hours of commute daily!). With this change I figure I’ll have about 8-10 hours of extra time per week to work on things.
- Useful bash aliases for VPS
Some useful bash aliases that I use on my VPS’: www=/srv/www conf=/etc/apache2/sites-enabled alias ra='/etc/init.d/apache2 restart' alias ownit='chown -R www-data:www-data .' Create an Apache conf and directory for a new domain: function makeconf { primary=${1} conffile="${conf}/${primary}.conf" site_path="/srv/www/${primary}" mkdir -p ${site_path} echo "<VirtualHost *:80>" >> "${conffile}" echo " ServerName ${primary}" >> "${conffile}" echo " ServerAlias www.${primary}" >> "${conffile}" shift for i; do cat >> "${conffile}" <<EOL ServerAlias ${i} ServerAlias www.${i} EOL done echo " DocumentRoot ${site_path}" >> "${conffile}" echo "</VirtualHost>" >> "${conffile}" } Grab the latest Wordpress tar and extract it to the current directory: function wordpressitup { wget --no-check-certificate https://wordpress.org/latest.tar.gz tar xfz latest.tar.gz cd wordpress cp -R * .. cd .. rm -r wordpress echo "Wordpress installed" } Some shortcuts to go to common directories: function dwww { cd /srv/www } function dcache { cd /var/cache/mod_pagespeed/v2 } function dconf { cd /etc/apache2/sites-enabled/ } See which directories and files are using up all of the space: function fsizes { du -h --max-depth=1 | sort -hr df -BG }
2016
- Upgrading to El Capitan with an old installer
I upgrade my Macbook to El Capitan as soon as I could, and have had very few issues with the release. On my iMac at work though, I’ve been putting off the upgrade since last October – due to time constraints and not wanting to mess anything in my dev environment up. Today I tried to install El Capitan using the Install OS X El Capitan.app installer.
2015
- Getting Notified when a process is using 100% CPU on Mac OS X
Lately I’ve noticed node.js occasionally spawning a process that’s using 100% CPU. When this happens, the battery on my MacBook quickly drains.
- Maintaining updates for a bunch of WordPress sites with Google Spreadsheets
Here’s a useful trick I’ve come up with, to maintain a list of WordPress installations and easily see if they’re up to date.
2014
- Compressing PDF files from your Mac or Linux terminal with Ghostscript
I arrived at this solution recently when looking to compress a massive print-quality PDF for the web. If you search for “compressing pdf files on mac” you’ll get lots of bad results. There are lots of paid applications out there that claim to be able to do this, but they’re (obviously) not free.
2013
- Migrating from Outlook .pst to mbox and then uploading to an IMAP mail server
Microsoft Outlook uses a stupid/proprietary format to store mail locally. This is the burden I had to deal with recently while attempting to rescue mail from a friends dying computer.
- Adventures in IMAP: Migrating lots of mail to Atmail
Besides my day job as a front-end developer at 2degrees, I run my own web design company with my partner, called Marmalade & Jam. When launching Marmalade & Jam, I decided to go with 123-reg as I needed a quick way to get everything up and running, and at the time they seemed like a good deal.
- Making Postgres work nicely on OS X Mountain Lion
Postgres on OS X has been a pain in the ass for as long as I have had to use it. To start with, the version that comes with OS X is old, so I’ve always had to replace it with a better version.
- Awesome Bash arrays
Just some examples of how to do things with Bash arrays, and their analogous examples in Javascript.
- On second thought...
… Google Hangouts for Chrome needs some work.
- Converting SVG to PNG online and in your terminal
This post is mostly for my own benefit on the rare occasion that I have to convert SVG files to PNG. I always spend a large amount of time looking for an online SVG to PNG converter or a terminal one-liner to do this.
- Chrome 'Add to Trello' extension
I attended the third Refresh Oxford hack day yesterday, hosted at Incuna’s offices in Summertown.
- Removing the Blackberry Desktop Software for Mac without having to re-download a 70mb installer from Blackberry
If you happen to have installed the Blackberry Desktop Software and you want to remove it and it’s annoying persistant daemons, you might have discovered that this can only be done by downloading the 70mb installer dmg, and running the uninstaller.
- These tabs they are a changin'
The latest update to Chrome (25.0.1364.99) seems to have brought some slight tweaks the interface. The tab bar has seen some tweaks to the spacing of the close button, as well as the hover/active/inactive states of tabs, and the infamous blank ‘new tab’ button has been stretched a little. The inactive state of tabs and the ‘new tab’ button seems to blend in to the background a bit more too.
2012
- Installing MySQL on OS X Mountain Lion
I was having some issues getting MySQL installed on OS X 10.8 Mountain Lion, and then I came across a useful article describing how to do it.
- Getting to grips with git log
git is a powerful tool. After using it for the past couple of years I’m still finding new/powerful things that can be done with it.
- Dynamic location based desktop on your Mac with Satellite Eyes
I came across this awesome application today, it sets your wallpaper to a satellite view of your current location. The application features a number of rendering mode, and full support for multiple monitors.
- Dealing with crappy memory management in OS X
Using a lot of memory-intensive programs throughout the day, such as Virtualbox virtual machines, Photoshop and numerous browsers each with a couple of handfuls of tabs, you come to realise how bad the memory management in Mac OS X is.
- A possible solution to 'bad interpreter: operation not permitted' error on Mac OS X Lion
Out of the blue I started having an issue in my Terminal.app on Lion where downloaded scripts/applications wouldn’t run. I first noticed this when trying to setup the Android SDK.
- Updates to my 'install all firefox' bash script for Mac OS X
I wrote briefly about my install-all-firefox shell script back in December last year. Since then the script has received a complete rewrite, and some new features.
- Synchronising your Sublime Text 2 preferences with Dropbox
I use Sublime Text 2 both at work and at home, and it’s hard to manually keep my settings/packages in sync.
2011
- prev/next to left/right arrow key bind userscript
This is a userscript for Google Chrome (it might work with Firefox/Greasemonkey but I haven’t tested). It binds the left/right keys to click on prev/next links.
- Bash script to install all major versions of Firefox on OS X
I wrote a nice bash script that automatically downloads and installs the major versions of Firefox, sets up profiles for each and modifies the .app launchers so that they start with their designated profiles.
- Notched - indicate if Notch has replied to a topic on /r/minecraft comments
Another Chrome userscript for reddit.com This one is specifically for anybody wanting to know if Notch (the creator of Minecraft) has responded to the comment thread they are reading. Unable to recover the image :( This script adds a div to the top of the comments thread saying if Notch has replied, and then has a link to each comment. Grab it here: http://userscripts.org/scripts/show/110751
- Imgur Url Changer and pics/funny comment link subreddit remover aka reddit link stuff
I know, it sure is a catchy name! This is just a modification of my previous “Imgur to Filmot url changer” userscript for reddit.com
- Google Plus userstyle for Reddit
I created a userstyle for Reddit to make it look more like Google+ and other redesigned Google sites. To install you will need either Stylish or Stylebot for Google Chrome. I’ve only tested this in Google Chrome, and it’s far from complete, but for now it functions nicely enough on subreddit pages and comment threads. For the best experience, disable custom styles for subreddits.
- Reddit open imgur links in new window/tab
Derivative of the previous reddit/imgur userscript I wrote, this one simply makes all imgur links open in new window/tab (target="_blank") Download
- Reddit imgur to filmot url changer
Browsing Reddit while at work probably isn’t the best thing to do if trying to be productive, but sometimes it’s necessary to unwind periodically. Inside our intranet at work imgur is blocked, so browsing Reddit isn’t as enjoyable as it could be.. until now!
- Grooveshark view-modes userscript for Fluidapp/Chrome/GreaseMonkey
I’ve created a userscript to give the Grooveshark website some view modes. This is specifically for use with Fluid, but I imagine it would work okay with Chrome/etc too. More information about the userscript/setup after the break!
2010
- Using Greasemonkey scripts with Google Chrome
This isn’t new news, but it’s something I’ve found quite useful. You can use userscripts created for Firefox/Greasemonkey in Google Chrome. Many of the scripts that you can find over on userscripts.org can be used effortlessly by Google Chrome, and once installed can be disabled/uninstalled from the Extensions tab.
2006
- Pointless software
.. what the hell is the point in this songbird crap :| imagine if itunes and firefox made love, songbird is the demonspawn of that unfortunate circumstance. i’ll stick with foobar2000, thankyou very much. .. its only a preview release, but damn.. they need to work on the interface a bit, and perhaps “think different” even if that is hard enough to do, stealing the apple dream.
2004
- no, no! dont do that!
so, i’ve just reinstalled windows xp, and did a complete format of my hard drive.. it’s at time like this im glad i bought my creative zen xtra 30gb mp3 player, the mp3 player is so cool..
- For your convenience
re-installing windows xp is, to be blunt, a pain in the ass. on microsoft’s own back, there are so many flaws in the software that updating it with patches takes more time than I’m willing to allow myself to devote to..