This question answers the question of how I use an external computer to create a backup of my RPi.

I'm wondering whether I can create a backup image of the SD card that is currently in use, and copying it to a file on a USB storage device. Is this possible? If not, is there any way to create a backup of a RPi without involving another computer?

  • 2
    Sure, but skip /tmp, /run, /proc, /sys, /dev, and /mnt. You don't need to create an image, you need a backup you can create or update an image from. So don't use dd, look into rsync. – goldilocks Mar 14 '13 at 2:13
  • 1
    @goldilocks I would love it if you would flesh this comment out into a more complete answer, explaining the backup & restore process you have in mind. – Eric Wilson Mar 14 '13 at 9:31
  • Done -- sorry it took me a few days to find the time. – goldilocks Mar 17 '13 at 15:33
  • 1
    If your destination volume is big enough, remounting the filesystem read-only and doing a dd copy with an appropriate block size will probably be fastest for a "new" copy. Doing a file-by-file copy to flash/SD media is probably a bad idea. – Chris Stratton Dec 11 '15 at 1:41

Here's an intro to using rsync for back-up on the pi. Once the initial back-up is created, keeping it up to date this way is much much faster than constantly ripping the entire image. You can do this to a local hard drive or over a network.

You actually do not want a complete copy of a running system as a back-up, since some of the stuff ostensibly in the filesystem exists only at runtime. Including that in a backup and then using it to recreate an image later may create problems for you.

There are some other exceptions too. Rsync can accept a list of (glob) patterns to exclude, and those can be read from a file, so let's first go thru what should be in such a file. Note that the entries are of the form /directory/* and not /directory. This is because we want them to exist, but we don't want to copy anything in them.

