Backing up Elasticsearch Daily using Elasticdump

I found the Elasticsearch snapshot functionality not very easy to use so once again fell back to using the npm package Elasticdump to complete my Daily Elasticsearch backups.

Note: This script relys on you creating new Elasticsearch indexes each day for your Elasticsearch data. See how to do that here.

For the purposes of this guide, I use the date format YYYY-MM-DD.

The backup script:

First – Ensure you have Elasticdump installed and configured on your server – See how to do this here.

#!/bin/bash

# Define Variables
date=$(date --date="yesterday" +%F)
bkpdir=/mnt/backup/"$date"/
bkp=/mnt/backup/full-server/elk-server-"$date".tar.gz
bkplog=/mnt/backup/full-server/elk-server-"$date".log
dirs="$bkpdir /scripts /root /application"

# Create log files and backup dir
mkdir $bkpdir
touch $bkplog

# Use Elasticdump to backup today's indexes (Excluding docker logs as example)
for index in $(curl -GET 'localhost:9200/_cat/indices/*?v&s=index' | grep "$date" | grep -v "docker-logs" | awk {'print $3'}); do
echo "Backing up $index" >> $bkplog
echo "elasticdump --input=http://localhost:9200/"$index" --output=$ | gzip > "$bkpdir""$index".json.gz"
echo "Index $index backed up" >> $bkplog
done

# Compress directories into zip
echo "## Zipping directories ##" >> $bkplog
tar -czvf $bkp $dirs >> $bkplog >> $bkplog
echo "## Zipping completed ##" >> $bkplog

The backup script will first use Elasticdump to export each of your indexes for yesterday (Explained below) before using tar to compress these and other system directories set in the dirs variable. My docker setup (Inc config files) is stored within /application, adjust this as required for your setup.

Once the script has run – You will have each index individually archived in gzip format in: /mnt/backup/”$date”/ (A new backup folder will be created each day for that day’s archies). You will also have a “full-server” backup in /mnt/backup/full-server/ – You can then expand this script to scp this full backup to another server.

The script should be scheduled in Crontab to run in the early hours of the morning (Not late in the evening) to ensure it backs up all Elasticsearch data from the previous day.

The Restore Process:

Note, this assumes that your ELK is configured to use the following directories:

/application/elk-stack/ (Docker repo with ELK config)
/mnt/elk-stack/elasticsearch-data/ (Elasticsearch directory)

The first stage in your restore process (Restoring all individual daily backups of the server) will be to transfer all of the backup files to your new ELK server.

My ELK instance runs on Docker so re-installing the application on the machine is as simple as installing docker and docker-compose (See here) and restoring the /application directory from my full-server backup and running docker-compose up.

As my ELK server contains a fair amount of data (Not huge by any means..) – I have added two 200GB disks onto the server I am restoring to – One to extract the archives on and one to restore the data to. These disks are mounted to /mnt/restore and /mnt/elk-stack (Self explanitory).

Once you have transferred all of your backup archives to /mnt/restore Eg by SCP if they are remote – The next stage will be to extract all of the archives to the same location (Run this in screen as it will take time to process!):

find /mnt/restore/ -name "*tar.gz" -exec tar -zxf {} -C /mnt/restore/ \;

This will extract all of your top level folders (Eg /application /root etc) to /mnt/restore and all of the daily backups from ELK will be extracted to /mnt/restore/mnt/backup/.

While these directories are extracting – Create the Elasticsearch data directory + Restore your ELK configuration / docker directory to /application from the backup and ensure docker + docker-compose are ready to go.

mkdir /mnt/elk-stack/elasticsearch-data/
chmod -R 777 /mnt/elk-stack/elasticsearch-data/
cp -r /mnt/restore/application /application
cd /application/elk-stack/
docker-compose up -d

Once the archives have all expanded into their individual archives – You must then extract each of the json archives (Again run this in screen as it will take time):

for archive in $(find /mnt/restore/mnt/backup/ -name "*.json.gz"); do gzip -d $archive; done

Finally – We can use Elasticdump to import the archives back into Elasticsearch. This will go through each of your backup indexes and import them into Elasticsearch (Run this in screen as well).

for backup in $(find /mnt/restore/mnt/backup/ -name "*.json"); do index=$(basename $backup | sed -e 's/.json//g'); echo elasticdump --bulk=true --input="$backup" --output=http://localhost:9200/$index ;done

Any comments or questions? Get in touch here or Email me at [email protected]