Allow multiple schedules in the same container (#78)

* Allow mounting of config directory for multiple schedules

* Add docs for conf.d feature

* Fix behavior on multiple files

* Define default case first in entrypoint script
This commit is contained in:
Frederik Ring 2022-03-04 13:51:26 +01:00 committed by GitHub
parent 6e1b8553e6
commit c9ebb9e14e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 4 deletions

View File

@ -28,6 +28,7 @@ It handles __recurring or one-off backups of Docker volumes__ to a __local direc
- [Manually triggering a backup](#manually-triggering-a-backup) - [Manually triggering a backup](#manually-triggering-a-backup)
- [Update deprecated email configuration](#update-deprecated-email-configuration) - [Update deprecated email configuration](#update-deprecated-email-configuration)
- [Using a custom Docker host](#using-a-custom-docker-host) - [Using a custom Docker host](#using-a-custom-docker-host)
- [Run multiple backup schedules in the same container](#run-multiple-backup-schedules-in-the-same-container)
- [Recipes](#recipes) - [Recipes](#recipes)
- [Backing up to AWS S3](#backing-up-to-aws-s3) - [Backing up to AWS S3](#backing-up-to-aws-s3)
- [Backing up to Filebase](#backing-up-to-filebase) - [Backing up to Filebase](#backing-up-to-filebase)
@ -653,6 +654,32 @@ DOCKER_HOST=tcp://docker_socket_proxy:2375
In case you are using a socket proxy, it must support `GET` and `POST` requests to the `/containers` endpoint. If you are using Docker Swarm, it must also support the `/services` endpoint. If you are using pre/post backup commands, it must also support the `/exec` endpoint. In case you are using a socket proxy, it must support `GET` and `POST` requests to the `/containers` endpoint. If you are using Docker Swarm, it must also support the `/services` endpoint. If you are using pre/post backup commands, it must also support the `/exec` endpoint.
### Run multiple backup schedules in the same container
Multiple backup schedules with different configuration can be configured by mounting an arbitrary number of configuration files (using the `.env` format) into `/etc/dockervolumebackup/conf.d`:
```
version: '3'
services:
# ... define other services using the `data` volume here
backup:
image: offen/docker-volume-backup:latest
volumes:
- data:/backup/my-app-backup:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./configuration:/etc/dockervolumebackup/conf.d
volumes:
data:
```
A separate cronjob will be created for each config file.
If a configuration value is set both in the global environment as well as in the config file, the config file will take precedence.
The `backup` command expects to run on an exclusive lock, so it is your responsibility to make sure the invocations do not overlap.
In case you need your schedules to overlap, you need to create a dedicated container for each schedule instead.
When changing the configuration, you currently need to manually restart the container for the changes to take effect.
## Recipes ## Recipes
This section lists configuration for some real-world use cases that you can mix and match according to your needs. This section lists configuration for some real-world use cases that you can mix and match according to your needs.

View File

@ -5,10 +5,21 @@
set -e set -e
if [ ! -d "/etc/dockervolumebackup/conf.d" ]; then
BACKUP_CRON_EXPRESSION="${BACKUP_CRON_EXPRESSION:-@daily}" BACKUP_CRON_EXPRESSION="${BACKUP_CRON_EXPRESSION:-@daily}"
echo "Installing cron.d entry with expression $BACKUP_CRON_EXPRESSION." echo "Installing cron.d entry with expression $BACKUP_CRON_EXPRESSION."
echo "$BACKUP_CRON_EXPRESSION backup 2>&1" | crontab - echo "$BACKUP_CRON_EXPRESSION backup 2>&1" | crontab -
else
echo "/etc/dockervolumebackup/conf.d was found, using configuration files from this directory."
for file in /etc/dockervolumebackup/conf.d/*; do
source $file
BACKUP_CRON_EXPRESSION="${BACKUP_CRON_EXPRESSION:-@daily}"
echo "Appending cron.d entry with expression $BACKUP_CRON_EXPRESSION and configuration file $file"
(crontab -l; echo "$BACKUP_CRON_EXPRESSION /bin/sh -c 'set -a; source $file; set +a && backup' 2>&1") | crontab -
done
fi
echo "Starting cron in foreground." echo "Starting cron in foreground."
crond -f -l 8 crond -f -l 8

View File

@ -21,7 +21,7 @@ services:
volumes: volumes:
- webdav_backup_data:/var/lib/dav - webdav_backup_data:/var/lib/dav
backup: &default_backup_service backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary} image: offen/docker-volume-backup:${TEST_VERSION:-canary}
hostname: hostnametoken hostname: hostnametoken
depends_on: depends_on:

1
test/confd/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
local

2
test/confd/backup.env Normal file
View File

@ -0,0 +1,2 @@
BACKUP_FILENAME="conf.tar.gz"
BACKUP_CRON_EXPRESSION="*/1 * * * *"

View File

@ -0,0 +1,22 @@
version: '3'
services:
backup:
image: offen/docker-volume-backup:${TEST_VERSION:-canary}
restart: always
volumes:
- ./local:/archive
- app_data:/backup/app_data:ro
- ./backup.env:/etc/dockervolumebackup/conf.d/00backup.env
- ./never.env:/etc/dockervolumebackup/conf.d/10never.env
- /var/run/docker.sock:/var/run/docker.sock
offen:
image: offen/offen:latest
labels:
- docker-volume-backup.stop-during-backup=true
volumes:
- app_data:/var/opt/offen
volumes:
app_data:

2
test/confd/never.env Normal file
View File

@ -0,0 +1,2 @@
BACKUP_FILENAME="never.tar.gz"
BACKUP_CRON_EXPRESSION="0 0 5 31 2 ?"

26
test/confd/run.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/sh
set -e
cd $(dirname $0)
mkdir -p local
docker-compose up -d
# sleep until a backup is guaranteed to have happened on the 1 minute schedule
sleep 100
docker-compose down --volumes
if [ ! -f ./local/conf.tar.gz ]; then
echo "[TEST:FAIL] Config from file was not used."
exit 1
fi
echo "[TEST:PASS] Config from file was used."
if [ -f ./local/never.tar.gz ]; then
echo "[TEST:FAIL] Unexpected file was found."
exit 1
fi
echo "[TEST:PASS] Unexpected cron did not run."