Read Only Raspbian

Sometimes you need a raspberry pi to be hardened against unclean shutdowns, or pulling the SD card out, or you're just sick of the card getting corrupted. These are instructions for ruggedising your raspbian image so it's far lass likely to get messed up. Derived mostly from

Install raspbian

Install Raspbian to an SD card as per the instructions, either the regular or lite image, then boot and log into your pi.

These instructions were written for debian jessie.


Expand the Filesystem


We will create a new partition layout with the existing /boot, a slightly bigger / (root), and a new /var to hold any files that need to be writable.


sudo fdisk /dev/mmcblk0

type p and hit return, write down the Start of /dev/mmcblk0p2:

Command (m for help): p
Disk /dev/mmcblk0: 7.5 GiB, 8068792320 bytes, 15759360 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x6f92008e

Device         Boot   Start      End Sectors  Size Id Type
/dev/mmcblk0p1         8192   131071  122880   60M  c W95 FAT32 (LBA)
/dev/mmcblk0p2       131072  13019679 13150751 1.3G 83 Linux

Delete partition 2 (yea, really) by typing these letters (remember to press enter after each one).


Now make a new partition 2 in the same starting location but bigger, replace <these sections> with the correct number:

<The exact number from Start before (131072 for me)>
+<Half the size of your SD card (eg '4' for an 8GB card)>G

Now print the table again with p and write down the End of /dev/mmcblk0p2

Now make a new partition 3 in the rest of the space:

<The End of partition 2, PLUS ONE>
<just press return to let it use the rest of the SD card>

Now if that all went well type w and press enter to save the new partition table. Otherwise press q to forget everything you just did and try again.

Expand the root filesystem in partition 2

sudo partprobe
sudo resize2fs /dev/mmcblk0p2

Make the new filesystem in partition 3

sudo mke2fs -t ext4 /dev/mmcblk0p3

Mount the new filesystem and move things into it

sudo mount /dev/mmcblk0p3 /mnt/

Copy the content of /var into it

sudo cp -rp /var/* /mnt/

Make a new place to keep /srv

sudo mkdir -p /mnt/local/srv

Copy home into the new location.

sudo cp -rp /home /mnt/local/

There are now some special files in /etc that programs want to write, we solve these as so..

Link mtab to dynamic copy

sudo rm /etc/mtab
sudo ln -s /proc/self/mounts /etc/mtab

Link resolv.conf to a writable location

sudo apt-get install resolvconf
sudo mv /etc/resolv.conf /mnt/local/resolv.conf
sudo ln -s /var/local/resolv.conf /etc/resolv.conf

Remove /etc/network/run and reconfigure ifupdown

sudo rm /etc/network/run
sudo dpkg-reconfigure ifupdown

Modify fstab

Now we modify the filesystem table.

use your favourite text editor to open /etc/fstab and make it look like this:

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults,ro          0       2  # added 'ro' to /boot options
/dev/mmcblk0p2  /               ext4    defaults,noatime,ro  0       1  # added 'ro' to / options
# a swapfile is not a swap partition, no line here  # You probably don't want swap if you're looking to ruggedise your pi, if you want one, use a swap file at /var/swap
#   use  dphys-swapfile swap[on|off]  for that
tmpfs		/tmp		tmpfs	nodev,nosuid,size=100M	0	0  # /tmp is a RAMdisk, here we dedicate 100MB of our RAM to /tmp
/dev/mmcblk0p3	/var		ext4	defaults,noatime	0	2  # this is /var
/var/local/srv	/srv		none	bind  # this is /srv, which is actually a directory in /var
/var/local/home	/home		none	bind  # this is /home, which is actually a directory in /var


Now reboot and you will be in read only mode:

sudo reboot

Making changes

If you need to make changes, like installing new packages, you can do it like so:

Enter read/write mode:

sudo mount -o remount,rw /
sudo mount -o remount,rw /boot

Make your changes, eg:

sudo raspi-config
sudo apt-get install vim

Return to read-only mode:

sudo mount -o remount,ro /boot
sudo mount -o remount,ro /

Installing your own code

If you run software on your pi that you wrote, like something that runs in your home directory, or a cloned git repo; you probably want it to be protected by read only mode. Your home is no good as it is read/write. Follow these guidelines to make your software rugged too:

  • Copy your project to a directory in /opt, like /opt/bracken/my-project/ (remember to go to read/write mode to do this).
  • If it's a git repository, clone it in /opt
  • If your program writes files you want to keep, put them in /var, like /var/my-project/database.db
  • If your program writes temporary files put them in /tmp, this doesn't write to the SD card at all.
  • Put your logs in /var somewhere. Or better yet, use the system logger. Research 'syslog' in whatever programming language you use. Or start your program using a systemd service file, this will put anything you print into the system log.
This article is issued from Old-wiki. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.