Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,40 @@ You can finetune the retention cycle of the restic backups using the `PRUNE_REST
:warning: | SFTP restic backend is not directly supported. Please use RCLONE backend with SFTP support.
---|---

##### `rclone` backup method
Rclone acts as the `tar` backup method but automatically moves the compressed files to a remote drive via [rclone](https://rclone.org/).

There are a few special environment variables for the rclone method.

- `RCLONE_REMOTE` is the name of the remote you've configured in your rclone.conf, see [remote setup](https://rclone.org/remote_setup/).
- `RCLONE_COMPRESS_METHOD`=gzip
- `DEST_DIR` acts as the directory on the remote. Files are not stored locally when using rclone.

Other parameters such as `PRUNE_BACKUPS_DAYS`, `ZSTD_PARAMETERS`, and `BACKUP_NAME` are all used as well.

**Note** that you will need to place your rclone config file in `/config/rclone/rclone.conf`.
This can be done by adding it through docker-compose,

```yaml
- ./rclone.config:/config/rclone/rclone.conf:ro
```
or by running the config wizard in a container and mounting the volume.
```shell
docker run -it --rm -v rclone-config:/config/rclone rclone/rclone config
```

then you must bind the volume **for the mc-backup process**
```yaml
volumes:
- rclone-config:/config/rclone
```
**and the service**
```yaml
volumes:
rclone-config:
external: true
```

## Volumes

- `/data` :
Expand Down
61 changes: 61 additions & 0 deletions backup-loop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ fi
: "${XDG_CONFIG_HOME:=/config}" # for rclone's base config path
: "${ONE_SHOT:=false}"
: "${TZ:=Etc/UTC}"
: "${RCLONE_COMPRESS_METHOD:=gzip}"
: "${RCLONE_REMOTE:=}"
export TZ

export RCON_HOST
Expand Down Expand Up @@ -296,6 +298,65 @@ restic() {
call_if_function_exists "${@}"
}

rclone() {
_find_old_backups() {
command rclone lsf --format "tp" "${RCLONE_REMOTE}:${DEST_DIR}" | grep ${BACKUP_NAME} | awk \
-v DESTINATION="${DEST_DIR}" \
Comment on lines +303 to +304
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...ah, given https://github.com/itzg/docker-mc-backup/pull/51/files#r774779939 it seems like you'll want this to be

Suggested change
command rclone lsf --format "tp" "${RCLONE_REMOTE}:${DEST_DIR}" | grep ${BACKUP_NAME} | awk \
-v DESTINATION="${DEST_DIR}" \
command rclone lsf --format "tp" "${RCLONE_REMOTE}:${RCLONE_REPOSITORY}" | grep ${BACKUP_NAME} | awk \
-v DESTINATION="${RCLONE_REPOSITORY}" \

The way to read ${RCLONE_REPOSITORY:=${DEST_DIR}} is "If RCLONE_REPOSITORY isn't already set, set it to the value of the DEST_DIR variable". And the leading colon on the line is a way to say process the line but don't execute it.

-v PRUNE_DATE="$(date '+%Y-%m-%d %H:%M:%S' --date="${PRUNE_BACKUPS_DAYS} days ago")" \
'BEGIN { FS=";" } $1 < PRUNE_DATE { printf "%s/%s\n", DESTINATION, $2 }'
}
init() {
# Check if rclone is installed and configured correctly
mkdir -p "${DEST_DIR}"
case "${RCLONE_COMPRESS_METHOD}" in
gzip)
readonly tar_parameters=("--gzip")
readonly backup_extension="tgz"
;;

bzip2)
readonly tar_parameters=("--bzip2")
readonly backup_extension="bz2"
;;

zstd)
readonly tar_parameters=("--use-compress-program" "zstd ${ZSTD_PARAMETERS}")
readonly backup_extension="tar.zst"
;;

*)
log ERROR 'RCLONE_COMPRESS_METHOD is not valid!'
exit 1
;;
esac
}
backup() {
ts=$(date +"%Y%m%d-%H%M%S")
outFile="${BACKUP_NAME}-${ts}.${backup_extension}"
log INFO "Backing up content in ${SRC_DIR} to ${outFile}"
command tar "${excludes[@]}" "${tar_parameters[@]}" -cf "${outFile}" -C "${SRC_DIR}" . || exitCode=$?
if [ ${exitCode:-0} -eq 1 ]; then
log WARN "tar exited with code 1. Ignoring"
fi
if [ ${exitCode:-0} -gt 1 ]; then
log ERROR "tar exited with code ${exitCode}! Aborting"
exit 1
fi

command rclone copy "${outFile}" "${RCLONE_REMOTE}:${DEST_DIR}"
rm "${outFile}"
}
prune() {
if [ -n "$(_find_old_backups)" ]; then
log INFO "Pruning backup files older than ${PRUNE_BACKUPS_DAYS} days"
_find_old_backups | tee \
>(awk '{ printf "Removing %s\n", $0 }' | log INFO) \
>(while read -r path; do command rclone purge "${path}"; done)
fi
}
call_if_function_exists "${@}"
}

##########
## main ##
##########
Expand Down