Backup volumes from host instead of copying paths

* Backupbot will now copy all volumes from a service with
  backupbot.enabled = 'true' label from the /var/lib/docker/volumes/
  path directly. This reduces the resource overhead of copying
  stuff from one volume to another.
  Recipes need to be adjustet that db-dumps are saved into a volume
  now!
* Remove the Dockerfile and move stuff into a entrypoint. This
  simplifies the whole versioning thing and makes this "just"
  a recipe

Co-authored-by: Moritz < moritz.m@local-it.org>
This commit is contained in:
2023-05-30 14:37:42 +02:00
parent 27e2e61d7f
commit 24d2c0e85b
7 changed files with 47 additions and 75 deletions

View File

@ -1,12 +1,14 @@
#!/bin/bash
set -e
server_name="${SERVER_NAME:?SERVER_NAME not set}"
restic_password_file="${RESTIC_PASSWORD_FILE:?RESTIC_PASSWORD_FILE not set}"
restic_host="${RESTIC_HOST:?RESTIC_HOST not set}"
backup_path="${BACKUP_DEST:?BACKUP_DEST not set}"
backup_paths=()
# shellcheck disable=SC2153
ssh_key_file="${SSH_KEY_FILE}"
@ -71,8 +73,8 @@ else
mapfile -t services < <(docker service ls --format '{{ .Name }}')
fi
post_commands=()
if [[ \ $*\ != *\ --skip-backup\ * ]]; then
rm -rf "${backup_path}"
for service in "${services[@]}"; do
echo "service: $service"
@ -80,36 +82,21 @@ if [[ \ $*\ != *\ --skip-backup\ * ]]; then
if echo "$details" | jq -r '.["backupbot.backup"]' | grep -q 'true'; then
pre=$(echo "$details" | jq -r '.["backupbot.backup.pre-hook"]')
post=$(echo "$details" | jq -r '.["backupbot.backup.post-hook"]')
path=$(echo "$details" | jq -r '.["backupbot.backup.path"]')
if [ "$path" = "null" ]; then
echo "ERROR: missing 'path' for $service"
continue # or maybe exit?
fi
container=$(docker container ls -f "name=$service" --format '{{ .ID }}')
echo "backing up $service"
stack_name=$(echo "$details" | jq -r '.["com.docker.stack.namespace"]')
if [ "$pre" != "null" ]; then
# run the precommand
# shellcheck disable=SC2086
echo "executing precommand $pre in container $container"
docker exec "$container" sh -c "$pre"
fi
# run the backup
for p in ${path//,/ }; do
# creates the parent folder, so `docker cp` has reliable behaviour no matter if $p ends with `/` or `/.`
dir=$backup_path/$service/$(dirname "$p")
test -d "$dir" || mkdir -p "$dir"
docker cp -a "$container:$p" "$dir/$(basename "$p")"
done
if [ "$post" != "null" ]; then
# run the postcommand
# shellcheck disable=SC2086
docker exec "$container" sh -c "$post"
# append post command
post_commands+=("docker exec $container sh -c \"$post\"")
fi
# add volume paths to backup path
backup_paths+=(/var/lib/docker/volumes/${stack_name}_*)
fi
done
@ -121,10 +108,11 @@ if [[ \ $*\ != *\ --skip-backup\ * ]]; then
fi
if [[ \ $*\ != *\ --skip-upload\ * ]]; then
_restic backup --host "$server_name" --tag coop-cloud "$backup_path"
if [ "$REMOVE_BACKUP_VOLUME_AFTER_UPLOAD" -eq 1 ]; then
echo "Cleaning up ${backup_path}"
rm -rf "${backup_path}"
fi
_restic backup --host "$server_name" --tag coop-cloud "${backup_paths[@]}"
fi
# run post commands
for post in "${post_commands[@]}"; do
echo "executing postcommand $post"
eval "$post"
done