Node-RED Backup script (BASH & RSYNC)

UPDATED: 2021-02-28 - Fixed the script so that it works properly - reminder to self, don't use relative paths when working with CRON!


Hi again all, on a roll today. :smiley:

This time I finally got round to writing a backup script so that I don't have to do it by hand. I've usually done this with a remote tool in the past but I wanted some extra cover and something I can run manually as well if I need an extra backup.

The script here is written as a daily rotating backup so there are some things that you might want to do, I've listed some at the end.

You will need to have rsync installed but nothing else is needed other than CRON to run on a daily schedule (you could do that from within Node-RED if you wanted to).

However, this version also uses mosquitto_pub to send notifications on success or failure. Remove if you don't want that. You could instead use CURL to trigger a Node-RED endpoint.

#! /usr/bin/env bash

# Redirect stdout to syslog - show with: `sudo journalctl -t nrmain-backup`
exec 1> >(logger -t nrmain-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nrmain-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
SOURCE_PATH=/home/home/nrmain
DEST_PATH=/home/home/nrmain-backup
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting daily backup of $SOURCE_PATH/ to $DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [ -d $DEST_PATH/daily.7 ] ; then
    echo "  Deleting oldest daily backup $DEST_PATH/daily.7"

    rm -rf $DEST_PATH/daily.7
fi

# Shift all other daily backups ahead one day
for OLD in 6 5 4 3 2 1	; do
	if [ -d $DEST_PATH/daily.$OLD ] ; then
		NEW=$(($OLD+1))

		echo "  Moving $DEST_PATH/daily.$OLD to $DEST_PATH/daily.$NEW"
		
		# Backup last date
		# ISSUE: touch does not support options on synology (busybox) system
		touch $DEST_PATH/.timestamp -r $DEST_PATH/daily.$OLD
		mv $DEST_PATH/daily.$OLD $DEST_PATH/daily.$NEW
		# Restore timestamp
		touch $DEST_PATH/daily.$NEW -r $DEST_PATH/.timestamp

	fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [ -d $DEST_PATH/daily.0 ] ; then

	echo "  Copying hardlinks from $DEST_PATH/daily.0 to $DEST_PATH/daily.1"

	cp -al $DEST_PATH/daily.0 $DEST_PATH/daily.1
fi

echo "Finished rotating snapshots ..."

if ! [ -d $DEST_PATH/daily.0 ] ; then
	mkdir -p $DEST_PATH/daily.0
fi

# Set today's date on the current backup folder
touch $DEST_PATH/daily.0

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' \
      $SOURCE_PATH/ $DEST_PATH/daily.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
if ! [ $? = 24 -o $? = 0 ] ; then
	echo "Fatal: Node-RED daily backup finished with errors!"
    mosquitto_pub -r -t services/nrmainbackup/daily/fail -m $ENDDATE
else
    echo "Finished Node-RED daily backup, no errors."
    mosquitto_pub -r -t services/nrmainbackup/daily/success -m $ENDDATE
fi

# Sync disks to make sure data is written to disk
sync

#EOF

Some things you might want to do differently:

  • This version is set up to work with my alternate installer and assumes that you are running Node-RED with a user account. The folder containing node-red is ~/nrmain, the userDir folder is ~/nrmain/data. You might want to adjust paths.
  • Have more than 7d of backups. Maybe a second script that rotates monthly.

And as a bonus, here is the monthly script that I'm using:

#! /usr/bin/env bash

# Monthly backup for node-red

# Redirect stdout to syslog - show with: `sudo journalctl -t nrmain-backup`
exec 1> >(logger -t nrmain-backup -p local0.info)
# redirect stderr to syslog
exec 2> >(logger -t nrmain-backup -p local0.err)

# --- SET THESE TO THE CORRECT LOCATIONS --- #
SOURCE_PATH=/home/home/nrmain
DEST_PATH=/home/home/nrmain-backup
# ------------------------------------------ #

STARTDATE=$(date +'%Y-%m-%d %T')

echo " "
echo "Starting monthly backup of $SOURCE_PATH/ to $DEST_PATH/ ..."
echo "Rotating snapshots ..."

# Delete oldest daily backup
if [ -d $DEST_PATH/monthly.12 ] ; then
    echo "Deleting oldest monthly backup $DEST_PATH/monthly.12"

	rm -rf $DEST_PATH/monthly.12
fi

# Shift all other daily backups ahead one day
for OLD in 11 10 9 8 7 6 5 4 3 2 1	; do
	if [ -d $DEST_PATH/monthly.$OLD ] ; then
		NEW=$(($OLD+1))

		echo "Moving $DEST_PATH/monthly.$OLD to $DEST_PATH/monthly.$NEW"
		
		# Backup last date
		# ISSUE: touch does not support options on synology (busybox) system
		touch $DEST_PATH/.timestamp -r $DEST_PATH/monthly.$OLD
		mv $DEST_PATH/monthly.$OLD $DEST_PATH/monthly.$NEW
		# Restore timestamp
		touch $DEST_PATH/monthly.$NEW -r $DEST_PATH/.timestamp

	fi
done

# Copy hardlinked snapshot of level 0 to level 1 (before updating 0 via rsync)
if [ -d $DEST_PATH/monthly.0 ] ; then

	echo "Copying hardlinks from $DEST_PATH/monthly.0 to $DEST_PATH/monthly.1"

	cp -al $DEST_PATH/monthly.0 $DEST_PATH/monthly.1
fi

echo "Finished rotating snapshots ..."

if ! [ -d $DEST_PATH/monthly.0 ] ; then
	mkdir -p $DEST_PATH/monthly.0
fi

# Set today's date on the current backup folder
touch $DEST_PATH/monthly.0

ENDDATE=$(date --iso-8601=s)

# Back up
echo "Performing rsync backup ..."
rsync --archive --hard-links --delete --delete-excluded \
      --exclude 'node_modules' --exclude 'data/node_modules' \
      $SOURCE_PATH/ $DEST_PATH/monthly.0

# Validate return code
# 0 = no error,
# 24 is fine, happens when files are being touched during sync (logs etc)
# all other codes are fatal -- see man (1) rsync
if ! [ $? = 24 -o $? = 0 ] ; then
	echo "Fatal: Node-RED monthly backup finished with errors!"
    #curl --insecure -I 'https://localhost:1880/nrnotify'
    mosquitto_pub -r -t services/nrmainbackup/monthly/fail -m $ENDDATE
else
    echo "Finished Node-RED monthly backup, no errors."
    #curl --insecure -I 'https://localhost:1880/nrnotify'
    mosquitto_pub -r -t services/nrmainbackup/monthly/success -m $ENDDATE
fi

# Sync disks to make sure data is written to disk
sync

#EOF
2 Likes

Hi all, just updated the above backup script with some corrections. Also added the monthly script.