If like me, you make many changes on your Raspberry Pi, it might be a good idea to create backups.
And what’s even better is to make sure backups are recoverable 🙂
Yes, but then how to backup a Raspberry Pi and recover it? That what we’ll see in this complete guide.
The best way to create a backup of a Raspberry Pi is to use a tool like rsync, and copy the important files to another location on the network.
It’s also possible to create entire backups of the SD card, to make sure everything is secured.
As often, there is not only one way to do this. It highly depends on how you use your Raspberry Pi, and what is available on your network to store the backups.
It this tutorial, I will guide you through several solutions:
- Back up only important files (configuration, documents, MySQL databases)
- Make a complete image of the SD card on another computer
- Or do a full backup of a Raspberry Pi while running
We will now see in detail how to do each one.
Backup only the important files
The first method you can use if you have a simple installation is to backup only the needed files.
For example, if you use your Raspberry Pi for a security camera, once you back up the configuration file, it’s ok, you don’t need more.
So we’ll see step by step :
- How to create a script to do that
- How to schedule it if the files are modified
- How to send the file on another computer (in the script or manually)
- And finally, how to restore the files
Before starting to create the script, you have to identify the files you need to save.
In my script I’ll use a file and a folder that you can adapt to your needs:
Then we need to create a backup folder to store the files:
Use nano to create the script:
And finally, the first version of a simple script could look like this:
#!/bin/bash /bin/cp /etc/app1/file1.conf /home/pi/backups /bin/cp /etc/app2 /home/pi/backups/ -r
As you can see it’s a basic script, that will overwrite the old backup each time.
So now we’ll improve this script on several points.
The first good practice we’ll use to improve the scripts is to add variables.
For example, you have 200 files to backups to /home/pi/backups and tomorrow you want to save them in /media/nas/pi/.
You’ll have to edit 200 lines in your script to change the destination folder.
A better way to do this is to create a variable at the beginning with the destination folder path and use it for each line.
I’ll also do the same for the “cp” command, so if you want to change it to use rsync or another command, you’ll have only one line to edit.
Here’s a better script:
#!/bin/bash DEST_FOLDER='/home/pi/backups/' BACKUP_CMD='/bin/cp' $BACKUP_CMD /etc/app1/file1.conf $DEST_FOLDER $BACKUP_CMD /etc/app2 $DEST_FOLDER -r
The result will be the same, but it will be easier to update
Most of the time, we use compression for backup or at least archive files.
I’ll use tar to archive all files in one and gzip to compress this file.
Here is the new script:
#!/bin/bash DEST_FOLDER='/home/pi/backups/' DEST_FILE='backup.tar' BACKUP_CMD='/bin/tar -rvf' /bin/rm $DEST_FOLDER/$DEST_FILE.gz $BACKUP_CMD $DEST_FOLDER/$DEST_FILE /etc/app1/file1.conf $BACKUP_CMD $DEST_FOLDER/$DEST_FILE /etc/app2 /bin/gzip $DEST_FOLDER/$DEST_FILE
I add a new variable DEST_FILE to store the file name of the backup.
“tar -rvf” allows you to append several files to one tar file.
“gzip” allows you to compress the whole tar file.
Stop overwriting files
As you can see in the last script, we delete the previous backup each time.
It’s not a good thing to do. If there is an issue with the backup, you’ll not be able to get an older version.
The good practice is to name the backup file with the current date time, like this:
#!/bin/bash DEST_FOLDER='/home/pi/backups/' DEST_FILE='backup-$(date +%F_%R).tar' BACKUP_CMD='/bin/tar -rvf' $BACKUP_CMD $DEST_FOLDER/$DEST_FILE /etc/app1/file1.conf $BACKUP_CMD $DEST_FOLDER/$DEST_FILE /etc/app2 /bin/gzip $DEST_FOLDER/$DEST_FILE
Nothing changed except we add the date in the DEST_FILE variable, so that we stop deleting the previous backup.
Each time the script run, it will now create a new file and keep all the previous versions.
Once we have created our script, following the previous steps, most of the work is done.
We only need to schedule our script so that it starts every day automatically.
For that, we will use the crontab:
- Open the user’s crontab:
- Paste this line at the end of the file:
0 0 * * * /usr/local/bin/backup.sh
This cron will run your backup script each day at midnight, but you can change it if you want.
- Save and quit (CTRL+O, Enter, CTRL+X)
If you back up files with privilege access needed, don’t forget to schedule the script in the root crontab (sudo crontab -e).
If you are not comfortable with this, do not hesitate to read my tutorial on scheduling tasks on Raspberry Pi.
Delete old files
As you can see, each day a new file will be created, and we never delete it.
What you can do to free disk space is to delete files older than eight days (or more if needed).
To configure this, you can add this command at the end of the script:
/usr/bin/find $DEST_FOLDER -mtime +8 -delete
By adding this, you’ll have at anytime only eight backup files of history in your destination folder.
Feel free to change the number of files you want to keep.
It’s always a good idea to keep several days of history.
You can’t be sure to see the issue with your files on the first day.
Send backup over the network
We now have a backup with a few days of history on the SD card, but it’s not enough.
If tomorrow you SD card doesn’t work anymore, it will not help to have backup files on it.
We need to put the files safe on another computer to avoid this kind of problems.
To a Linux computer or a NAS
If you have another computer on Linux (or a NAS), you can transfer backup files on it to keep them safe.
This method will work for macOS too.
Personally, I’m using a 4 bay Synology NAS, which is great to save high volumes of critical data. It’s a bit expensive, but you have redundancy and security that is difficult to get on a standard computer (and also many tools included).
For less important data, you can also turn another Raspberry Pi into a NAS and sync your files to it (check my tutorial if you want to try).
The first way to do this is manually.
If your files never change or if they are not so critical, you can do this once a week or a month to be safe.
To transfer the files from the Raspberry Pi to the Linux computer, we’ll use rsync.
So you need to install it on both machines:
sudo apt-get install rsync
Then create a backup folder on your computer:
Then you have two ways to transfer files:
- From your computer:
rsync -auzr pi@[RASPBERRY_IP]:/home/pi/backups/* /home/[USER]/backups_pi/
- From the Raspberry Pi:
rsync -auzr /home/pi/backups/* [USER]@[COMPUTER_IP]:/home/[USER]/backups_pi/
Don’t forget to replace the variables with the Raspberry Pi IP address and your username.
And feel free to delete old files before or after the transfer on your computer.
As when saving on the Raspberry Pi, it’s always a good idea to automate this kind of task.
The problem you might have seen is that a password is required when the transfer starts.
To avoid this, you must first make an exchange of SSH keys between the two machines.
For this step, I’ll assume it’s your computer that triggers the transfer.
If you prefer to transfer in the other direction, you have to do the opposite (generate the keys on the Raspberry Pi and allow them on the PC).
- Firstly start by generating a key on your computer (if you have already one, it’s ok, go to next step):
ssh-keygen -t rsa
Press Enter to each question, leave the passphrase empty.
- Then transfer the public key on the Raspberry Pi:
rsync ~/.ssh/id_rsa.pub pi@[RASPBERRY_IP]:/home/pi/
Last time you need to enter your password.
- On the Raspberry Pi, add the public key to the allowed keys:
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
- Try to connect in ssh now. It shouldn’t ask you a password:
So, now you should be able to put the rsync command in a script that will not ask for a password.
The script should look like this:
#!/bin/bash rsync -auzr pi@[RASPBERRY_IP]:/home/pi/backups/* /home/[USER]/backups_pi/ find /home/[USER]/backups_pi -mtime -8 -delete
Then schedule the script by adding it in your crontab as explain previously.
To Windows computer
If your computer is on Windows, you can also send your backup to it, manually or automatically.
To manually transfer files from the Raspberry Pi to your Windows computer, the easiest way is to install WinSCP on Windows.
It’s a free software to transfer files with SSH:
- Once installed, start WinSCP
- Add a new site with the Raspberry Pi information
- Click Save, and connect to this new site
- On the right, you’ll see the Raspberry Pi files, and on the left, your computer files.
You can now transfer files from one to the other with a drag & drop.
Go to /home/pi/backups on the Raspberry Pi and download one or all files.
Then you can remove the older files on your computer to keep only the last eight days for example.
There is no way to schedule a transfer with WinSCP. And it’s not easy to install SSH on Windows (to use it in a script at least).
So we have to find another method.
What I suggest you is to share a folder on Windows and access it from the Raspberry Pi.
Share a folder
Follow these steps to share a folder on Windows:
- Create a new folder to store your backups
- Right click on this folder and choose Properties in the context menu
- Go on the Sharing tab and click on the Share button
- By default, your user will have access to this share, but you can add other users if you want.
You’ll need a user with a password.
If your main user doesn’t have any password, you need to set one.
If you prefer you can create another account with a password.
- When it’s ok, click on the Share button
- It’s OK. You are now sharing the folder on the local network
Keep the network path to use it on the next step
For me, it was something like this: \\[COMPUTER-NAME]\Users\[USER]\Desktop\share
Mount the share on the Raspberry Pi
Now we need to connect the Raspberry Pi to the share.
To do this permanently, follow these steps:
- Create a new folder to host the share:
sudo mkdir /media/share
- Edit the /etc/fstab file:
sudo nano /etc/fstab
This file manages all drives and shares on the Raspberry Pi.
- Paste this line:
//[COMPUTER-NAME]/Users/[USER]/Desktop/share /media/share cifs username=[USER],password=[PASSWORD],iocharset=utf8 0 0
You need to replace all variables with your environment values.
You may also need to replace the folder name in the first value.
Note that we use / and not \ in the network path.
Save and quit (CTRL+O, Enter, CTRL+X)
- Mount the share once:
sudo mount /media/share
Your shared folder is now accessible in /media/share and if you create a file in this folder, the file will be available on your Windows computer:
sudo touch /media/share/test
Now that the share is available, you can create and schedule a script to copy backup files to this folder each day for example:
#!/bin/bash cp /home/pi/backups/* /media/share/ find /media/share -mtime +8 -delete
This backup is the easiest one to restore.
You only need to extract files from the archive and send them back to the original folder.
On Linux, you can use the default archive software from your distribution.
For example, on Ubuntu, double-click on the backup file to open it and see files in it.
And then click “Extract”.
Once you get the needed files, send them back to the Raspberry Pi with rsync as seen above.
On Windows, I’m not certain that the default tool can open a .tar.gz file, but you can try.
If not, you have to install a software like 7zip or WinRAR.
Extract the files with this tool and transfer them to the Raspberry Pi with WinSCP as seen above.
It’s a good idea to follow this restore procedure at least once.
So you can be sure that it works and that you know how to do it.
With this method, it’s easy to check that your backup is well done each day as expected.
You could create a script to check that you have recent files in your backups folder.
Something like this:
#!/bin/bash if [[ $(find /home/pi/backups -type f -mtime -1) ]]; then echo "Backup OK" //DO NOTHING else echo "Backup KO" //DO SOMETHING (MAIL ?) fi
Export MySQL data
If you have MySQL databases on your Raspberry Pi, the procedure is a bit different.
The best practice for MySQL data backup is to first export and then save this export.
Export database with this command line:
mysqldump -uroot -p[PASSWORD] [DATABASE-NAME] > export-[DATABASE-NAME].sql
This command will create a file with all SQL queries needed to recreate the database from scratch.
You can follow the same steps as seen previously to:
- create a script
- schedule it
- transfer files to another computer
If you have more than one database to back up, put as many lines as needed in your script and change the database name and the file name on each line.
To recover a lost database you have to follow the same steps as for files backup.
Once the .sql file back on the Raspberry Pi, you can use this command to import data to a fresh database:
mysql -uroot -p[PASSWORD] [DATABASE-NAME] < [BACKUP-FILE].sql
The database must be empty to start the import.
So depending on the situation, you must follow one of these two methods:
- Import the backup into a database with another name (and then copy only what you are interested in)
- OR rename the corrupt database, recreate it (empty) and then import the backup file
As with file backup, consider testing this procedure at least once.
Create an image of the SD card
So we saw in the previous paragraphs how to save some files on a Raspberry Pi.
Now, how to do if you have a complex installation that you want to fully back up?
The goal of this backup method is to create an image with all your Raspberry Pi files in it.
Then you could flash this image to another SD card to recover the Raspberry Pi in the same state.
On Linux, you can use the dd command to create an image of a device:
- Take the SD card out from the Raspberry Pi
- Insert the SD card on your computer
- Find the device name:
sudo fdisk -l
This command will display all the storage devices of your computer.
You should see your hard drive, and somewhere at the end of the list your SD card.
Note the name of the device (generally /dev/sdX or /dev/mmcblk0).
- Create the image (replace the device name) :
sudo dd bs=4M if=/dev/mmcblk0 of=backup.img
After a few minutes, you’ll get the full backup image from your Raspberry Pi.
This command should also work on macOS, replace 4M by 4m in the last command.
On Windows, the best software to do this is Win32 Disk Imager:
- Download Win 32 Disk Imager, install it and launch it
- You should get a window like this
- Enter the image destination folder and file name (.img)
- Select the SD card letter in the device list
- Click on “Read”
- This tool will create the image in the selected folder
The easiest way to restore this backup is to flash the image on another SD card with Etcher:
- Download Etcher from the official website
- Install and run it
- Choose your backup image on the left
- Choose your SD card
- Click on the “Flash” button
You’ll get a new SD card with the system in the same state as during the backup.
On Linux / Mac you can also use dd to flash the SD card (reverse if and of):
sudo dd bs=4M if=backup.img of=/dev/mmcblk0
If you have an empty SD card, feel free to try this procedure to be sure it’s working in your case.
Clone a Raspberry Pi in operation (hot backup)
This last way is the same idea as the previous one, but for a critical installation.
If you can’t stop your Raspberry Pi to make the full backup into an image, you have to follow this procedure.
I will introduce you two ways to do a full backup of your Raspberry Pi in operation (from a desktop tool or with command lines).
In both cases, you’ll need to plug a second SD card in the Raspberry Pi to copy the running SD card to another.
If you don’t have one already, I recommend buying a cheap USB adapter on Amazon like this one.
Prefer an adapter with a short cable (long cable is not needed, and USB key format may obstruct access to other plugs). So the one I link is perfect for this.
PiClone (Desktop version)
If your Raspberry Pi is running the Desktop version, there is a tool called PiClone you can use for this.
The name in the main menu is “SD Card Copier”.
You can find it in the Accessories submenu.
The use of this software is simple:
- Choose your main SD card in the “Copy From Device” list
- Choose your backup SD card in the “Copy To Device” list
- Press Start to start the transfer
- Wait a few minutes and extract the backup SD card
Feel free to try this backup SD card in another Raspberry Pi to check it’s working properly.
Script (Lite version)
If you are running the Raspberry Pi OS Lite version or if you want to create a script, there is a shell script available to do this.
I will explain the basics to use this script.
But you can find all the information on the Github page if you need more.
- You’ll need to install Git to download the files:
sudo apt-get install git
- Start by downloading and installing the script:
git clone https://github.com/billw2/rpi-clone.git
sudo cp rpi-clone rpi-clone-setup /usr/local/sbin
- Then use fdisk to get the backup SD card name:
sudo fdisk -lYou should see the current SD card: sda or mmcblk0 most of the time.
- And below the backup SD card: sdb or mmcblk1 generally
- And finally, use rpi-clone:
sudo rpi-clone sdb -v
Replace sdb with your backup SD card name.
You know how to make backups of your Raspberry Pi in several ways.
Try to schedule them or if it’s not possible, try to do them regularly.
Also, try to check them from time to time.
There is nothing worse than a backup that hasn’t worked or is unusable because you have never tested that it worked as expected.