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.
Page Contents
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).
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?
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
Oops I made a type “if=if=” should be just one time “if=”.
Interesting read about how much gzip streaming zip reduces total transfer time (wire time):
http://henry.precheur.org/web/http_compression
It’s about 36%.
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.