Skip to content

Instantly share code, notes, and snippets.

@pldmgg
Created February 16, 2020 23:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pldmgg/422befa6a3a2c6a97c281a941dcf381f to your computer and use it in GitHub Desktop.
Save pldmgg/422befa6a3a2c6a97c281a941dcf381f to your computer and use it in GitHub Desktop.
backup_docker_containers.sh
#!/bin/bash
# Reference: https://github.com/tlaanemaa/backup-docker
# Reference for starting addons via comd line: https://www.reddit.com/r/homeassistant/comments/an8lsl/how_do_you_issue_hassio_cli_commands_in_a/
#
# Installation of Prerequisites
# sudo apt-get install npm
# sudo npm install -g backup-docker
# sudo apt-get install powershell
# cd ~
# wget https://dl.google.com/go/go1.13.8.linux-amd64.tar.gz
# sudo tar -C /usr/local -xzf go1.13.8.linux-amd64.tar.gz
# export PATH=$PATH:/usr/local/go/bin
# go get -d github.com/home-assistant/cli
# cd go/src/github.com/home-assistant/cli/
# go install
# cd ~
if (( $EUID != 0 )); then
echo "Please run as root! Halting!"
exit 1
fi
if ! [ -x "$(command -v backup-docker)" ]; then
echo 'Error: backup-docker npm package is not installed! Halting!' >&2
exit 1
fi
if ! [ -x "$(command -v pwsh)" ]; then
echo 'Error: pwsh is not installed! Halting!' >&2
exit 1
fi
if ! [ -f "$HOME/go/bin/cli" ]; then
echo 'Error: The home assistant cli (https://github.com/home-assistant/cli) is not installed! Halting!' >&2
exit 1
fi
#backupdir='/mnt/WDElements575/ldfam_share/docker_backups'
backupdir=$1
if [ ! -d $backupdir ]; then
echo 'Error: The backup directory does not exist! Halting!' >&2
exit 1
fi
backupcontainersdir="${backupdir}/containers"
backupvolumesdir="${backupdir}/volumes"
backuptarfile="${backupvolumesdir}/usr_share_hassio.tar"
backupdockercmdstringpath="${backupvolumesdir}/ha_docker_cmd_string.txt"
backupdockerhaaddonspath="${backupvolumesdir}/ha_docker_addon_string_arrray.txt"
hassiosupervisorip=$(docker inspect hassio_supervisor | grep "IPv4Address" | awk '{print $2}' | sed 's/"//g')
# Add the hassio_supervisor container IP Address to /etc/hosts if it isn't in there already
linetoadd="${hassiosupervisorip} hassio_supervisor"
grep -qxF "${linetoadd}" /etc/hosts || sudo bash -c "echo '${linetoadd}' >> /etc/hosts"
# Set the variable $HASSIO_TOKEN to interact with the hassio_supervisor API
export $(docker inspect homeassistant | sed -n 's/^[ \t]*//;/"HASSIO_TOKEN=/{s/[",]//g; p; }')
#~/go/bin/cli info --endpoint "http://hassio_supervisor/" --api-token $HASSIO_TOKEN
#~/go/bin/cli addons start core_ssh --endpoint "http://hassio_supervisor/" --api-token $HASSIO_TOKEN
if [ -z "$HASSIO_TOKEN" ]; then
echo 'Error: Unable to determine HASSIO_TOKEN! Halting!' >&2
exit 1
fi
# Get the docker command used to start the homeassistant container
# haenvvars=$(docker inspect -f '{{ .Config.Env}}' homeassistant)
haenvvars=$(docker inspect -f '{{ .Config.Env}}' homeassistant)
if [ -z "$haenvvars" ]; then
echo 'Error: Unable to determine homeassistant container environment variables! Halting!' >&2
exit 1
fi
envvarsstring=$(pwsh -Command "(('${haenvvars}' -replace '^\[',' ') -replace '\]','') -replace '[\s]',' -e '")
dockercmdstring="docker run --init -d --name="homeassistant"${envvarsstring} -v /usr/share/hassio/homeassistant:/config --net=host homeassistant/qemux86-64-homeassistant:0.105.4"
addonslugsarray=($(docker ps -a --format '{{.Names}}' | grep "addon"))
if [ -z "$addonslugsarray" ]; then
echo 'Error: Unable to determine the names of any home assistant addon containers! Halting!' >&2
exit 1
fi
# Don't backup homeassistant, hassio_dns, hassio_supervisor containers, or addon containers because systemctl services
# hassio-supervisor.service and hassio-apparmor.service take care of setting up these when they restart
#backup-docker backup -d /mnt/WDElements575/ldfam_share/docker_backups --non-persistent-volumes
backup-docker backup $(docker ps -a --format '{{.Names}}' | grep -v "homeassistant" | grep -v "hassio_dns" | grep -v "hassio_supervisor" | grep -v "addon" | tr '\n' ' ') -d $backupdir
# Save the homeassistant container docker command string to a file under volumes
echo $dockercmdstring > $backupdockercmdstringpath
# Save the array of addon slugs to a file under volumes
for i in "${addonslugsarray[@]}"; do slug="${i//addon_/}"; echo $slug >> "${backupdockerhaaddonspath}"; done
# Now we have /mnt/WDElements575/ldfam_share/docker_backups/containers and /mnt/WDElements575/ldfam_share/docker_backups/volumes, which
# are backups of all containers NOT related to Home Assistant
# Now we need to actually backup Home Assistant.
# Before we can tar the /usr/share/hassio directory, we need to make sure all containers are stopped
sudo systemctl stop hassio-supervisor.service
sudo systemctl stop hassio-apparmor.service
# Stop all containers just in case...
docker stop $(docker ps -a -q)
# Create archive of /usr/share/hassio and place it in the volumes folder
cd /usr/share/hassio && sudo tar cvf $backuptarfile * && cd ~
# Next, place the containers and volumes folders into a folder that has todays current datetime
now=$(date +'%H%M%S_%m%d%Y')
newbackupdir="${backupdir}/docker_backup_${now}"
if [ ! -d $newbackupdir ]; then
mkdir $newbackupdir
fi
mv $backupcontainersdir $newbackupdir
mv $backupvolumesdir $newbackupdir
# Now we need to explictly remove homeassistant, hassio_dns, hassio_supervisor, and the addon containers
#docker rm homeassistant hassio_dns hassio_supervisor
#docker rm $(docker ps -a --format '{{.Names}}' | grep "addon" | tr '\n' ' ')
# Start the containers that have nothing to do with Home Assistant
docker start $(docker ps -a --format '{{.Names}}' | grep -v "homeassistant" | grep -v "hassio_dns" | grep -v "hassio_supervisor" | grep -v "addon" | tr '\n' ' ')
# Start the hassio systemctl services to start hassio_dns and hassio_supervisor
sudo systemctl start hassio-supervisor.service
sudo systemctl start hassio-apparmor.service
sleep 30
# Now hassio_dns and hassio_supervisor have been started
# Recreate the homeassistant container
#$dockercmdstring
# Start the home assistant docker container again
docker start homeassistant
# Wait for homeassistant
sleep 60
# Startup all of the addon containers
for i in "${addonslugsarray[@]}"; do slug="${i//addon_/}"; ~/go/bin/cli addons start $slug --endpoint "http://hassio_supervisor/" --api-token $HASSIO_TOKEN; done
docker ps -a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment