This, this I learned the hard way.
I have a number of Raspberry Pi devices around the house performing various functions, from retro game emulation to radio monitoring, but the one that sees the most use is the one running Domoticz – the home automation software. Like most of my Pi builds it runs on top of Raspbian Jessie Lite a Unix-like OS based on Debian and optimised for the Pi.
The logging for Domoticz and some of the associated home automation services can be pretty heavy. And SD cards really don’t like it when you write – and overwrite – lots of data. My first two builds of Domoticz were on 8GB SD Cards. Both survived about 90 days before suffering IO errors. Turns out that the volume of logs being written had beaten the wear-leveling on the card and it was struggling to write anything.
So, how do you run a Unix-like system on a Pi as a headless, long-term server, without periodically killing and replacing the card?
First: swap. Checking the memory usage showed that I didn’t need it. On Raspbian the easiest way to permanently disable swap is to remove the subsystem that supports it:
sudo apt-get remove dphys-swapfile
After a reboot, the system won’t try to write memory to the SD Card.
By default, every time a file is read a property is updated to indicate the last access date. We don’t are about this and since we want to reduce unnecessary writes, we can turn the behaviour off by adding the noatime flag to any mount point we wish to protect:
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
Helpfully, this is actually a default in the latest Raspbian builds.
Well, more storage actually. Part of my problem with the 8GB cards was that I didn’t have a lot of free space left. That makes life harder for the wear-levelling algorithm. Since the rebuild I’ve been using 32GB cards – and having over 75% of the space free means more spare blocks for the algorithm to work with. One source notes that doubling the size of the card can more than double the longevity.
Who needs logs?
Nuclear option: those logs? Don’t need ’em. I so very rarely need to refer to them that keeping around months worth of logs is counter productive. So for now I’m keeping them on a temporary filesystem in RAM. When the device reboots those logs are gone. In this case, using tmpfs to create a 50M partition and then putting /var/logs on it.
tmpfs /var/tmp tmpfs nodev,nosuid,size=50M 0 0
And in fstab:
none /var/log tmpfs size=50M,noatime 0 0
I’ve seen some advice around turning off journalling on the filesystem, but haven’t tried this yet. So far the other changes I’ve made have served me well.
One final thing: periodically, when I’m happy with how the system is running, I take the SD card out and use an imaging tool to create a backup image of the entire card. win32diskimager is a great tool for this on Windows – a guide to using it is here.