backup raspberry pi

The ultimate guide to backup and restore your Raspberry Pi

If like me you make a lot of 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?
There are several methods you can use to back up your Raspberry Pi:

  • 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

It all depends on your use of the Raspberry Pi and your network

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

Script

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:

  • /etc/app1/file1.conf
  • /etc/app2

Then we need to create a backup folder to store the files

mkdir /home/pi/backups

Use nano to create the script

nano /usr/local/bin/backup.sh

And finally, the first 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

Use variables

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

Compress files

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 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 and we stop deleting the previous backup

Each time the script run, it will now create a new file and keep all the previous versions

Schedule backups

Once we have created our script, following the previous steps, most of the work is done

It remains only to program our script so that it starts every day for example
For that, we will use the crontab

  • Open the user’s crontab
    crontab -e
  • 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 backup 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 do to free space is to delete files older than eight days (or more if needed)

To do this, you can add this command at the end of the script:

/usr/bin/find $DEST_FOLDER -mtime +8 -delete

By doing 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 some 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

Manually

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

mkdir /home/[USER]/backups_pi

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

Automatically

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 and allow them on the pc)

Key exchange

  • 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

    Type 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
    ssh pi@[RASPBERRY_IP]

Script example

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

Manually

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
    winscp settings
  • 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
Automatically

There is no way to schedule a transfer with WinSCP. And it’s not easy to install SSH on Windows.
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

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

Script example

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

Restore

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

From Linux

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

From Windows

On Windows, I’m not sure 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

Uncompress the files with this tool and transfer them to the Raspberry Pi with WinSCP as seen above

Try it

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

Monitoring

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

Backup

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

Restore

To recover a lost database you have to follow the same steps than 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?

Backup

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

Linux

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

Windows

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
    win32 disk image
  • 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

Restore

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

Prerequisites

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)

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
sd card copier raspbian

  • 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 with the Raspbian 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 git to download the files
sudo apt-get install git
  • Start by downloading and installing the script:
cd ~/Downloads
git clone https://github.com/billw2/rpi-clone.git 
cd rpi-clone
sudo cp rpi-clone rpi-clone-setup /usr/local/sbin
  • Then use fdisk to get the backup SD card name
sudo fdisk -l

You 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

Conclusion

That’s it.
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

 

Leave a Comment