🎉 First version!
This commit is contained in:
commit
c37a733313
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
services.conf
|
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@ -0,0 +1,15 @@
|
||||
FROM wernight/duplicity
|
||||
USER root
|
||||
|
||||
VOLUME /services
|
||||
|
||||
# Setup files
|
||||
COPY . /data
|
||||
WORKDIR /data
|
||||
|
||||
# Setup cronjob
|
||||
COPY crontab /etc/cron.d/backup-cron
|
||||
RUN chmod 0644 /etc/cron.d/backup-cron
|
||||
RUN crontab /etc/cron.d/backup-cron
|
||||
|
||||
CMD ["crond", "-f"]
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more information, please refer to <http://unlicense.org/>
|
20
backup.conf.example
Normal file
20
backup.conf.example
Normal file
@ -0,0 +1,20 @@
|
||||
## Backup config file for service. To find the syntax for this file,
|
||||
## take a look at `man duplicity` or the web docs at this url:
|
||||
## http://duplicity.nongnu.org/vers8/duplicity.1.html#sect9
|
||||
##
|
||||
## Special syntax has been added, a single pound sign line will be
|
||||
## interpreted like a variable assignment, a line with two pound
|
||||
## signs will be seen as comments.
|
||||
|
||||
|
||||
## This make daily backups, and keep them for one months, making
|
||||
## incremental backups and doing a full backup once a week.
|
||||
# RETAIN=1M
|
||||
# INCREMENT=1W
|
||||
# INTERVAL=1D
|
||||
|
||||
## The current directory (where this file is in) will get included,
|
||||
## but the subdirectory mnt will be excluded. (** matches the working
|
||||
## directory)
|
||||
+ **
|
||||
- **/mnt
|
140
backup.sh
Executable file
140
backup.sh
Executable file
@ -0,0 +1,140 @@
|
||||
#!/bin/sh
|
||||
|
||||
BASE="/services"
|
||||
SERVICES=$(ls $BASE)
|
||||
|
||||
echo "#### STARTING NEW BACKUP OF ALL SERVICES ####"
|
||||
echo ""
|
||||
echo " SERVICES IN TRACKER:"
|
||||
for SERVICE in $SERVICES; do
|
||||
echo " - ${SERVICE}"
|
||||
done
|
||||
echo ""
|
||||
echo " BACKUP STARTED ON $(date)"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
for SERVICE in $SERVICES; do
|
||||
LOCAL="$BASE/$SERVICE"
|
||||
|
||||
# Skip service if it doesn't have an backup config specified
|
||||
if [ ! -f "$LOCAL/backup.conf" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
RETAIN="1M"
|
||||
INCREMENT="1W"
|
||||
INTERVAL="1H"
|
||||
|
||||
# Read config for extra options
|
||||
while IFS='=' read -r key val; do
|
||||
[ "${key##\#\#*}" ] || continue # Skip if line starts with two hash signs
|
||||
[ ! "${key##\#*}" ] || continue # Skip if line doesn't start with a hash sign
|
||||
key="${key##\#}" # Strip the hash sign
|
||||
|
||||
# Key isn't escaped so the space after the hash sign gets consumed
|
||||
# by the assignment. This way the space is optional
|
||||
export $key="$val" 2>/dev/null ||
|
||||
printf ' warning %s is not a valid variable name\n' "$key"
|
||||
done < "$LOCAL/backup.conf"
|
||||
|
||||
echo "==== BACKING UP $SERVICE ===="
|
||||
echo ""
|
||||
echo " Retaining backups for $RETAIN"
|
||||
echo " Maxiumum incremental backup duration is $INCREMENT"
|
||||
echo " Running every $INTERVAL"
|
||||
echo ""
|
||||
|
||||
INTERVAL_INT=1
|
||||
case $INTERVAL in
|
||||
*M) INTERVAL_INT=$(( ${INTERVAL%%M} * 24 * 61 / 2 ));;
|
||||
*W) INTERVAL_INT=$(( ${INTERVAL%%W} * 24 * 7 ));;
|
||||
*D) INTERVAL_INT=$(( ${INTERVAL%%D} * 24 ));;
|
||||
*H) INTERVAL_INT=$(( ${INTERVAL%%H} ));;
|
||||
*) INTERVAL_INT=1;;
|
||||
esac
|
||||
|
||||
if [ $(( ( $(date +%s) / 3600 ) % $INTERVAL_INT )) -ne 0 ]; then
|
||||
echo "==== SKIPPING $SERVICE"
|
||||
echo " Service not yet scheduled for backup."
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
continue
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
while read REMOTE; do
|
||||
# Skip if line is empty
|
||||
[ -z "$REMOTE" ] && continue
|
||||
|
||||
REMOTE="$REMOTE/$SERVICE"
|
||||
TYPE=$(echo "$REMOTE" | cut -d \: -f 1)
|
||||
SERVER=$(echo "$REMOTE" | cut -d \: -f 3 | cut -d \@ -f 2 | cut -d \/ -f 1)
|
||||
|
||||
echo "==== USING REMOTE:"
|
||||
echo " $SERVER over $TYPE"
|
||||
echo ""
|
||||
|
||||
echo " > BACKUP"
|
||||
duplicity \
|
||||
--verbosity 2 \
|
||||
--no-encryption \
|
||||
--allow-source-mismatch \
|
||||
--full-if-older-than "$INCREMENT" \
|
||||
--include-filelist "$LOCAL/backup.conf" \
|
||||
"$LOCAL" "$REMOTE" \
|
||||
2>&1 | sed 's/^/ /'
|
||||
|
||||
echo " > DELETE OLD"
|
||||
duplicity \
|
||||
--verbosity 2 \
|
||||
remove-older-than "$RETAIN" \
|
||||
--no-encryption \
|
||||
--allow-source-mismatch \
|
||||
--include-filelist "$LOCAL/backup.conf" \
|
||||
--force \
|
||||
"$REMOTE" \
|
||||
2>&1 | sed 's/^/ /'
|
||||
|
||||
echo ""
|
||||
echo " > VERIFY"
|
||||
duplicity \
|
||||
verify \
|
||||
--verbosity 2 \
|
||||
--no-encryption \
|
||||
--allow-source-mismatch \
|
||||
--include-filelist "$LOCAL/backup.conf" \
|
||||
"$REMOTE" "$LOCAL" \
|
||||
2>&1 | sed 's/^/ /'
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo " [!] SOMETHING BAD HAPPENED"
|
||||
echo " Backups where made but don't check out. Is the remote's storage full?"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo ""
|
||||
done < "/data/services.conf"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
done
|
||||
|
||||
echo "#### BACKUP FINISHED ####"
|
||||
echo ""
|
||||
echo " ENDED ON $(date)"
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
1
crontab
Normal file
1
crontab
Normal file
@ -0,0 +1 @@
|
||||
10 * * * * /data/backup.sh 2>/proc/1/fd/2 >/proc/1/fd/1
|
10
docker-compose.yml
Normal file
10
docker-compose.yml
Normal file
@ -0,0 +1,10 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
backup:
|
||||
build: .
|
||||
volumes:
|
||||
- /services:/services
|
||||
- ./mnt/duplicity/.cache:/home/duplicity/.cache
|
||||
- ./mnt/duplicity/.gnupg:/home/duplicity/.gnupg
|
||||
restart: always
|
2
mnt/duplicity/.gitignore
vendored
Normal file
2
mnt/duplicity/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.cache/
|
||||
.gnupg/
|
72
readme.md
Normal file
72
readme.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Automatic service backup
|
||||
|
||||
This docker container will backup services on a schedule, using duplicity as an back end.
|
||||
|
||||
|
||||
## How to configure
|
||||
|
||||
To configure file hosting locations you can add storage locations to the `services.conf` file. One per line, you can add duplicity connections. The syntax of these can be found in [their docs](http://duplicity.nongnu.org/vers8/duplicity.1.html).
|
||||
|
||||
After changing the `services.conf` file, you'll have to rebuild the container.
|
||||
|
||||
The script sends logs to the docker log socket (as is usual with containers).
|
||||
|
||||
```
|
||||
docker-compose build
|
||||
docker-compose up -d
|
||||
docker-compose logs -f
|
||||
```
|
||||
|
||||
|
||||
## How to use
|
||||
|
||||
This docker container assumes that you use the following directory structure:
|
||||
|
||||
```
|
||||
some_folder/
|
||||
service1/
|
||||
backup.conf
|
||||
service2/
|
||||
backup.conf
|
||||
service3/
|
||||
```
|
||||
|
||||
By default, `some_folder` is mapped to `/services` as this is where my services reside. You can change this in the `docker-compose.yml` file.
|
||||
|
||||
If you put a `backup.conf` file into a service's directory it will get backed up. If you omit this file, the service will be skipped.
|
||||
|
||||
The contents of the backup file are a duplicity include list. You can find more documentation about them at [their docs](http://duplicity.nongnu.org/vers8/duplicity.1.html#sect9)
|
||||
|
||||
You can find an example file with some comments at `backup.conf.example`.
|
||||
|
||||
### Backup file syntax
|
||||
|
||||
Lines starting with `##` are comments.
|
||||
|
||||
Lines starting with `#` are interpreted as variable assignments. There are three variables used to control backup behaviour.
|
||||
|
||||
```
|
||||
## These are also the default values
|
||||
# RETAIN=1M
|
||||
# INCREMENT=1W
|
||||
# INTERVAL=1H
|
||||
```
|
||||
|
||||
`RETAIN` specifies how long backups should be kept around.
|
||||
`INCREMENT` specifies how long incremental backups are made before creating a full backup again. This will make a full backup every week.
|
||||
`INTERVAL` specifies how long between backups.
|
||||
|
||||
The `RETAIN` and `INCREMENT` variables are directly fed into duplicity and use their syntax. The `INTERVAL` variable is read by the container, and has the following options:
|
||||
|
||||
```
|
||||
1M for once each month
|
||||
1W for once each week
|
||||
1D for once each day
|
||||
1H for once each hour
|
||||
|
||||
2H for once each two hours
|
||||
6H for once each six hours
|
||||
12H for twice each day
|
||||
```
|
||||
|
||||
Values must be whole integers, and the minimal value possible is `1H`.
|
2
services.conf.example
Normal file
2
services.conf.example
Normal file
@ -0,0 +1,2 @@
|
||||
webdavs://nextcloudusername:nextcloudpassword@nextcloudhost/remote.php/webdav/path/to/folder
|
||||
b2://b2keyId:b2applicationKeyGenerateOneWithoutSlashesJustKeepTrying@b2BucketName/path/to/folder
|
Loading…
Reference in New Issue
Block a user