If you're running a Raspberry Pi as a headless server, having a complete backup of its microSD card can save a lot of time and effort if the card fails or something goes wrong with your system.
This guide explains how to create an automated, weekly, compressed, full-disk image of a Raspberry Pi 4 running Debian. The process uses standard Linux tools already included with Debian, and keeps the two most recent backups to help manage storage space.
Why Create a Full-Disk Backup?
A full-disk image backs up the entire microSD card, including the operating system, installed software, configuration files, services, and partition layout. Unlike copying individual files, a full-disk image can be written to a replacement card to restore the system to its previous state.
This is particularly useful for a headless Raspberry Pi running services such as Pi-hole, Jellyfin, Samba, OpenVPN, or Tailscale. Rebuilding these services and restoring their configurations manually can take considerable time.
This approach creates a compressed disk image using gzip. The resulting file is smaller than an uncompressed image in many cases, while still containing the complete disk structure needed for restoration.
Requirements
- A Raspberry Pi running Debian.
- A microSD card containing the system you want to back up.
- An external or network-mounted backup drive with enough free space.
- A backup location that is mounted and accessible when the scheduled backup runs.
This example uses a 256 GB microSD card and saves backups to:
/mnt/wd_network/Backups/PiOSMicroSDCard
You can choose a different backup drive or directory. If you do, be sure to update the relevant paths in the script below to match your own setup. The mount-point check and the destination directory must both refer to your actual backup location.
Identify Your microSD Card
Before creating a backup, you need to confirm the device name of your microSD card. Do not assume it is always the same on every system.
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS,MODEL
On many Raspberry Pi systems, the microSD card is identified as /dev/mmcblk0. Confirm that this matches the device and capacity shown by the command before proceeding.
The script below uses /dev/mmcblk0 as its source device. If your system reports a different device, change the SOURCE variable accordingly.
Create the Backup Script
Create a new script file, for example:
nano /home/pi/backup-pi.sh
Paste the following script into the file. Make sure the very first line is #!/bin/bash, with no blank line or other characters before it.
#!/bin/bash
set -euo pipefail
SOURCE="/dev/mmcblk0"
BACKUP_MOUNT="/mnt/wd_network"
DEST="${BACKUP_MOUNT}/Backups/PiOSMicroSDCard"
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP="raspberry-pi-${TIMESTAMP}.img.gz"
TEMP="${DEST}/${BACKUP}.partial"
FINAL="${DEST}/${BACKUP}"
COMPLETE=0
cleanup() {
STATUS=$?
trap - EXIT
if [ "$COMPLETE" -ne 1 ]; then
rm -f -- "$TEMP" "$FINAL" "${FINAL}.sha256"
fi
exit "$STATUS"
}
trap cleanup EXIT
echo "Starting Raspberry Pi backup: $(date)"
if ! mountpoint -q "$BACKUP_MOUNT"; then
echo "ERROR: Backup drive is not mounted."
exit 1
fi
if [ ! -d "$DEST" ]; then
echo "ERROR: Backup directory does not exist."
exit 1
fi
if [ ! -b "$SOURCE" ]; then
echo "ERROR: Source device not found: $SOURCE"
exit 1
fi
echo "Creating compressed disk image..."
dd if="$SOURCE" bs=4M status=progress | gzip -1 > "$TEMP"
echo "Verifying compressed image..."
gzip -t "$TEMP"
echo "Moving backup into place..."
mv -- "$TEMP" "$FINAL"
echo "Creating checksum..."
(
cd "$DEST"
sha256sum "$BACKUP" > "${BACKUP}.sha256"
)
COMPLETE=1
echo "Backup completed: $FINAL"
shopt -s nullglob
BACKUPS=("$DEST"/raspberry-pi-*.img.gz)
if [ "${#BACKUPS[@]}" -gt 2 ]; then
while IFS= read -r OLD; do
rm -f -- "$OLD" "${OLD}.sha256"
echo "Removed old backup: $OLD"
done < <(printf '%s\n' "${BACKUPS[@]}" | sort -r | tail -n +3)
fi
echo "Backup process finished: $(date)"
Save the file and exit the editor.
Configure the Script
There are a few variables at the beginning of the script that you may need to customize:
SOURCE: The device representing your Raspberry Pi's microSD card.BACKUP_MOUNT: The mount point of your backup drive.DEST: The directory where the backup files will be stored. In this example, it is constructed using the mount point and the backup directory path.
If you use a different backup drive or folder, update BACKUP_MOUNT and DEST accordingly. The directory specified by DEST must already exist, and the backup drive must be mounted at the specified mount point before the script runs.
The script checks that the mount point is active before starting. This helps prevent a backup from accidentally being written to the Raspberry Pi's own filesystem when the external or network drive is unavailable.
Make the Script Executable
Allow the script to be executed by its owner:
chmod 700 /home/pi/backup-pi.sh
The script requires root privileges to read the entire microSD card. You can run it manually for testing with:
sudo /home/pi/backup-pi.sh
During the backup, dd reads the entire device and passes the data to gzip for compression. The status=progress option displays progress information in the terminal.
The script then tests the compressed file with gzip -t, generates a SHA-256 checksum, and moves the completed backup into its final filename. The checksum can later be used to check whether the backup file has changed or become corrupted.
If the backup fails before completion, the script attempts to remove its incomplete files. The retention step then removes older compressed backups, leaving the two most recent completed backups.
Schedule Weekly Backups
To automate the process, use cron. Open the root user's crontab:
sudo crontab -e
Add the following line to run the backup every Sunday at 3:00 AM:
0 3 * * 0 /home/pi/backup-pi.sh
Save and exit the editor. Cron will now run the backup script weekly with root privileges.
Choose a time when the Raspberry Pi is likely to have minimal activity. However, keep in mind that running a full-disk image while Debian is running does not guarantee a perfectly consistent snapshot. Files and application databases can change while the image is being created. For stronger consistency, shut down the Pi and image the card from another Linux system.
Understanding the Backup Files
Each successful run creates two files in your backup directory. For example:
raspberry-pi-2026-10-04_03-00-00.img.gz
raspberry-pi-2026-10-04_03-00-00.img.gz.sha256
The .img.gz file is a compressed, full-disk image of the microSD card. The .sha256 file contains its checksum, which can be used to verify the backup file's integrity.
The script keeps the two most recent backups and removes older ones after a new backup completes. This provides a basic recovery history without allowing the backup directory to grow indefinitely.
Compression can substantially reduce the space needed to store the image, particularly when the card contains a lot of unused space. It does not, however, avoid reading the entire microSD card, so the backup can still take a considerable amount of time.
Restoring a Backup
A compressed full-disk image can be restored to a replacement microSD card. The target card should have at least as much actual capacity as the original card; cards advertised with the same nominal capacity can differ slightly in their usable size.
The restoration process requires a computer that can access the backup drive and write directly to the microSD card. Depending on the filesystem used by your backup drive, you may need a Linux system to access the backup files. For example, macOS does not natively support reading ext4 drives.
If you do not have a separate Linux computer, a Linux virtual machine can be a practical option. You can run a Linux distribution such as Ubuntu using either Parallels Desktop on a Mac or Oracle VirtualBox. Configure the virtual machine to access the external backup drive and the microSD card through USB passthrough.
Before restoring, confirm that both devices are accessible inside Linux and carefully identify the microSD card's device name. The following example assumes the backup file is in the current directory and the replacement card is identified as /dev/sdX. Replace that placeholder with the correct device for your system. Selecting the wrong device can overwrite valuable data.
First, verify the backup checksum:
sha256sum -c raspberry-pi-2026-10-04_03-00-00.img.gz.sha256
Then restore the image by decompressing it directly onto the microSD card:
gzip -dc raspberry-pi-2026-10-04_03-00-00.img.gz | sudo dd of=/dev/sdX bs=4M status=progress conv=fsync
Use the whole device (such as /dev/sdX), not a partition (such as /dev/sdX1). Once the command finishes, run:
sync
Safely eject the card, insert it into the Raspberry Pi, and power it on. The restored system should have the same operating system, installed services, configurations, and data that were present when the image was created.
Important Considerations
- Test your backups: A completed image and a valid checksum do not guarantee that the Raspberry Pi will boot successfully from a restored card. Periodically test a restoration using a spare card if possible.
- Protect your backup drive: Keeping backups on a separate drive helps protect against microSD card failure, but it does not protect against failure of the backup drive itself. Consider keeping an additional copy elsewhere.
- Be aware of live imaging: The Pi remains running during this script. Changes made to files or databases while the image is being captured can result in an inconsistent backup. Scheduling the backup during a quiet period reduces activity but cannot eliminate this risk.
- Allow enough storage: Although gzip often reduces the image size significantly, the amount of compression depends on the data on the card. Make sure your backup destination has sufficient free space.
- Protect sensitive data: The image contains the entire system, potentially including passwords, keys, VPN configurations, and other sensitive information. The compressed file is not encrypted, so store it securely.
With a weekly schedule and two retained backups, you have a straightforward recovery option if your Raspberry Pi's microSD card fails or a system change causes problems. The most important final step is to make sure you can actually restore and boot from one of those backups.