This page collects notes on how to make automatic backups to an external drive.
I'm running the examples on a Raspbian Lite 11 (bullseye).
These are the steps I'll follow:
Make sure it's formatted with something writable by gnu/linux. Prefer ext4 if it's not intended to be read by Windows machines. FAT32 is fine as long as you don't store files bigger than 4GB. For now, you should avoid NTFS.
Watch where your pendrive is located
$ lsblk
In my case, mmcblk0 refers to the raspberry sd card, while sda refers to the pendrive. My output:
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 1 7,6G 0 disk
└─sda1 8:1 1 7,6G 0 part
mmcblk0 179:0 0 29,8G 0 disk
├─mmcblk0p1 179:1 0 256M 0 part /boot
└─mmcblk0p2 179:2 0 29,6G 0 part /
Get and save the UUID.I've formatted it in ext4. List this information using:
$ blkid
/dev/mmcblk0p1: LABEL_FATBOOT="boot" LABEL="boot" UUID="C839-E506" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="cd05fba6-01"
/dev/mmcblk0p2: LABEL="rootfs" UUID="568caafd-bab1-46cb-921b-cd257b61f505" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="cd05fba6-02"
/dev/sda1: LABEL="backupdrive" UUID="fa196346-a1b8-4019-9d4b-bcaa6488e734" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="1703ab4f-01"
In my case, the third line is the relevant one.
The script will:
To mount it, we'll need to create a folder to link to the external drive. Once mounted, the external drive will appear in the chosen folder.
Create the needed folder. The -p flag is needed to not throw errors if it already exists. Afterwards, mount it using the previous paragraph UUID and the destination folder by typing:
$ sudo mkdir -p /media/extdrive
$ sudo mount -U fa196346-a1b8-4019-9d4b-bcaa6488e734 /media/extdrive
You can copy with cp or by rsync. I suggest the first one if it's few files or you're sure they've changed. If you have to copy entire folders with many files, use rsync in order to skip unaltered ones.
I'll use cp as I want to copy only one file, i.e. a sqlite database, to the pendrive. Remember the last / so that cp knows we want to put that file in the folder.
The -p flag here keeps permissions, timestamp, owner and group data.
$ sudo cp -p /path/to/file.sqlite3 /media/extdrive/
After copying the file, we want to unmount the drive. I don't trust power failures, and by unmounting it we're even more sure that no I/O happens when it's not intended.
$ sudo umount /media/extdrive
If nothing appears on screen, it probably went fine. If this error appears umount: /media/extdrive: target is busy. you have probably cd'd into the directory and you need to exit with cd ..
I'll put this script in /opt/backup.sh
Create a new file with your favorite editor:
$ cd /opt
$ sudo nano backup.sh
This is the full content of my script.
#!/bin/bash
mkdir -p /media/extdrive
mount -U fa196346-a1b8-4019-9d4b-bcaa6488e734 /media/extdrive
sudo cp -p /home/django/progetto_verifica_tamponi/db.sqlite3 /media/extdrive/
sudo umount /media/extdrive
Add execution permission and test it:
$ sudo chmod +x backup.sh
$ sudo ./backup.sh
It's time to set a root crontab to run the previously made script. The former lists current user's ones, while the latter lists root's ones.
$ crontab -l
$ sudo crontab -l
Edit the root crontab. It prompts us to choose an editor. Type 1 if you don't know what this means:
$ sudo crontab -e
no crontab for root - using an empty one
Select an editor. To change later, run 'select-editor'.
1. /bin/nano <---- easiest
2. /usr/bin/vim.tiny
3. /bin/ed
Choose 1-3 [1]:
I want to run it twice per hour, only during work hours (from 7 to 22) every day. The comma "," is a value list separator. The dash "-" specifies a range. The asterisk means "every value of this column is ok".
For reference, these are the column headings. dom means "day of the month", mon means "month" and dow means "day of the week":
m h dom mon dow command
Then, this is my simple configuration line:
0,30 7-22 * * * /opt/backup.sh
I suggest using this website as a reference to build and test the meaning of your configuration line.