/proc/*
/sys/*

These do not really exist on disk. They're an interface to the kernel, which creates and maintains them in memory. If you copy these and then copy them back into a system and boot it, it will be (at best) meaningless, since the kernel uses those as mount points for the interfaces [If you want to see what happens when you mount a device on a directory with data in it, try. It works and won't do any harm, but the stuff that was in the directory is now inaccessible.]

Note that it is critical that the /sys and /proc mount points exist. But they should not contain anything. Next:

/dev/*

The dev directory is not quite the same thing as proc and sys but for our purposes it is. If you believe that you should save this so you can have the same device nodes in your backup or something, you're wrong. Don't bother. Do not copy dev. Once upon a long time ago linux did work that way, but it doesn't anymore.

/boot/*

This is sort of a special case with the most (perhaps all) of the Pi specific distros such as Raspbian. It's actually a mount point for the first, vfat, partition. We are going to deal with that separately. Whatever you do, don't bother including it here, because again, it's a mount point.

/tmp/*
/run/*

/run is generally not on disk either, it's in memory. Perhaps /tmp could be too (this would save a bit of SD card action), but in any case, as the names imply, these are not places for storing persistent data. Applications which use them expect that they may be deleted at each boot.

/mnt/*
/media/8

These are important particularly if you are planning to back up to a hard drive or USB stick and the device is in /mnt or /media (automounting tends to use the latter), because if you don't exclude the location of those devices in the filesystem you will create a loop backing up the content of the drive to itself, until it runs out of space. I think rsync might be smart enough to spot something that dumb but try to avoid testing the premise.

On to the actual backing up: Create a directory to back up to on the locally mounted harddrive, USB thing, etc. -- e.g. "pi_backup". You can alternately backup to a remote location via ssh (see below) or using a network mounted filesystem, but this will probably take a while the first time.

If the file containing the list to exclude is /rsync-exclude.txt1 and your drive is /mnt/usbhd, to do the actual backup:

rsync -aHv --delete --exclude-from=/rsync-exclude.txt / /mnt/usbhd/pi_backup/

Notice that there is a trailing slash on pi_backup/.

This will take a while and produce a lot of output (if you want to examine that in a log instead, append > rsync.log). --delete is meaningless the first time, but for keeping the backup updated use it. This ensures that stuff you've later deleted on the pi also gets removed from your backup. The a sets recursion into directories and makes sure all the file attributes match. -H is to preserve hard links,2 v is for verbose which is why you get some output (otherwise rsync is quiet). See man rsync for more.

There is a shortcut whereby you can skip the --exclude-from file. If you are sure that all of the things you don't want to copy (/tmp etc.) are on separate filesystems, you can just use:

rsync -axHv --delete-during / /mnt/usbhd/pi_backup/

-x has been inserted. This is the short form of --one-file-system, which tells rsync not to cross filesystem boundaries. Personally I prefer the --exclude-from, but on e.g., default Raspbian, --one-file-system will work fine. You can use both if you want to be -xtra careful :D

That's not quite a complete backup. It's enough if you haven't put anything in boot and you are fine with using the back up to just restore the system by sticking the card in a computer and running:

rsync -av --delete-during /mnt/usbhd/pi_backup/ /mnt/sdcard_partition2/

You could also do this with a card with a new image on it (presuming it's the same as your base image) although that's a little inefficient if you have to create the image (because you're then going to overwrite most of it). You could also connect another SD card via a usb adapter with such an image on it, and use the above method to maintain a duplicate card.

If you've put stuff in /boot (eg, a custom kernel), including /boot/config.txt, you'll want to back that up too (pretty simple -- there's not much to it). Just do it separately, and when you restore, that stuff goes in the first partition.

See here if you want to create a blank raspbian style image which you could then backup into. You can use a similar methodology to create an empty Raspbian style card -- just rather than dealing with an .img file, you'd be dealing with a real device (e.g. /dev/sdb), meaning all you have to do is create the partition table with fdisk and then format /dev/sdb1 and sdb2 (or whatever) with mkfs.

But copying the whole image is easier! Why bother with this?

It's not that hard; I restored to a blank card (formatted as per that last link) in 10 minutes. Yes, just using dd on the whole thing is simpler (if you find stuff like words confusing...), BUT then it takes quite a while every time you want to update your backup because you must do 100% of it every time. Using rsync, once a backup exists, updating it is much much faster, so you can set this up to happen painlessly everyday via cron. Over a network even. Every six hours. The more often you do it, the less time it will take.

rsync via ssh

Here's an example:

rsync [options] --rsh="ssh [ssh options]" root@[the pi ip]:/ /backup/rpi/

"Options" would be, eg, -av --delete --exclude-from=/rsync-exclude.txt and "ssh options" is whatever you normally use (if anything). You must have root access via ssh to do this for the purposes of a system backup (set PermitRootLogin=yes in /etc/ssh/sshd_config and restart the server).


  1. You should keep this file. You can put comments in it on lines beginning with # or ;. This could include the actual rsync command, which can be copy pasted later so you don't have to remember it each time.

  2. Thanks to Kris for pointing out rsync doesn't do this automatically.

  • Goldilocks. That looks like a great use of rysync. Any chance of rolling it into a script for us? – totalitarian Aug 27 '13 at 7:47
  • Instead of manually excluding all mountpoints, why not mkdir /tmp/backupable && mount --bind / /tmp/backupable and rsync that? That also has the advantage of backing up any data stored in places that are "shadowed" by something mounted there. – n.st Dec 18 '14 at 5:11
  • @n.st Good idea (lol)! I've edited the suggestion into the question, although I still think using --exclude-from is a better idea. If you have time, you could write this up as a separate answer, you have my vote, and I can reference that. This answer is long winded enough. – goldilocks Dec 18 '14 at 21:09
  • 1
    @IgorGanapolsky The intention is to not create an image (read the "But copying the whole image is easier! Why bother with this?" part). In addition to being easier and faster to maintain once created, this method is generally more flexible. If you want to use it later to create an .img you can; this and this should help to explain how they are structured and can be created. – goldilocks Jan 25 '17 at 15:23
  • 1
    See the paragraph that begins, "That's not quite a complete backup...". It's basically the exact same thing in reverse. This may help with some concepts that people are commonly confused by/about. – goldilocks Jan 25 '17 at 15:38

A working script from the Raspberry Community made by a member there.

You can reuse and tweak the code how ever you like.It is well documented and self explanatory.

#!/bin/bash

# Setting up directories
SUBDIR=raspberrypi_backups
DIR=/hdd/$SUBDIR

echo "Starting RaspberryPI backup process!"

# First check if pv package is installed, if not, install it first
PACKAGESTATUS=`dpkg -s pv | grep Status`;

if [[ $PACKAGESTATUS == S* ]]
   then
      echo "Package 'pv' is installed."
   else
      echo "Package 'pv' is NOT installed."
      echo "Installing package 'pv'. Please wait..."
      apt-get -y install pv
fi

# Check if backup directory exists
if [ ! -d "$DIR" ];
   then
      echo "Backup directory $DIR doesn't exist, creating it now!"
      mkdir $DIR
fi

# Create a filename with datestamp for our current backup (without .img suffix)
OFILE="$DIR/backup_$(date +%Y%m%d_%H%M%S)"

# Create final filename, with suffix
OFILEFINAL=$OFILE.img

# First sync disks
sync; sync

# Shut down some services before starting backup process
echo "Stopping some services before backup."
service apache2 stop
service mysql stop
service cron stop

# Begin the backup process, should take about 1 hour from 8Gb SD card to HDD
echo "Backing up SD card to USB HDD."
echo "This will take some time depending on your SD card size and read performance. Please wait..."
SDSIZE=`blockdev --getsize64 /dev/mmcblk0`;
pv -tpreb /dev/mmcblk0 -s $SDSIZE | dd of=$OFILE bs=1M conv=sync,noerror iflag=fullblock

# Wait for DD to finish and catch result
RESULT=$?

# Start services again that where shutdown before backup process
echo "Start the stopped services again."
service apache2 start
service mysql start
service cron start

# If command has completed successfully, delete previous backups and exit
if [ $RESULT = 0 ];
   then
      echo "Successful backup, previous backup files will be deleted."
      rm -f $DIR/backup_*.tar.gz
      mv $OFILE $OFILEFINAL
      echo "Backup is being tarred. Please wait..."
      tar zcf $OFILEFINAL.tar.gz $OFILEFINAL
      rm -rf $OFILEFINAL
      echo "RaspberryPI backup process completed! FILE: $OFILEFINAL.tar.gz"
      exit 0
# Else remove attempted backup file
   else
      echo "Backup failed! Previous backup files untouched."
      echo "Please check there is sufficient space on the HDD."
      rm -f $OFILE
      echo "RaspberryPI backup process failed!"
      exit 1
fi

Consider adding comments to the original forum or post your own version to help mature the content. Take a little give a little.

*And thank you for giving back AndersW (Click for GIT script)

  • 2
    What if the filesystem (file deletion, new files added) changes in the time while the pi is backuping? – keiki Mar 14 '13 at 13:47
  • 2
    I back up several disks while they are running with rsync, and I have frequently been able to get exactly what I need from these file backups. However, in general, a unix file system can not be copied perfectly (with every bit in place and correct) while the file system is mounted (*). A copy made while the system was mounted is sometimes called a "dirty copy". Several measures can be taken to improve the quality of a dirty copy (as the script above does, shutting off cron and mysql) but it can't be perfect. Cheers! * -- I am wrong about this, it depends on the file system. – Tai Viinikka Mar 14 '13 at 14:28
  • 1
    @TaiViinikka You don't need a perfect copy. You need a partial copy that can be (quickly and easily) re-imposed on the original base image. rsync is the way to go; when I have time tomorrow I'll add an answer. rsnapshot is also worth investigating. – goldilocks Mar 14 '13 at 18:12
  • 3
    Based on ppumkins answer above, I synced up the 'dd' script with the latest comments in the original thread and added some minor improvements myself. The end result is available here: <github.com/aweijnitz/pi_backup>;. Please don't hesitate to add improvements and sending me pull requests. – AndersW Sep 4 '13 at 21:36
  • 1
    Ideas about how to actually use the backup file produced are here: Restore of Raspberry Backup. – goldilocks Jan 21 '14 at 14:56

I have adapted @goldilocks answer on rsync for back-up on the pi. I backup to an ext4 partition on a HDD mounted on the Pi. If the HDD is not mounted, rsync would copy to the mount directory (until the SD Card is full). If the HDD is not mounted in rw mode copious error messages are produced. Neither of these is desirable, so I check that my partition is is mounted in rw mode before proceeding.

NOTE 2015-03-03 I modified my answer to accurately copy hardlinks. The original worked, but converted many hardlinks into files. In addition to wasting space, this compromises many uses which assume the hardlinks are in place. (My current image has 869 links, many in Raspbian itself.)

My script to do this follows. (My partition is PiData, mounted on /mnt/PiData

#!/bin/bash
# script to synchronise Pi files to backup
BACKUP_MOUNTED=$(mount | awk '/PiData/ {print $6}' | grep "rw")
if [ $BACKUP_MOUNTED ]; then
    echo $BACKUP_MOUNTED
    echo "Commencing Backup"
    rsync -avH --delete-during --delete-excluded --exclude-from=/usr/bin/rsync-exclude.txt / /mnt/PiData/PiBackup/
else
    echo "Backup drive not available or not writable"
fi

Restore (or update another Pi) with the following:-

sudo rsync -avH /mnt/PiData/PiBackup/ /

I have enhanced the rsync-exclude.txt to eliminate unnecessary files.

The first group are the directories documented by @goldilocks https://raspberrypi.stackexchange.com/users/5538/

The second group are the files and directories created by OS X when I access my Pi using AFP (Apple Filing Protocol). (These are normally invisible on OS X, but not on Raspbian. In any event, there is no need to backup.) Even if you never use AFP, these will do no harm.

The third group are files which do not need to be backed up (and certainly not copied to another Pi). Examples fake-hwclock.data, RPi-Monitor reports. You will probably have others.

/proc/*
/sys/*
/dev/*
/boot/*
/tmp/*
/run/*
/mnt/*

.Trashes
._.Trashes
.fseventsd
.Spotlight-V100
.DS_Store
.AppleDesktop
.AppleDB
Network Trash Folder
Temporary Items

.bash_history
/etc/fake-hwclock.data
/var/lib/rpimonitor/stat/
  • Is there a way to make that output an .img file? – Igor Ganapolsky Jan 25 '17 at 15:24
  • @IgorGanapolsky Well, seeing as all of the essential files are there (excepting boot files), it is obviously possible, but if you want an image make an image. You should ask any new question in a new post, not comments. – Milliways Jan 26 '17 at 3:42

I have three Pis running in my local net and need to backup them on a regular base with cron when they are up and running. That's why I created a script which is able to create dd, tar and rsync backups and to restore them. I prefer to use rsync for my backups but other folks prefer dd or tar. It's used by a lot of people already. Hope it's useful for others also :-) raspibackup - Raspberry creates backups of itself

  • 1
    Nope, sorry: asking user to run (as root!) a script downloaded over HTTP is irresponsible. Please distribute this script over a safe channel. – Clément May 1 '16 at 20:38
  • I see your point. But please note: Initially the user had to download raspiBackup and the sample config file manually and to copy them in /usr/local/bin and /usr/local/etc (That's why root access is required). But then I was asked by users to provide an installation script for their convenience. The instructions how to install everything manually are still there (actually the last installation option). If you want to discuss this issue in more detail feel free to comment on the webpage. I don't think this is the right place for this kind of discussion because it's offtopic. – framp May 7 '16 at 7:36
  • 1
    I don't think it's off topic, and root or not doesn't matter much. The point is that software should be distributed over a secure channel, and your answer is encouraging bad security practices. – Clément May 7 '16 at 21:44
  • 1
    That would be a great step forward, yes :) – Clément May 9 '16 at 3:06
  • 1
    Just to note that delivery over HTTPS does not in any way add any security in this instance! You are still downloading and running a script from the Internet. The secure process is to download the script (http/https is irrelevant), open the script in an editor and read it top to bottom, check it for oddities and insecurities. Only when you are satisfied should you run it. Framp might be a hacker for all any of us know and delivery over https would only make him smile in that case :) (BTW, that isn't an accusation Framp!) – Julian Knight Jun 15 '16 at 15:02

Here is our stable tool for such purposes: https://github.com/aktos-io/aktos-dcs-tools

This tool is written to make ssh connections, make backup-root, make mount-root from remote places in mind at first, and then local sessions are added. So it supports local backups, direct remote backups, proxy remote backups. Backups are taken incrementally (only diffs are transferred) and backup directories are standalone (just pick a directory/version to restore, any directory has a full backup). Of course, you have versions (backup.last-0 is the newest one). You can interrupt backup process at anytime and continue later.

Here are the instructions for your specific problem:

 ssh to-your-raspberry
 cd /mnt/usb0/my-rpi-backups
 git clone https://github.com/ceremcem/aktos-dcs-tools backup-tools
 ln -s backup-tools/Makefile .

 ./backup-tools/configure # you do not need to make any settings for local sessions, just save the default 

 # just for the first time
 make set-local-session  # a flag file is created
 make init               # snapshots directory is created

 # anytime you want to back up
 make backup-root        # backup with rsync

EDIT

Now there is a new target added: You can create a physical SD Card from your backups with one command:

make create-disk-from-last-backup

Follow the instructions, create your SD Card, boot RaspberryPi with this newly created SD Card.

Open terminal and type 'lsblk -f' .
This should show all connected storage devices.
Then type 'dd if=/dev/[the NAME of your sd card] bs=1M'.
This will take a while so you might want to run it in the background.
This is the same exact way you backup your sd card in Linux.

  • That backs up EVERYTHING, even unnecessary and undesirable files. – Igor Ganapolsky Jan 25 '17 at 15:27
  • This will make an inconsistent backup because on a running system things changed during backup! – Ingo Jul 12 at 9:36

Here is a complete different approach. You can use LVM (Logical Volume Manager) to make consistent backups. Beside other improvements like easy adding, expanding and reducing storage or restore the operating system to an earlier status from a snapshot you can also make backups. You don't have do worry about dynamic changed files during backup, setting file systems read only, exclude specific directories or something else. With LVM you simply create a snapshot, mount this snapshot and backup it with the method you prefer. You can make a copy with cp -a, make a mirror with rsync, make an archive with tar or make an image with dd. Assuming you have mounted a backup device on /mnt/usbhd/pi_backup/ you can do for example:

rpi ~$ sudo lvcreate --snapshot --name rpi_snap --size 1G rpi_vg/root_lv
rpi ~$ sudo mkdir /mnt/snapshot
rpi ~$ sudo mount /dev/mapper/rpi_vg-rpi_snap /mnt/snapshot

# make backups
rpi ~$ sudo cp -a /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo rsync -aH --delete /mnt/snapshot/ /mnt/usbhd/pi_backup/
rpi ~$ sudo tar -czf /mnt/usbhd/pi_backup/backup.tar.gz -V "Backup of my Raspberry Pi" -C /mnt/snapshot/ ./
rpi ~$ sudo dd if=/mnt/snapshot/ of=/mnt/usbhd/pi_backup/backup.img bs=4M

rpi ~$ sudo umount /mnt/snapshot/
rpi ~$ sudo lvremove rpi_vg/rpi_snap

It takes only one time a little effort to setup LVM. How to do that you can look at Easy backups and snapshots of a running system with LVM.

protected by Community Jan 20 '14 at 18:52

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.