From 7d5123063035274aa1720225473a0b20e4520076 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sat, 12 Apr 2025 12:27:38 +0100 Subject: [PATCH] Add healthcheck --- Dockerfile | 5 +++++ README.md | 7 ++++++- docker-compose.yml | 5 ++++- src/backup.sh | 3 ++- src/healthcheck.sh | 17 +++++++++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) create mode 100755 src/healthcheck.sh diff --git a/Dockerfile b/Dockerfile index 0eeda07..e92d638 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,4 +14,9 @@ COPY src /src COPY config/ssh_config /etc/ssh/ COPY config/exclude.conf /exclude.conf + +# Add healthcheck to verify backup completed within allowed time +ENV MAX_BACKUP_AGE_SECONDS=86400 +HEALTHCHECK --interval=10s --timeout=10s --start-period=1h CMD /src/healthcheck.sh + ENTRYPOINT ["sh", "-c", "/src/schedule.sh"] diff --git a/README.md b/README.md index 7464505..87dfd8f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Create a snapshot of a [BTRFS](https://docs.kernel.org/filesystems/btrfs.html) v ## Background -Over the past year, this backup setup has enabled me to successfully restore all my data after incidents. This is all thanks to the excellent backup tool called BorgBackup. The scripts in this repository serve as an opinionated thin wrapper around it. The Docker image provided can be used directly in various self-hosting setups. It's designed to be a simple and effective tool for those looking to establish a reliable backup system, saving time and avoiding common pitfalls. +Over the past 2 years, this backup setup has enabled me to successfully restore all my data after incidents. This is all thanks to the excellent backup tool called BorgBackup. The scripts in this repository serve as an opinionated thin wrapper around it. The Docker image provided can be used directly in various self-hosting setups. It's designed to be a simple and effective tool for those looking to establish a reliable backup system, saving time and avoiding common pitfalls. ## Features @@ -19,6 +19,7 @@ Over the past year, this backup setup has enabled me to successfully restore all - **Scheduled Backups**: Automates backups according to a defined schedule. - **Log Rotation**: Maintains weekly logs of all backup activities. - **Multi-Repository Backups**: Allows backups to multiple BorgBackup repositories simultaneously. +- **Healtcheck**: The healthcheck is based on the time of the last successful backup. ### Multi-target backups @@ -65,6 +66,10 @@ Thus, the following sets of environment variables are valid for multi-target bac > This first back up to a remote repository, then to a local one +### Healthcheck + +When a backup succeeds, it writes down the success time to a file. The healthcheck compares the current time with the last backup's time and it reports healthy if the two are between `MAX_BACKUP_AGE_SECONDS` of each other. This value can be overriden. + ## Repository layout - src diff --git a/docker-compose.yml b/docker-compose.yml index da63e30..01e0090 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,10 @@ services: - KEEP_DAILY=6 # default: 6 - KEEP_WEEKLY=3 # default: 3 - KEEP_MONTHLY=48 # default: 48 - - KEEP_YEARLY=10 # default: 0 (!) + - KEEP_YEARLY=10 # default: 10 + + # Used for determining the health of the container + - MAX_BACKUP_AGE_SECONDS=86400 # default: 86400 (1d) volumes: - /volumes:/source:ro # we backup this folder (which is a BTRFS volume), we mustn't change it, so it's readonly - /volumes/backup:/snapshot # we must mount a path to a folder on the BTRFS disk for the snapshot to be put at, this is just a temporary path diff --git a/src/backup.sh b/src/backup.sh index 6039dae..eafb4e8 100755 --- a/src/backup.sh +++ b/src/backup.sh @@ -3,7 +3,7 @@ KEEP_DAILY=${KEEP_DAILY:-6} KEEP_WEEKLY=${KEEP_WEEKLY:-3} KEEP_MONTHLY=${KEEP_MONTHLY:-48} -KEEP_YEARLY=${KEEP_YEARLY:-0} +KEEP_YEARLY=${KEEP_YEARLY:-10} echo "Starting backup script at `date`" @@ -49,3 +49,4 @@ borg compact --threshold=5 --cleanup-commits --verbose --progress btrfs subvolume delete /snapshot/source echo "Finished backup script at `date`" +date > /backup_completion_time.log # this used by the healtcheck diff --git a/src/healthcheck.sh b/src/healthcheck.sh new file mode 100755 index 0000000..6912ad3 --- /dev/null +++ b/src/healthcheck.sh @@ -0,0 +1,17 @@ +#! /bin/sh + +set -e + +if [ -f /backup_completion_time.log ]; then + current_time=$(date +%s) + backup_time=$(date --file /backup_completion_time.log +%s) + age_in_seconds=$((current_time - backup_time)) + + if [ ${age_in_seconds} -lt ${MAX_BACKUP_AGE_SECONDS} ]; then + echo "Backup completed within the last ${MAX_BACKUP_AGE_SECONDS} seconds. Healthcheck passed." + exit 0 + fi +fi + +echo "Backup not completed within the last ${MAX_BACKUP_AGE_SECONDS} seconds. Healthcheck failed." +exit 1