From 355951c02ab9d3d9b8ca13deb5a3d66a603d4ece Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Wed, 27 Nov 2019 22:39:05 +0100 Subject: [PATCH 1/9] Update changelog for v1.1.1 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e46437f..a780c77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [1.1.1](https://github.com/djmaze/resticker/tree/1.1.1) (2019-11-27) + +[Full Changelog](https://github.com/djmaze/resticker/compare/1.1.0...1.1.1) + +**Implemented enhancements:** + +- Restic 0.9.6 release [\#17](https://github.com/djmaze/resticker/issues/17) +- doco and samples for restore [\#15](https://github.com/djmaze/resticker/issues/15) + +**Fixed bugs:** + +- Use proper sh semantics for the entrypoint [\#18](https://github.com/djmaze/resticker/pull/18) ([schue](https://github.com/schue)) + ## [1.1.0](https://github.com/djmaze/resticker/tree/1.1.0) (2019-10-30) [Full Changelog](https://github.com/djmaze/resticker/compare/1.0.1...1.1.0) From 07ed27a46f8fbb2c07d2b874fbe6688e7caf2c6d Mon Sep 17 00:00:00 2001 From: panakour Date: Sat, 4 Jan 2020 16:39:19 +0200 Subject: [PATCH 2/9] update rclone to 1.50.2 --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 6d2b8cb..a9c3ae9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,8 @@ ARG RESTIC_VERSION=0.9.6 ARG RESTIC_SHA256=1cc8655fa99f06e787871a9f8b5ceec283c856fa341a5b38824a0ca89420b0fe ARG GO_CRON_VERSION=0.0.4 ARG GO_CRON_SHA256=6c8ac52637150e9c7ee88f43e29e158e96470a3aaa3fcf47fd33771a8a76d959 -ARG RCLONE_VERSION=1.49.5 -ARG RCLONE_SHA256=7922455f95e8e71f9e484f84ac3ae015379e65ccc3f7d93d804fc0a76515c973 +ARG RCLONE_VERSION=1.50.2 +ARG RCLONE_SHA256=2112883164f1f341b246a275936e7c3019d68135002098d84637839dec9526c8 RUN curl -sL -o go-cron.tar.gz https://github.com/djmaze/go-cron/archive/v${GO_CRON_VERSION}.tar.gz \ && echo "${GO_CRON_SHA256} go-cron.tar.gz" | sha256sum -c - \ From 3b1478583b8c7d81f272702b7dc69fd7e3268e11 Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Fri, 31 Jan 2020 23:27:09 +0100 Subject: [PATCH 3/9] Run arm builds on arm64 --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index b8fb88f..41238af 100644 --- a/.drone.yml +++ b/.drone.yml @@ -30,7 +30,7 @@ name: arm platform: os: linux - arch: arm + arch: arm64 steps: - name: build From 3c2a16381fb86cfa3280e1e5aa795080e544fefa Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Fri, 31 Jan 2020 23:28:17 +0100 Subject: [PATCH 4/9] Build & tag "latest" (master) version as well fixes #24 --- .drone.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.drone.yml b/.drone.yml index 41238af..1af9d09 100644 --- a/.drone.yml +++ b/.drone.yml @@ -17,9 +17,6 @@ steps: password: from_secret: docker_password when: - branch: - exclude: - - master event: exclude: - pull_request @@ -44,9 +41,6 @@ steps: password: from_secret: docker_password when: - branch: - exclude: - - master event: exclude: - pull_request @@ -71,9 +65,6 @@ steps: password: from_secret: docker_password when: - branch: - exclude: - - master event: exclude: - pull_request From 9bff1bf028a38a4ec024f80e5794929326b3281f Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Sun, 29 Mar 2020 22:24:34 +0200 Subject: [PATCH 5/9] Fix restore instructions in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3556556..746dc20 100644 --- a/README.md +++ b/README.md @@ -36,9 +36,9 @@ In order to restore files on a host where the container is already running via D ```bash # Find the latest snapshot for the current host (note the ID) -docker-compose exec app snapshots -H +docker-compose exec app restic snapshots -H # Restore the given file on the host -docker-compose exec app restore --include /path/to/file +docker-compose exec app restic restore --include /path/to/file ``` When using Swarm mode, you need to manually SSH into the host and run `docker exec -it ..` accordingly. From e52310e73d235b30127720a300be5d88a56bebb6 Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Mon, 1 Jun 2020 15:10:31 +0200 Subject: [PATCH 6/9] Add prune support using a separate service and cron schedule --- Dockerfile | 2 +- README.md | 8 +++++++- docker-compose.example.yml | 13 ++++++++++++- docker-swarm.example.yml | 13 ++++++++++++- entrypoint | 13 ++++++++++--- prune | 39 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 81 insertions(+), 7 deletions(-) create mode 100755 prune diff --git a/Dockerfile b/Dockerfile index a9c3ae9..da3cdc1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -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"] diff --git a/README.md b/README.md index 746dc20..268e608 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ 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) @@ -18,6 +19,8 @@ Run automatic [restic](https://restic.github.io/) backups via a Docker container 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: @@ -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 diff --git a/docker-compose.example.yml b/docker-compose.example.yml index 1bea29c..c7308bc 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -1,7 +1,7 @@ version: "3.3" services: - app: + backup: image: mazzolino/restic hostname: docker environment: @@ -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 diff --git a/docker-swarm.example.yml b/docker-swarm.example.yml index 77d3caa..0277ff4 100644 --- a/docker-swarm.example.yml +++ b/docker-swarm.example.yml @@ -1,7 +1,7 @@ version: "3.3" services: - app: + backup: image: mazzolino/restic environment: BACKUP_CRON: "0 30 3 * * *" @@ -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 diff --git a/entrypoint b/entrypoint index 84d32fa..8923ec5 100755 --- a/entrypoint +++ b/entrypoint @@ -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 @@ -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 diff --git a/prune b/prune new file mode 100755 index 0000000..aaeab4b --- /dev/null +++ b/prune @@ -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 "$@" From 5580f5087d06d264be745bebd6ccf61e3731c578 Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Sun, 7 Jun 2020 20:37:39 +0200 Subject: [PATCH 7/9] Allow custom backup arguments using RESTIC_BACKUP_ARGS --- README.md | 1 + backup | 2 +- docker-compose.example.yml | 1 + docker-swarm.example.yml | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 268e608..c868d6b 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ E.g. * `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 +* `RESTIC_BACKUP_ARGS` - Optional. Additional arguments given to *restic backup*. * `RESTIC_BACKUP_TAGS` - Optional. Tags to set on each snapshot, separated by commas. E.g. `swarm,docker-volumes` * `RESTIC_FORGET_ARGS` - Optional. If specified `restic forget` is run with the given arguments after each backup. E.g. `--prune --keep-last 14 --keep-daily 1` * (Additional variables as needed for the chosen backup target. E.g. `B2_ACCOUNT_ID` and `B2_ACCOUNT_KEY` for Backblaze B2.) diff --git a/backup b/backup index 2d79b33..e06ea49 100755 --- a/backup +++ b/backup @@ -29,7 +29,7 @@ start=`date +%s` echo Starting Backup at $(date +"%Y-%m-%d %H:%M:%S") set +e -restic backup ${tag_options} ${RESTIC_BACKUP_SOURCES} +restic backup ${RESTIC_BACKUP_ARGS:-} ${tag_options} ${RESTIC_BACKUP_SOURCES} if [ $? -ne 0 ] then set -e diff --git a/docker-compose.example.yml b/docker-compose.example.yml index c7308bc..2346dda 100644 --- a/docker-compose.example.yml +++ b/docker-compose.example.yml @@ -9,6 +9,7 @@ services: RESTIC_REPOSITORY: b2:my-repo:/restic RESTIC_PASSWORD: supersecret RESTIC_BACKUP_SOURCES: /mnt/volumes + #RESTIC_BACKUP_ARGS: -v RESTIC_BACKUP_TAGS: docker-volumes RESTIC_FORGET_ARGS: --prune --keep-last 14 --keep-daily 1 B2_ACCOUNT_ID: xxxxxxx diff --git a/docker-swarm.example.yml b/docker-swarm.example.yml index 0277ff4..5b3727e 100644 --- a/docker-swarm.example.yml +++ b/docker-swarm.example.yml @@ -8,6 +8,7 @@ services: RESTIC_REPOSITORY: b2:my-repo:/restic RESTIC_PASSWORD: supersecret RESTIC_BACKUP_SOURCES: /mnt/volumes + #RESTIC_BACKUP_ARGS: -v RESTIC_BACKUP_TAGS: docker-volumes RESTIC_FORGET_ARGS: --prune --keep-last 14 --keep-daily 1 B2_ACCOUNT_ID: xxxxxxx From 6fa501e2179648c3600520a3b5e0193e2b29471e Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Sun, 7 Jun 2020 20:52:58 +0200 Subject: [PATCH 8/9] Update changelog for v1.2.0 [skip ci] --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a780c77..b5f6a6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## [1.2.0](https://github.com/djmaze/resticker/tree/1.2.0) (2020-06-07) + +[Full Changelog](https://github.com/djmaze/resticker/compare/1.1.1...1.2.0) + +**Implemented enhancements:** + +- Allow custom backup arguments using RESTIC\_BACKUP\_ARGS [\#38](https://github.com/djmaze/resticker/pull/38) ([djmaze](https://github.com/djmaze)) +- Add prune support using a separate service and cron schedule [\#36](https://github.com/djmaze/resticker/pull/36) ([djmaze](https://github.com/djmaze)) +- update rclone to 1.50.2 [\#25](https://github.com/djmaze/resticker/pull/25) ([panakour](https://github.com/panakour)) + +**Fixed bugs:** + +- PRE\_COMMANDS: Invalid interpolation format for "environment" option in service [\#31](https://github.com/djmaze/resticker/issues/31) + ## [1.1.1](https://github.com/djmaze/resticker/tree/1.1.1) (2019-11-27) [Full Changelog](https://github.com/djmaze/resticker/compare/1.1.0...1.1.1) From ab7d17ec87617de68fae964d36b958a9bc95917d Mon Sep 17 00:00:00 2001 From: Martin Honermeyer Date: Sun, 7 Jun 2020 23:13:17 +0200 Subject: [PATCH 9/9] Fix manifest template since they changed the trimPrefix syntax -_- --- manifest.tmpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/manifest.tmpl b/manifest.tmpl index 3072ae2..9298d42 100644 --- a/manifest.tmpl +++ b/manifest.tmpl @@ -1,4 +1,4 @@ -image: mazzolino/restic:{{#if build.tag}}{{trimPrefix build.tag "v"}}{{else}}latest{{/if}} +image: mazzolino/restic:{{#if build.tag}}{{trimPrefix "v" build.tag}}{{else}}latest{{/if}} {{#if build.tags}} tags: {{#each build.tags}} @@ -7,17 +7,17 @@ tags: {{/if}} manifests: - - image: mazzolino/restic:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}amd64 + image: mazzolino/restic:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}amd64 platform: architecture: amd64 os: linux - - image: mazzolino/restic:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}arm + image: mazzolino/restic:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm platform: architecture: arm os: linux - - image: mazzolino/restic:{{#if build.tag}}{{trimPrefix build.tag "v"}}-{{/if}}arm64 + image: mazzolino/restic:{{#if build.tag}}{{trimPrefix "v" build.tag}}-{{/if}}arm64 platform: architecture: arm64 os: linux