How to automate backup of Raspberry Pi via script

This post describes how to automatically backup a running Raspberry Pi as image file on a NAS in the network.

For more articles about Raspberry Pi check: Raspberry Pi

One of my Raspberry Pis is very important in my home setup. It hosts my git, my Jenkins, my VPN Server and many more things. It would take me days to get everything up and running again in case of an sd card failure. So i have setup an automatic backup which flash-copies the current state as an image file to my NAS. With that I can directly flash on a new SD card and everything is working again.

The backup runs once a week triggered by my Jenkins server. But a cronjob would do it as well.

The Script

Everything is done in one script which is started by jenkins, the content is the following:

sudo mount -t nfs -o soft 192.168.2.132:/path/on/nas /home/user1/nas
sudo dd if=/dev/mmcblk0 of=/home/user1/nas/pi.img bs=1M
sudo pishrink.sh -z /home/user1/nas/pi.img
sudo mv /home/user1/nas/pi.img.gz /home/user1/nas/pi_`date +"%F"`.img.gz
umount -f -l /home/user1/nas

The first line mounts a specific folder to store the backup on NAS. You can omit that if your NAS is permanently mounted on your PI.

The second line flash-copies the whole SD card content into an image file into the mounted folder. This would already be enough for the backup/restore procedure.

The third line shrinks the newly created image with a nice script which is available here: https://github.com/Drewsif/PiShrink

This makes the image significantly smaller.

In the fourth line the newly created shrinked image file is renamed so that it contains the date when it was produced.

Finally the nas mount is removed again.

The procedure is the same when you want to create a base image for faster setup of Raspberry Pis, see also Create your Own Image for Raspberry Pi.

How it behaves

The PI holds a 64 GB SD card from which at the moment 12 GB are used. The size of the shrinked image is 5.9 GB.

The script execution takes around 58 minutes (this can be important for the jenkins timeout configurations).

5 Comments

Marty

You could dramatically improve efficiency and more than half total bits transferred over the network by piping the workload with the following command to replace the last 3 lines in your original script:

dd if=if=/dev/mmcblk0 | bzip2 –best > /home/user1/nas/pi_`date +”%F”`.img.bz2

or if you are more fond of gzip (for lesser but faster compression) by:

dd if=if=/dev/mmcblk0 | gzip –fast > /home/user1/nas/pi_`date +”%F”`.img.gz

Good luck and let me know how you fare?

Reply
Benni

I tried that: it took around 30% less time (45 minutes compared to 65 minutes) but the image takes around 900MB more space (6.6 GB vs. 7.5 GB).
I have not yet tested how it will behave when image is used for SD card flash

Marty

Hi Benni,

I revisited your imaging script which is started by Jenkins.

My previous advice will not work with “prishrink.sh”. It shrinks the filesystem in the image filedown to the actually populated part of the the filesystem. It can’t do that on a gzip’ed image file. Therefor your image took around 900MB more space.

I assume that the script is executed on your RPi and I assume it’s a multicore Pi (version 4?).
Is that correct?

The best strategy to speed things up is to reduce wire time (bits in transit over the 100Mbit network connection to the NAS).

Does your Pi have enough storage space (flash drive etc.) to operate on the image of your entire microSD card?

Let me know, then I can work out a faster strategy.

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *