Script to AutoBackup TrueNAS config

drakz_au

Cadet
Joined
Mar 14, 2023
Messages
1
After searching for a solution to automatically backup the TrueNAS config file I have created this script.

This is not my original work, it is heavily edited from the information posted in this thread by users 'NasKar' and 'engedics'.

Run this script as a CRON job to backup your config as often as you like. It even deletes old backups (if configured to).

There are 5 user configurable variables that you need to set before you run the script.

This definitely works on SCALE, not sure if it works on CORE.

And it's only just occurred to me that there should be no reason that it needs to even be run on the TrueNAS server, it should be able to be run on a remote server (that has access to the TrueNAS server obviously). In that case the "backuploc" variable would be a directory on the server running the script.


Code:
# Script to backup TrueNAS SCALE configuration file
# WARNING: DOES NOT CHECK IF A VALID BACKUP IS ACTUALLY CREATED
#
#
# Thanks to 'NasKar' and 'engedics' from this thread: https://www.truenas.com/community/threads/best-way-to-get-auto-config-backup.94537/
#
#
# If a valid backup file is not created then there is something wrong with the API call
# Check that your URL and API Key are both correct
#


# # # # # # # # # # # # # # # #
# USER CONFIGURABLE VARIABLES #
# # # # # # # # # # # # # # # #


# Server IP or URL (include http(s)://)
serverURL="https://<SERVER IP OR URL>"

# TrueNAS API key (Generate from 'User Icon' -> 'API Keys' in TrueNAS WebGUI)
apiKey="<API KEY>"

# Include Secret Seed (true| false)
secSeed=true

# Path on server to store backups
backuploc="<PATH TO STORE BACKUPS>"

# Max number of backups to keep (set as 0 to never delete anything)
maxnrOfFiles=5


# # # # # # # # # # # # # # # # # #
# END USER CONFIGURABLE VARIABLES #
# # # # # # # # # # # # # # # # # #


echo
echo "Backing up current TrueNAS config"

# Check current TrueNAS version number
versiondir=`cat /etc/version | cut -d' ' -f1`

# Set directory for backups to: 'path on server' / 'current version number'
backupMainDir="${backuploc}/${versiondir}"

# Create directory for for backups (Location/Version)
mkdir -p $backupMainDir


# Use appropriate extention if we are exporting the secret seed
if [ $secSeed = true ]
then
    fileExt="tar"
    echo "Secret Seed will be included"
else
    fileExt="db"
    echo "Secret Seed will NOT be included"
fi
    
# Generate file name
fileName=$(hostname)-TrueNAS-$(date +%Y%m%d%H%M%S).$fileExt


# API call to backup config and include secret seed
curl --no-progress-meter \
-X 'POST' \
$serverURL'/api/v2.0/config/save' \
-H 'Authorization: Bearer '$apiKey \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{"secretseed": '$secSeed'}' \
--output $backupMainDir/$fileName

echo
echo "Config saved to ${backupMainDir}/${fileName}"

#
# The next section checks for and deletes old backups
#
# Will not run if $maxnrOfFiles is set to zero (0)
#

if [ ${maxnrOfFiles} -ne 0 ]
then
    echo
    echo "Checking for old backups to delete"
    echo "Number of files to keep: ${maxnrOfFiles}"

    # Get number of files in the backup directory
    nrOfFiles="$(ls -l ${backupMainDir} | grep -c "^-.*")"

    echo "Current number of files: ${nrOfFiles}"

    # Only do something if the current number of files is greater than $maxnrOfFiles
     if [ ${maxnrOfFiles} -lt ${nrOfFiles} ]
     then
         nFileToRemove="$((nrOfFiles - maxnrOfFiles))"
         echo "Removing ${nFileToRemove} file(s)"
          while [ $nFileToRemove -gt 0 ]
          do
             fileToRemove="$(ls -t ${backupMainDir} | tail -1)"
             echo "Removing file ${fileToRemove}"
             nFileToRemove="$((nFileToRemove - 1))"
             rm ${backupMainDir}/${fileToRemove}
             done
         fi
# Inform the user that no files will be deleded if $maxnrOfFiles is set to zero (0)
else
    echo
    echo "NOT deleting old backups because '\$maxnrOfFiles' is set to 0"
fi

#All Done

echo
echo "DONE!"
echo
 

cmplieger

Dabbler
Joined
Aug 6, 2023
Messages
11
Thanks for this, it works great! Using it on a remote server to copy the config file daily.
 

NasKar

Guru
Joined
Jan 8, 2016
Messages
739
I created a windows share on the backup location and use syncback free to copy the config to my windows computer as a backup.
 

sfatula

Guru
Joined
Jul 5, 2022
Messages
608
AFAIK, /var/db/system/configs*/ contains a daily backup of your configs at 3:45AM. I just back the files there up (after 3:45AM).
 

holofrog

Cadet
Joined
Dec 28, 2022
Messages
3
In case you already have an off-site (or cloud) replication of one of your datasets, you can just use this one-liner script in a cron job (set the user to root):

tar -cf /mnt/pool1/path/to/dataset/truenas-config-$(cat /etc/version | cut -d' ' -f1)-$(date +%Y%m%d%H%M%S).tar -C /data freenas-v1.db pwenc_secret
 

liteswap

Dabbler
Joined
Jun 7, 2011
Messages
37
I've taken the liberty of adding a couple of features to this excellent script (thank you @drakz_au):

1. I've added a compare process so that the config file isn't saved if it's identical to the previous one
2. I've added an off-server copy operation so, especially for single server situations, the config is immediately copied somewhere else.
3. Also tidied up, slightly, the config file name to make it a bit more human-readable :)

Code:
# Script to backup TrueNAS SCALE configuration file
# WARNING: DOES NOT CHECK IF A VALID BACKUP IS ACTUALLY CREATED
#
#
# Thanks to 'NasKar' and 'engedics' from this thread: https://www.truenas.com/community/threads/best-way-to-get-auto-config-backup.94537/
#
#
# If a valid backup file is not created then there is something wrong with the API call
# Check that your URL and API Key are both correct
#

# # # # # # # # # # # # # # # #
# USER CONFIGURABLE VARIABLES #
# # # # # # # # # # # # # # # #

# Server IP or URL (include http(s)://)
serverURL="https://<SERVER IP OR URL>"

# TrueNAS API key (Generate from 'User Icon' -> 'API Keys' in TrueNAS WebGUI)
apiKey="<API KEY>"

# Include Secret Seed (true| false)
secSeed=true

# Path on server to store backups
backuploc="<PATH TO STORE BACKUPS>"

# Max number of backups to keep (set as 0 to never delete anything)
maxnrOfFiles=5

# # # # # # # # # # # # # # # # # #
# END USER CONFIGURABLE VARIABLES #
# # # # # # # # # # # # # # # # # #

echo
echo "Backing up current TrueNAS config"

# Check current TrueNAS version number
versiondir=`cat /etc/version | cut -d' ' -f1`

# Set directory for backups to: 'path on server' / 'current version number'
backupMainDir="${backuploc}/${versiondir}"

# Create directory for for backups (Location/Version)
mkdir -p $backupMainDir

# Use appropriate extension if we are exporting the secret seed
if [ $secSeed = true ]
then
    fileExt="tar"
    echo "Secret Seed will be included"
else
    fileExt="db"
    echo "Secret Seed will NOT be included"
fi
   
# Generate file name
fileName=$(hostname)-config-$(date +%Y%m%d-%H%M%S).$fileExt

# API call to backup config and include secret seed
curl --no-progress-meter \
-X 'POST' \
$serverURL'/api/v2.0/config/save' \
-H 'Authorization: Bearer '$apiKey \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{"secretseed": '$secSeed'}' \
--output $backupMainDir/$fileName

#### NEW SECTION 1 STARTS ####
# compare new file to old file, delete new if identical to last one
cmpFile="$( ls -t ${backupMainDir} | tail -1 )"
if cmp $fileName $cmpFile ; then
  echo deleting "${backupMainDir}/${fileName}"
  rm $backupMainDir/$fileName
  echo "Config has not changed, no action taken. Quitting"
  exit
fi
#
#### NEW SECTION 1 ENDS ####

echo
echo "Config saved to ${backupMainDir}/${fileName}"

#### NEW SECTION 2 STARTS ####
# This copies the config file off the server and onto fastmail files
curl -T ${backupMainDir}/${fileName} -u <off-site-server-credentials> <off-site-server-address>
echo
echo "Config copied to <off-site server>."
#### NEW SECTION 2 ENDS ####
#
# The next section checks for and deletes old backups
#
# Will not run if $maxnrOfFiles is set to zero (0)
#

if [ ${maxnrOfFiles} -ne 0 ]
then
    echo
    echo "Checking for old backups to delete"
    echo "Number of files to keep: ${maxnrOfFiles}"

    # Get number of files in the backup directory
    nrOfFiles="$(ls -l ${backupMainDir} | grep -c "^-.*")"

    echo "Current number of files: ${nrOfFiles}"

    # Only do something if the current number of files is greater than $maxnrOfFiles
     if [ ${maxnrOfFiles} -lt ${nrOfFiles} ]
     then
         nFileToRemove="$((nrOfFiles - maxnrOfFiles))"
         echo "Removing ${nFileToRemove} file(s)"
          while [ $nFileToRemove -gt 0 ]
          do
             fileToRemove="$(ls -t ${backupMainDir} | tail -1)"
             echo "Removing file ${fileToRemove}"
             nFileToRemove="$((nFileToRemove - 1))"
             rm ${backupMainDir}/${fileToRemove}
             done
         fi
# Inform the user that no files will be deleted if $maxnrOfFiles is set to zero (0)
else
    echo
    echo "NOT deleting old backups because '\$maxnrOfFiles' is set to 0"
fi

#All Done

echo
echo "DONE!"
echo
 
Top