Migrating a Raspi setup to USB/SATA

My home IT infrastructure currently runs off a single trusty Raspberry Pi 4B - that’s around 30 containerized apps from DNS filter/proxy, Home Assistant et al for home automation, document management system, to printer proxy, vehicle data logger, and more. The Pi is an amazingly good fit for this purpose, especially since I’ve put it into the fantastic Argon One case for decent cooling, robustness and visual appeal. It’s been chugging away silently and reliably for some years now, but there were two things that nagged me: disk IO with the SD card is workable but far from snappy, plus the questionable long-term reliability of that SD card.

Turns out there is a solution for that! Argon has introduced a M.2 disk ‘shelf’ that simply replaces&extends the original Argon One case, and connects to one of the Raspi’s USB3 ports! (They probably introduced that quite some time ago, but I only now stumbled across it while trying to purchase their new Raspi-based NAS case. Enough with the product placement now, though!)

Phyiscal installation - boring

Ordered the M.2 shelf plus a matching M.2 SATA SSD drive a couple of days back, arrived yesterday. And because I cannot resist tinkering for long, I went ahead and put things together the same day. The physical side of the installation is completely boring, as expected: unscrew original case bottom, place M.2 disk in new shelf, screw back in place, connect USB plug - done. As might have become apparent in the intro, I like Argon 40 products - well designed, good fit, high quality build.

System migration

More interesting than the physical install was moving my entire system from the SD card over to the SSD. Well in actuality it was completely painless and only took 10 minutes - had I confidently known all the really necessary steps from the beginning :-) The issue I had was to figure out - from dozens of articles and blog posts, written over the course of the last 1-3 years - which steps were actually really necessary in my setup. Not very many, it turned out - but I definitely took a lot longer than 10 minutes to get there.

Context, prerequisites

Up front the context stuff: my Raspi is running 21.10 Ubuntu 64bit server edition. The Raspi’s bootloader was already updated to the latest version. I’m running some minor modifications to the boot/kernel-related things (see Deploy Deconz zigbee control software via docker), but nothing that has any impact on disk migration.

Raspi boot order

The Raspberry Pi 4B can boot from SD card or USB drive - and there is a bootloader option to tell it which to try first. Ultimately this is not really important other than maybe shaving of a little bit of time from your boot process - I set it to try USB first, like this (original source):

sudo rpi-eeprom-config

# Take note of the BOOT_ORDER code. The defualt code is 0xf41 and is read right to left to determine the boot order. 
# 1 = Check SD card
# 4 = Check USB drive
# f = Start again
# This boot order is exactly what we want. If the boot order code is anything other than 0xf41, you can change the boot configuration using this command. 
sudo -E rpi-eeprom-config --edit


Disk cloning

This part I expected to be the most daunting - but as usual, someone has been here before and hewn a path. With Bill Wilson’s rpi-clone script disk cloning is completely anticlimatic - again, especially once you know what you’re doing. In my case the relevant learnings include:

  • when cloning to an empty disk, the tool asks for a label for that disk (the big/root partition): if you plan to migrate to that disk, put writable as the label (more on that in the next section)
  • other than that, none of the more elaborate tool options are required - simply do sudo rpi-clone sda (sda being the device name of the disk to clone to)

There might have been a couple of questions asked during the process, but nothing surprising or difficult (otherwise I would have remembered).

Boot configuration

Now this is where the largest part of my research and trial went - entirely uncalled for in hindsight, as is normal. The key thing I wanted: boot from the new disk, mount all partitions from the new disk, do not use the SD card anymore. With the Ubuntu installation I’m using this is a complete no-brainer, as in:

  • boot config (/boot/firmware/cmdline.txt) and mount config (/etc/fstab) use disk labels
  • the identification label for the main (/) partition is writable, the firmare (/boot/firmware) partition label is system-boot

So the two corresponding partitions created on the cloned SATA disk by rpi-clone need to be labelled accordingly, and we’re done. The main partition is of type ext4, so to set the label/name to writable we use the e2label tool, like this: sudo e2label /dev/sda2 writable. (If you pay attention during the rpi-clone process for a fresh disk, you can directly assign that label then.)

The other partition (/dev/sda1) contains firmware and boot-related stuff, and for some reason is of type vfat. There exists a tool called mlabel (from the mtools) package. However, this utility is too much in line with Windows conventions, and only assigns uppercase-letter labels - so whatever you put in, the disk label ends up being SYSTEM-BOOT. The standard installation (/etc/fstab) is looking for a lowercase system-boot, however. So either modify the fstab entry to uppercase letters, or there is another little utility to the rescue: sudo fatlabel /dev/sda1 system-boot will do what we want and expect.

To get a nice list of the block devices in your system, and their fs-types, mountpoints and labels, you can use this command: sudo blkid -o list

That’s it, we’re done

And this is all - with those changes the raspberry boots entirely off the USB/SATA drive, the SD card is no longer needed! It can still be used though - for example as a fallback option. Because sudo rpi-clone mmcblk0 will now clone the contents of the main drive to the sd card, and thus provide an excellent, build-in safety net for disk failures.

Running on the M.2 disk makes the Raspi feel like a new machine - it feels an order of magnitude more responsive even in simple ssh sessions. For that alone the upgrade is worth it. Of course all the hosted applications benefit from the massive speed increase, especially disk-heavy solutions like docspell.

With regards to reliability there is a lot left to chance (I’ve never had disk problems in my life so far, no matter what technology) - the M.2 disk might fail tomorrow while the SD card soldiers on forever, or the other way around. However the chances should be a lot better with the M.2 version, and having the SD card still in the system as a backup option is a definitive upside.

Side note: while the Argon 40 hardware products are beautiful, their software tools (eg for case fan control) are on the ‘meh’ side (as in, not really working on my vanilla Ubuntu setup). And again someone has fixed that for us and provided a more robust, elegant solution - more than one person, actually. I am running argononed from DarkElvenAngel.


  • The gen4 Raspi is a very capable platform for running a bunch of home IT concerns - even with the modest 4GB version,
  • … but a USB/SATA disk upgrade massively boosts disk IO performance, and is worth it for that alone.