mirror of
https://github.com/Steffo99/backup-duplicity.git
synced 2024-12-22 19:44:22 +00:00
Compare commits
4 commits
1b4f138db3
...
3c35a85c1a
Author | SHA1 | Date | |
---|---|---|---|
3c35a85c1a | |||
5319dfc0ab | |||
c323b79d96 | |||
5229f32497 |
6 changed files with 89 additions and 42 deletions
|
@ -5,9 +5,9 @@ FROM alpine:latest AS final
|
||||||
# RUN pacman --noconfirm -Syu duplicity python-pip python-pydrive2
|
# RUN pacman --noconfirm -Syu duplicity python-pip python-pydrive2
|
||||||
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
|
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
|
||||||
RUN \
|
RUN \
|
||||||
apk add py3-pip python3-dev gcc libffi-dev musl-dev openssl-dev pkgconfig duplicity rust cargo git && \
|
apk add py3-pip python3-dev gcc libffi-dev musl-dev openssl-dev pkgconfig duplicity rust cargo git curl && \
|
||||||
pip install --upgrade pip && \
|
pip install --upgrade pip --break-system-packages && \
|
||||||
pip install pydrive2 && \
|
pip install pydrive2 --break-system-packages && \
|
||||||
apk del rust musl-dev libffi-dev gcc python3-dev cargo git pkgconfig openssl-dev
|
apk del rust musl-dev libffi-dev gcc python3-dev cargo git pkgconfig openssl-dev
|
||||||
|
|
||||||
WORKDIR /usr/lib/duplicity
|
WORKDIR /usr/lib/duplicity
|
||||||
|
@ -32,3 +32,5 @@ LABEL org.opencontainers.image.authors="Stefano Pigozzi <me@steffo.eu>"
|
||||||
# Configure duplicity
|
# Configure duplicity
|
||||||
ENV DUPLICITY_FULL_IF_OLDER_THAN=1M
|
ENV DUPLICITY_FULL_IF_OLDER_THAN=1M
|
||||||
|
|
||||||
|
ENV NTFY=""
|
||||||
|
ENV NTFY_TAGS=""
|
||||||
|
|
|
@ -18,10 +18,11 @@ Backup solution for Docker volumes based on Duplicity
|
||||||
|
|
||||||
### Backup
|
### Backup
|
||||||
|
|
||||||
1. Create a new volume in Docker with the name `duplicity_credentials`:
|
1. Create two new volumes in Docker with the names `duplicity_credentials` and `duplicity_cache`:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
# docker volume create duplicity_credentials
|
# docker volume create duplicity_credentials
|
||||||
|
# docker volume create duplicity_cache
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create a new file in the host system with the name `/root/secrets/backup/passphrase.txt`, and enter in it a secure passphrase to use to encrypt files:
|
2. Create a new file in the host system with the name `/root/secrets/backup/passphrase.txt`, and enter in it a secure passphrase to use to encrypt files:
|
||||||
|
|
47
backup.sh
47
backup.sh
|
@ -8,8 +8,47 @@ set -e
|
||||||
export PASSPHRASE=$(cat "${DUPLICITY_PASSPHRASE_FILE}")
|
export PASSPHRASE=$(cat "${DUPLICITY_PASSPHRASE_FILE}")
|
||||||
|
|
||||||
echo "Launched in backup mode, performing backup..." >> /dev/stderr
|
echo "Launched in backup mode, performing backup..." >> /dev/stderr
|
||||||
|
|
||||||
|
if [ -n "${NTFY}" ]; then
|
||||||
|
echo "Sending ntfy backup start notification..." >> /dev/stderr
|
||||||
|
curl "${NTFY}" \
|
||||||
|
--silent \
|
||||||
|
--header "X-Title: Backup started" \
|
||||||
|
--data "Duplicity is attempting to perform a backup to **${DUPLICITY_TARGET_URL}**..." \
|
||||||
|
--header "X-Priority: min" \
|
||||||
|
--header "X-Tags: arrow_heading_up,${NTFY_TAGS}" \
|
||||||
|
--header "Content-Type: text/markdown"
|
||||||
|
fi
|
||||||
|
|
||||||
duplicity \
|
duplicity \
|
||||||
--allow-source-mismatch \
|
--allow-source-mismatch \
|
||||||
--full-if-older-than "${DUPLICITY_FULL_IF_OLDER_THAN}" \
|
--full-if-older-than "${DUPLICITY_FULL_IF_OLDER_THAN}" \
|
||||||
/mnt \
|
/mnt \
|
||||||
"${DUPLICITY_TARGET_URL}"
|
"${DUPLICITY_TARGET_URL}"
|
||||||
|
|
||||||
|
backup_result=$?
|
||||||
|
|
||||||
|
if [ -n "${NTFY}" ]; then
|
||||||
|
case "$backup_result" in
|
||||||
|
0)
|
||||||
|
echo "Sending ntfy backup complete notification..." >> /dev/stderr
|
||||||
|
curl "${NTFY}" \
|
||||||
|
--silent \
|
||||||
|
--header "X-Title: Backup complete" \
|
||||||
|
--data "Duplicity has successfully performed a backup to **${DUPLICITY_TARGET_URL}**!" \
|
||||||
|
--header "X-Priority: low" \
|
||||||
|
--header "X-Tags: white_check_mark,${NTFY_TAGS}" \
|
||||||
|
--header "Content-Type: text/markdown"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Sending ntfy backup failed notification..." >> /dev/stderr
|
||||||
|
curl "${NTFY}" \
|
||||||
|
--silent \
|
||||||
|
--header "X-Title: Backup failed" \
|
||||||
|
--data "Duplicity failed to perform a backup to **${DUPLICITY_TARGET_URL}**, and exited with status code **${backup_result}**." \
|
||||||
|
--header "X-Priority: max" \
|
||||||
|
--header "X-Tags: sos,${NTFY_TAGS}" \
|
||||||
|
--header "Content-Type: text/markdown"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
|
|
||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
backup)
|
backup)
|
||||||
echo "Running first backup..."
|
echo "Running first backup..."
|
||||||
/etc/periodic/daily/backup.sh
|
/etc/periodic/daily/backup.sh
|
||||||
echo "Running cron for daily backups..."
|
echo "Running cron for daily backups..."
|
||||||
crond -f -l 0
|
crond -f -l 0
|
||||||
echo "Cron has exited."
|
echo "Cron has exited."
|
||||||
;;
|
;;
|
||||||
restore)
|
restore)
|
||||||
echo "Restoring from latest backup..."
|
echo "Restoring from latest backup..."
|
||||||
/usr/lib/backup-duplicity/restore.sh
|
/usr/lib/backup-duplicity/restore.sh
|
||||||
echo "Done."
|
echo "Done."
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "No such mode." >> /dev/stderr
|
echo "No such mode." >> /dev/stderr
|
||||||
|
|
|
@ -1,27 +1,32 @@
|
||||||
secrets:
|
secrets:
|
||||||
google_client_config:
|
google_client_config:
|
||||||
file: "./google_client_config.yml"
|
file: "./google_client_config.yml"
|
||||||
duplicity_passphrase:
|
duplicity_passphrase:
|
||||||
file: "./duplicity_passphrase.txt"
|
file: "./duplicity_passphrase.txt"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
duplicity_credentials:
|
duplicity_credentials:
|
||||||
external: true
|
external: true
|
||||||
|
duplicity_cache:
|
||||||
|
external: true
|
||||||
|
|
||||||
services:
|
services:
|
||||||
duplicity:
|
duplicity:
|
||||||
image: "ghcr.io/steffo99/backup-duplicity:latest"
|
image: "ghcr.io/steffo99/backup-duplicity:latest"
|
||||||
entrypoint: "/bin/sh"
|
entrypoint: "/bin/sh"
|
||||||
command: "/etc/periodic/daily/backup.sh"
|
command: "/etc/periodic/daily/backup.sh"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- "./exampledata:/mnt/example"
|
- "./exampledata:/mnt/example"
|
||||||
- "duplicity_credentials:/var/lib/duplicity"
|
- "duplicity_credentials:/var/lib/duplicity"
|
||||||
environment:
|
- "duplicity_cache:/usr/lib/duplicity/.cache/duplicity"
|
||||||
MODE: "backup"
|
environment:
|
||||||
DUPLICITY_PASSPHRASE_FILE: "/run/secrets/duplicity_passphrase"
|
MODE: "backup"
|
||||||
DUPLICITY_TARGET_URL: "pydrive://641079776729-90s4tnli0ao913ajrpv8cp3c4kkk77j5.apps.googleusercontent.com/Duplicity/this"
|
DUPLICITY_PASSPHRASE_FILE: "/run/secrets/duplicity_passphrase"
|
||||||
GOOGLE_DRIVE_SETTINGS: "/run/secrets/google_client_config"
|
DUPLICITY_TARGET_URL: "pydrive://641079776729-90s4tnli0ao913ajrpv8cp3c4kkk77j5.apps.googleusercontent.com/Duplicity/this"
|
||||||
secrets:
|
GOOGLE_DRIVE_SETTINGS: "/run/secrets/google_client_config"
|
||||||
- google_client_config
|
NTFY: "https://ntfy.sh/garasauto"
|
||||||
- duplicity_passphrase
|
NTFY_TAGS: "garasauto"
|
||||||
|
secrets:
|
||||||
|
- google_client_config
|
||||||
|
- duplicity_passphrase
|
||||||
|
|
|
@ -9,7 +9,7 @@ export PASSPHRASE=$(cat "${DUPLICITY_PASSPHRASE_FILE}")
|
||||||
|
|
||||||
echo "Launched in restore mode, restoring backup..." >> /dev/stderr
|
echo "Launched in restore mode, restoring backup..." >> /dev/stderr
|
||||||
duplicity \
|
duplicity \
|
||||||
--force \
|
--force \
|
||||||
--allow-source-mismatch \
|
--allow-source-mismatch \
|
||||||
"${DUPLICITY_TARGET_URL}" \
|
"${DUPLICITY_TARGET_URL}" \
|
||||||
/mnt
|
/mnt
|
||||||
|
|
Loading…
Reference in a new issue