Skip to content

Commit

Permalink
Merge pull request #36 from djmaze/add-prune
Browse files Browse the repository at this point in the history
Add prune support using a separate service and cron schedule
  • Loading branch information
djmaze committed Jun 3, 2020
2 parents 9bff1bf + e52310e commit 630d1d2
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 7 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ RUN apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/co
ENV RESTIC_REPOSITORY /mnt/restic

COPY --from=builder /usr/local/bin/* /usr/local/bin/
COPY backup /usr/local/bin/
COPY backup prune /usr/local/bin/
COPY entrypoint /

ENTRYPOINT ["/entrypoint"]
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,16 @@ Run automatic [restic](https://restic.github.io/) backups via a Docker container
* backup to any (local or remote) target supported by restic
* add custom tags to backups
* automatic forgetting of old backups
* prune backups on a schedule
* can be used as a (global) Docker swarm service in order to backup every cluster node
* multi-arch: the image `mazzolino/restic` runs on `amd64` as well as `armv7` (for now)

## Usage

Use the supplied example configs to set up a backup schedule.

The Compose files contain a *backup* and a *prune* service which can be scheduled independently of each other. Feel free to remove the *prune* service if you want to run the prune jobs manually.

### With Docker Compose

Adjust the supplied [docker-compose.yml](docker-compose.example.yml) as needed. Then run:
Expand Down Expand Up @@ -57,7 +60,10 @@ E.g.

## Configuration options

* `BACKUP_CRON` - A cron expression for when to run the backup. E.g. `0 30 3 * * *` in order to run every night at 3:30 am. See [the go-cron documentation](https://godoc.org/github.com/robfig/cron) for details on the expression format
*Note: `BACKUP_CRON` and `PRUNE_CRON` are mutually exclusive.*

* `BACKUP_CRON`- A cron expression for when to run the backup. E.g. `0 30 3 * * *` in order to run every night at 3:30 am. See [the go-cron documentation](https://godoc.org/github.com/robfig/cron) for details on the expression format
* `PRUNE_CRON` - A cron expression for when to run the prune job. E.g. `0 0 4 * * *` in order to run every night at 4:00 am. See [the go-cron documentation](https://godoc.org/github.com/robfig/cron) for details on the expression format
* `RESTIC_REPOSITORY` - location of the restic repository. You can use [any target supported by restic](https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html). Default `/mnt/restic`
* `RESTIC_BACKUP_SOURCES` - source directory to backup. Make sure to mount this into the container as a volume (see the example configs). Default `/data`
* `RESTIC_PASSWORD` - password for the restic repository. Will also be used to initialize the repository if it is not yet initialized
Expand Down
13 changes: 12 additions & 1 deletion docker-compose.example.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.3"

services:
app:
backup:
image: mazzolino/restic
hostname: docker
environment:
Expand All @@ -16,3 +16,14 @@ services:
TZ: Europe/Berlin
volumes:
- /var/lib/docker/volumes:/mnt/volumes:ro

prune:
image: mazzolino/restic
hostname: docker
environment:
PRUNE_CRON: "0 0 4 * * *"
RESTIC_REPOSITORY: b2:my-repo:/restic
RESTIC_PASSWORD: supersecret
B2_ACCOUNT_ID: xxxxxxx
B2_ACCOUNT_KEY: yyyyyyyy
TZ: Europe/Berlin
13 changes: 12 additions & 1 deletion docker-swarm.example.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: "3.3"

services:
app:
backup:
image: mazzolino/restic
environment:
BACKUP_CRON: "0 30 3 * * *"
Expand All @@ -18,3 +18,14 @@ services:
- /var/lib/docker/volumes:/mnt/volumes:ro
deploy:
mode: global

prune:
image: mazzolino/restic
hostname: docker
environment:
PRUNE_CRON: "0 0 4 * * *"
RESTIC_REPOSITORY: b2:my-repo:/restic
RESTIC_PASSWORD: supersecret
B2_ACCOUNT_ID: xxxxxxx
B2_ACCOUNT_KEY: yyyyyyyy
TZ: Europe/Berlin
13 changes: 10 additions & 3 deletions entrypoint
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/bin/sh
#!/bin/bash
set -euo pipefail

if [ -z "${RESTIC_REPOSITORY##*:*}" ]; then
echo "Trying to initialize remote repository '${RESTIC_REPOSITORY}' (in case it has not been initialized yet)"
restic init
restic init || true
elif [ ! -f "$RESTIC_REPOSITORY/config" ]; then
echo "Restic repository '${RESTIC_REPOSITORY}' does not exist. Running restic init"
restic init
Expand All @@ -11,6 +12,12 @@ fi
if [[ $# -gt 0 ]]; then
exec restic "$@"
else
exec go-cron "$BACKUP_CRON" /usr/local/bin/backup
if [[ -n "${BACKUP_CRON:-}" ]]; then
exec go-cron "$BACKUP_CRON" /usr/local/bin/backup
fi
if [[ -n "${PRUNE_CRON:-}" ]]; then
exec go-cron "$PRUNE_CRON" /usr/local/bin/prune
fi
>&2 echo "No valid operating mode configured! Exiting."
fi

39 changes: 39 additions & 0 deletions prune
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash
set -euo pipefail

function run_commands {
COMMANDS=$1
while IFS= read -r cmd; do echo $cmd && eval $cmd ; done < <(printf '%s\n' "$COMMANDS")
}

function run_exit_commands {
set +e
set +o pipefail
run_commands "${POST_COMMANDS_EXIT:-}"
}

main() {
run_commands "${PRE_COMMANDS:-}"

start=$(date +%s)
echo Starting prune at "$(date +"%Y-%m-%d %H:%M:%S")"

set +e
if ! restic prune "${RESTIC_REPOSITORY}"; then
set -e
run_commands "${POST_COMMANDS_FAILURE:-}"
exit
else
set -e
fi

echo Prune successful

end="$(date +%s)"
echo Finished prune at "$(date +"%Y-%m-%d %H:%M:%S")" after $((end-start)) seconds

run_commands "${POST_COMMANDS_SUCCESS:-}"
}

trap run_exit_commands EXIT
main "$@"

0 comments on commit 630d1d2

Please sign in to comment.