Raspberry Pi with read-only file system
Raspbian Buster Lite edition
Here are some very basic steps to make a Raspbian Lite installation read-only (stateless, volatile). This saves write cycles on the SD card and allows the Raspberry Pi to be powered off without shutdown.
Prepare the system
This guide is based on a fresh Raspbian Buster Lite (tested on version June 2019) installation.
Disable swap file
While disabling swapping is not a good idea in general, in a read-only environment there is no writable device for swapping.
dphys-swapfile swapoff dphys-swapfile uninstall systemctl disable dphys-swapfile.service
Remove unwanted packages
Log files are going to be stored on a temporary file system, so they do not need to be rotated.
fake-hwclock tries to store the time in a file, which is undesirable in this case.
apt-get remove -y --purge logrotate fake-hwclock
Disable apt activities
Disable automatic upgrades and manpage cache creation.
systemctl disable apt-daily-upgrade.timer systemctl disable apt-daily.timer systemctl disable man-db.timer
Move resolv.conf to /run
resolv.conf is the only file in
/etc that needs to be modified (assuming DHCP is used for nameserver discovery). It needs to be moved to a location that is writable (
/run is a
tmpfs) and readable by other processes (
/tmp is not a good location because it may be masked for some services using
PrivateTmp by systemd).
mv /etc/resolv.conf /run/resolvconf/resolv.conf ln -s /run/resolvconf/resolv.conf /etc/resolv.conf
Enable tmpfs /tmp and /var/tmp
These directories need to be writable, with specific permissions.
/var will be
tmpfs anyway, so only the permissions need to be adjusted.
/tmp the systemd supplied mount unit can be enabled.
echo -e "D /tmp 1777 root root -\nq /var/tmp 1777 root root -" > /etc/tmpfiles.d/tmp.conf cp /usr/share/systemd/tmp.mount /etc/systemd/system/ systemctl enable tmp.mount
Clean up /var
These files are not needed anymore, so before mounting the temporary file system
/var can be cleaned up to save some space on the SD card.
rm -rf /var/cache/apt /var/cache/debconf /var/lib/apt/lists
Enable read-only mode
Adjust kernel command line
Add this to the kernel command line (
fsck on boot and swap are disabled, the root file system is mounted read-only, and
systemd.volatile enables a temporary
/var mounted on top of the read-only root.
fsck.mode=skip noswap ro systemd.volatile=state
Edit the file system table
ro option to the file systems in
sed -i -e 's/vfat\s*defaults\s/vfat defaults,ro/' /etc/fstab sed -i -e 's/ext4\s*defaults,noatime\s/ext4 defaults,noatime,ro/' /etc/fstab
Disable read-only mode
Reverse the modifications in
/etc/fstab from the above steps and reboot.
This is not easy to reverse. Install and configure packages and services before executing these steps.
/varis volatile, there is no way of making the system read-write without a reboot. It might be possible to only mount some of
tmpfs, but services in general assume
/varto be writable, so this has to be done with extra care.
/varwill be empty on reboot. Services that need some kind of state from
/varneed to be reconfigured to get it from somewhere else. APT will not work, as the package database is also affected by this.
Time is received using NTP via
systemd-timesyncdon reboot. Until the correct time is received, a (very) wrong time is used, e.g. in the boot log.
systemd 242 (not provided in Raspbian Buster) will feature a more capable
systemd.volatile=overlaysetting that automatically mounts
overlayfs. This improves compatibility with services that are not aware of read-only file systems, but also has to be used carefully (e.g. writing lots of data to the in-memory
overlayfsquickly consumes all memory).
tmpfsis possible, however needs some additional work on boot in order to create the
overlayfs. This adds little benefit and would be obsolete once systemd 242 hits Raspbian.