Backup your Raspberry PI with one command
https://github.com/Chocorean/pibackup.git
pibackup.sh is a bash script that automatically dump a PI sdcard as a shrunk image to a [remote] directory, and handles rotation of several files. It is recommended to automate this script using systemd timers or cron, so the backups are done on a regular basis and without any interaction.
This is still WIP work, let me know if you have ideas about how to improve.
Once during a house move, I unplugged a Raspberry PI and somehow it killed the SD card. All my code was saved already, but I lost hours of my time spent on configuring and pimping my PI. I was so mad at myself for not doing backups that I started to look into automatic backup tools, but I didn't find anything that pleased me enough. So I bought an external drive and started this project. Hope it will be useful for more people than just myself!
Note: It will create a <output>/<target> directory, so you can use the same output directory for multiple nodes.
$ ./pibackup.sh -h
---
pibackup.sh 0.5
---
usage: pibackup.sh -o <output> [options]
Required parameters:
-o, --output-dir [DIRECTORY] Where backup will be saved and rotated.
Optional parameters:
-h, --help Display this message.
-n, --image-name [NAME] Rename the backup file as '<TARGET>.img.x'.
Default: self ($ uname -n)
-r, --rotation-count [COUNT] Quantity of files to be kept. Default: 8
-t, --tmp-dir [DIRECTORY] Temporary directory to use on the remote node. Default: /tmp
-T, --target [HOSTNAME] Name of the host to backup. Default: self ($ uname -n)
-q, --quiet Silent mode.
-z, --gzip Compress image using gzip.
-Z, --xz Compress image using xz.
$ which pishrink.sh
/usr/local/bin/pishrink.sh
cron you may need postfix to deliver local mails:sudo apt install postfix
All you need to do is download pibackup.sh, make it executable and put it in your PATH.
wget https://raw.githubusercontent.com/Chocorean/pibackup/main/pibackup.sh
chmod +x pibackup.sh
sudo mv pibackup.sh /usr/local/bin
For a local backup, this is simplest you can use:
user@pi $ pibackup.sh -o /backups -n awesome_pi
[pibackup.sh] Dumping sdcard ...
[ ... dd output ... ]
[pibackup.sh] Setting permissions ...
[pibackup.sh] Shrinking image ...
[ ... pishrink.sh output ... ]
[pibackup.sh] Rotating previous images ...
[pibackup.sh] Done ...
user@pi $ ls /backups/pi
awesome_pi.img.0
For a remote node, just specify its hostname or IP address.
user@pi$ pibackup.sh -o /backups -d another_pi
[pibackup.sh] Dumping sdcard ...
[ ... dd output ... ]
[pibackup.sh] Setting permissions ...
[pibackup.sh] Shrinking image ...
[ ... pishrink.sh output ... ]
[pibackup.sh] Rotating previous images ...
[pibackup.sh] Done ...
user@pi $ ls /backups/another_pi
another_pi.img.0
Doing backups is a good thing, however you know to know how to restore them. Right now, I haven't looked at the newest feature which allows to boot from the network, but I might add a section about it later.
Use a computer with access to the storage drive. If you compress your images, you will need to decompress them first:
# -Z ; xz
cp /path/to/backup.xz.0 backup.xz
unxz backup.xz
# -z ; gzip
cp /path/to/backup.gz.0 backup.gz
gunzip backup.gz
Now you have a suitable image for flashing an SD card. Plug the SD card you want to overwrite and copy the image:
sudo dd if=backup.img of=/dev/mmcblk0 bs=4M conv=noerror,sync status=progress
Insert the SD card in your PI and you recovered all your data!
The recommended way to use pibackup.sh is to create a systemd timer-service duo, but a cron job will work fine. You also need to make sure your nodes have a proper SSH config which allows the main node to connect to them without asking for password (see ~/.ssh/authorized_keys file).
You will first need to create the timer and the associated service. Then, enable and start the timer:
# systemctl enable pibackup.timer
# systemctl start pibackup.timer
Check the docs for OnCalendar= syntax.
/etc/systemd/system/pibackup.timer
[Unit]
Description=Run pibackup.sh every monday at 2am
[Timer]
Unit=pibackup.service
OnCalendar=Mon, 2:00 [Install]
WantedBy=timers.target
/etc/systemd/system/pibackup.service
[Unit]
Description=Run pibackup [Service]
Type=oneshot
ExecStart=/usr/local/bin/pibackup.sh ...
User=pi
systemd timer example
systemd service example
Thanks to Mcdostone for the suggestion.
I recommend to seperate cron logs from syslog logs for easier troubleshooting. If not the case already, edit /etc/rsyslog.conf and uncomment cron.* /var/log/cron.log.
As stated in the Prerequisites section, you may also need to install postfix because cron sends mails if a job has an output.
Also, I had to set SHELL and PATH variables inside the crontab to make it work, but that might not be necessary for you.
Check the docs for crontab syntax.
$ crontab -e # default shell
SHELL=/bin/bash
# set PATH variable
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin # Do a backup once a week on Mondays at 2am
0 2 MON /usr/local/bin/pibackup.sh ...
crontab example
Quoting Drewsif:
If you find a bug please create an issue for it. If you would like a new feature added, you can create an issue for it but I can't promise that I will get to it.
> Pull requests for new features and bug fixes are more than welcome!