mirror of
https://github.com/napnap75/multiarch-docker-images.git
synced 2025-12-16 19:54:18 +01:00
104 lines
3.5 KiB
Bash
Executable File
104 lines
3.5 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Backup one directory
|
|
function backup_dir {
|
|
# Check if the dir to backup is mounted as a subdirectory of /root inside this container
|
|
if [ -d "/root_fs$1" ]; then
|
|
restic backup /root_fs$1
|
|
return $?
|
|
else
|
|
echo "[ERROR] Directory $1 not found. Have you mounted the root fs from your host with the following option : '-v /:/root_fs:ro' ?"
|
|
return -1
|
|
fi
|
|
}
|
|
|
|
# Backup one file
|
|
function backup_file {
|
|
cat $1 | restic backup --stdin --stdin-filename $2
|
|
return $?
|
|
}
|
|
|
|
# Firt, check the repository is unlocked and try to unlock it
|
|
if [ "$(restic --no-lock list locks -q)" != "" ]; then
|
|
echo "[INFO] Repository locked, trying to unlock"
|
|
restic unlock
|
|
if [ $? -ne 0 ]; then
|
|
echo "[ERROR] Could not unlock repository"
|
|
return -1
|
|
fi
|
|
fi
|
|
|
|
count_success=0
|
|
count_failure=0
|
|
|
|
# List all the containers
|
|
for container_id in $(docker ps -aq) ; do
|
|
container_json=$(docker inspect $container_id)
|
|
# Get the name and namespace (in case of a container run in a swarm stack)
|
|
container_name=$(echo $container_json | jq -r '.[].Name' | cut -d'/' -f2)
|
|
# namespace=$(echo $container | jq -r ".Labels | .[\"com.docker.stack.namespace\"]")
|
|
|
|
# Backup the dirs labelled with "napnap75.backup.dirs"
|
|
|
|
backup_dirs=$(echo $container_json | jq -r '.[].Config.Labels."napnap75.backup.dirs"')
|
|
if [ "$backup_dirs" != "null" ] ; then
|
|
for dir_name in $backup_dirs ; do
|
|
echo "[INFO] Backing up dir" $dir_name "for container" $container_name
|
|
backup_dir $dir_name
|
|
if [ $? -ne 0 ]; then
|
|
((++count_failure))
|
|
else
|
|
((++count_success))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Backup the volumes labelled with "napnap75.backup.volumes"
|
|
backup_volumes=$(echo $container_json | jq -r '.[].Config.Labels."napnap75.backup.volumes"')
|
|
if [ "$backup_volumes" != "null" ] ; then
|
|
for volume_name in $backup_volumes ; do
|
|
# if [ $namespace != "null" ] ; then volume_name="${namespace}_${volume_name}" ; fi
|
|
volume_mount=$(echo $container_json | jq -r ".[].Mounts[] | select(.Name==\"$volume_name\") | .Source")
|
|
echo "[INFO] Backing up volume" $volume_name "with mount" $volume_mount "for container" $container_name
|
|
backup_dir $volume_mount
|
|
if [ $? -ne 0 ]; then
|
|
((++count_failure))
|
|
else
|
|
((++count_success))
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Backup the databases labelled with "napnap75.backup.databases"
|
|
backup_databases=$(echo $container_json | jq -r '.[].Config.Labels."napnap75.backup.databases"')
|
|
if [ "$backup_databases" != "null" ] ; then
|
|
for database_name in $backup_databases ; do
|
|
echo "[INFO] Backing up database" $database_name "for container" $container_name
|
|
docker exec $container_id bash -c "mysqldump --databases $database_name | gzip -c > /tmp/database_backup.sql.gz"
|
|
if [ $? -ne 0 ]; then
|
|
echo "[ERROR] Unable to backup database $database_name from container $container_name"
|
|
((++count_failure))
|
|
else
|
|
container_overlay=$(echo $container_json | jq -r '.[].GraphDriver.Data.MergedDir')
|
|
backup_file /root_fs${container_overlay}/tmp/database_backup.sql.gz ${container_name}—${database_name}.sql.gz
|
|
if [ $? -ne 0 ]; then
|
|
((++count_failure))
|
|
else
|
|
((++count_success))
|
|
fi
|
|
fi
|
|
docker exec $container_id bash -c "rm /tmp/database_backup.sql.gz"
|
|
done
|
|
fi
|
|
done
|
|
|
|
# Send a notification to Slack
|
|
if [[ "$SLACK_URL" != "" ]] ; then
|
|
curl -s -X POST --data-urlencode "payload={\"username\": \"rpi-docker-backup\", \"icon_emoji\": \":dvd:\", \"text\": \"Backup finished on host $HOSTNAME : $count_success succeeded, $count_failure failed\"}" $SLACK_URL
|
|
fi
|
|
|
|
# Return a non zero exit code if an error happened
|
|
if [ $count_failure -ne 0 ]; then
|
|
exit -1
|
|
fi
|