Skip to main content

Daily Backup Script

Create a backup script to run every night and backup:

  • MySQL database
  • /var/www/BookStack folder
  • Nginx configuration

TLDR; Skip to here for the script.

Create a master script

Due to the way I decided to implement logging for this script, I have to divide it in two. It is completely possible to have just one script, so adjust it to your liking. The script will be run as root, because it's writing to privileged directories. You are free to adjust permissions, directories, users etc.

RUN_bookstack_backup.sh

#!/bin/bash
LOG_DIR=/var/log/bookstack/backup_script
CURRENT_DATE=$(date +"%Y-%m-%d")

# Run bookstack_backup_worker.sh with root privileges, pipe it to gawk which puts timestamp before every line and writes to file
source ./bookstack_backup_worker.sh | gawk '{ print strftime("[%Y-%m-%d %H:%M:%S %Z]"), $0 }' > $LOG_DIR/bookstack-backup_$CURRENT_DATE.log
  • #!/bin/bash – The so called shebang', every bash script should start with one. Read more about it here.
  • LOG_DIR=/var/log/bookstack/backup_script – Creates a variable LOG_DIR specifying the location where to save logs. Simplifies scripts, so you don't have to type out long path multiple times.
  • CURRENT_DATE=$(date +"%Y-%m-%d") – Creates a variable CURRENT_DATE, which runs a command date with options +"%Y-%m-%d". This gives you a basic ISO date in YYYY-MM-DD format, separated with dashes. We will append this to the backup filenames.
  • source ./bookstack_backup_worker.sh – Run the backup script with source. Source runs the other script in a sub-shell and that allows us to share variables like CURRENT_DATE with the other script. The entire script is piped (|) to gawk.
  • gawk '{ print strftime("[%Y-%m-%d %H:%M:%S %Z]"), $0 }' – This is my timestamp logging solution. gawk takes the output of the entire bookstack_backup_worker.sh script and adds a timestamp at the beginning of every line. This timestamping solution is described in more detail in this guide. After gawk adds the timestamp, it sends it to a log file with >. The log file's path is specified using the LOG_DIR variable and has CURRENT_DATE inserted into its name. The entire path and filename then might look like this: /var/log/bookstack/backup_script/bookstack-backup_2021-09-04.log
  • To run this script, simply type sudo ./RUN_booktack_backup

bookstack_backup_worker.sh

#!/bin/bash
BOOKSTACK_DIR=/var/www/BookStack
NGINX_DIR=/etc/nginx
BACKUP_DIR=/var/backup/bookstack
DB_BACKUP_DIR=$BACKUP_DIR/db
WEBROOT_BACKUP_DIR=$BACKUP_DIR/files
NGINX_BACKUP_DIR=$BACKUP_DIR/nginx

exec 2>&1

# MYSQL DATABASE BACKUP
echo "Starting BACKUP SCRIPT..."
echo "Starting MySQL backup..."
echo "Backing up to $DB_BACKUP_DIR..."
mysqldump --defaults-extra-file=/root/.my.cnf -v -u bookstack-admin bookstack | gzip -vc > $DB_BACKUP_DIR/bookstackdb-backup_$CURRENT_DATE.sql.gz
echo "Done..."

# WEBSERVER BACKUP
# Archive and compress BookStack webroot folder and save it to backup location with current date
echo "Backing up BookStack webroot directory to $WEBROOT_BACKUP_DIR..."
tar -czvf $WEBROOT_BACKUP_DIR/bookstack-backup_$CURRENT_DATE.tar.gz $BOOKSTACK_DIR
echo "Done..."

# NGINX CONFIG BACKUP
# Archive and compress Nginx config folder and save it to backup location with current date
echo "Backing up Nginx to $NGINX_BACKUP_DIR..."
tar -czvf $NGINX_BACKUP_DIR/nginx-backup_$CURRENT_DATE.tar.gz $NGINX_DIR
echo "Done..."
echo "Finished..."