Skip to content

Instantly share code, notes, and snippets.

@fardjad
Last active September 14, 2024 22:33
Show Gist options
  • Save fardjad/57ad276c391a41bac18e86667c5d3c68 to your computer and use it in GitHub Desktop.
Save fardjad/57ad276c391a41bac18e86667c5d3c68 to your computer and use it in GitHub Desktop.
[Simple Remote Backup Solution for Linux] Periodically backup a list of directories to an NFS share with Tailscale and Restic #linux #systemd #restic #nfs #tailscale #backup

Files

NFS

Make sure network-online.target gets triggered correctly: https://systemd.io/NETWORK_ONLINE/

Run the following:

sudo systemctl daemon-reload

# make sure tailscale is up
# systemctl enable --now tailscaled
# tailscale up --reset=true --accept-routes=false --stateful-filtering=false

sudo systemctl enable --now nas-ping.service
sudo systemctl enable --now mnt-restic.mount

Restic

Make sure the files have the correct permissions:

sudo chmod 0600 /etc/restic/config.sh
sudo chmod 0600 /etc/restic/password
sudo chmod 0755 /usr/local/sbin/restic-simple-backup
sudo chmod 0755 /usr/local/sbin/system-backup

Initialize a restic repository (only for the first time):

sudo su
source /etc/restic/config.sh
restic init

Create a backup manually:

sudo system-backup

Check the snapshots:

sudo su
source /etc/restic/config.sh
restic snapshots

Timer

Run the following:

sudo systemctl daemon-reload
sudo systemctl enable system-backup.service
sudo systemctl enable --now system-backup.timer
export RESTIC_REPOSITORY=/mnt/restic
export RESTIC_PASSWORD_FILE=/etc/restic/password # generate a secure password and store it in this file
export TAG="replace-with-some-tag"
export KEEP_LAST=7
[Unit]
Description=Restic NFS Mount
After=nas-ping.service
[Mount]
What=1.2.3.4:/path/to/nfs/export
Where=/mnt/restic
Type=nfs4
Options=defaults,vers=4.1,proto=tcp,suid,rw,timeo=600,retrans=2,hard,fg,rsize=8192,wsize=8192,noatime,acregmin=0,acregmax=0,acdirmin=0,acdirmax=0,nofail
[Install]
WantedBy=multi-user.target
[Unit]
Description=NAS Ping
After=network-online.target
After=tailscaled.service
[Service]
ExecStartPre=/bin/bash -c "echo Waiting for NAS..."
ExecStartPre=/bin/bash -c "while ! ping -c1 1.2.3.4 &>/dev/null; do sleep 5; done" # replace 1.2.3.4 with the IP address of the NAS
ExecStart=/usr/bin/bash -c "echo NAS is reachable!"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
GENERATE_A_SECURE_RESTIC_REPO_PASSWORD
#!/usr/bin/env bash
set -e
source /etc/restic/config.sh
if [ -z "$TAG" ]; then
echo "TAG variable is not set"
exit 1
fi
if [ -z "$BACKUP_PATH" ]; then
echo "BACKUP_PATH variable is not set"
exit 1
fi
if [ -z "$KEEP_LAST" ]; then
echo "KEEP_LAST variable is not set"
exit 1
fi
restic --tag "$TAG" backup "$BACKUP_PATH"
restic forget --tag "$TAG" --keep-last "$KEEP_LAST"
sync
[Unit]
Description=System Backup Task
After=mnt-restic.mount
Requires=mnt-restic.mount
[Service]
Type=simple
User=root
Environment=HOME=/root
ExecStart=/usr/local/sbin/system-backup
#!/usr/bin/env bash
set -euo pipefail
export PATH="/usr/local/sbin:/usr/local/bin:/usr/bin"
for backup_path in "/home" "/etc"; do # add the directories you want to backup here
BACKUP_PATH="${backup_path}" restic-simple-backup
done
[Unit]
Description=Timer for System Backup Task
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment