1
Fork 0
mirror of https://github.com/Steffo99/backup-duplicity.git synced 2024-10-16 06:07:25 +00:00
This commit is contained in:
Steffo 2023-03-14 19:32:14 +01:00
commit 501e421357
Signed by: steffo
GPG key ID: 2A24051445686895
7 changed files with 208 additions and 0 deletions

11
.github/workflows/release.yml vendored Normal file
View file

@ -0,0 +1,11 @@
name: "Release new version"
on:
# Creation of a new tag starting with v
push:
tags:
- "v*"
jobs:
ghcrio:
uses: Steffo99/.github/.github/workflows/buildrelease-docker.yml@main

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "duplicity"]
path = duplicity
url = https://gitlab.com/duplicity/duplicity.git

32
Dockerfile Normal file
View file

@ -0,0 +1,32 @@
# FROM archlinux:latest
FROM alpine:latest
# Install duplicity
# RUN pacman --noconfirm -Syu duplicity python-pip python-pydrive2
RUN apk add duplicity
RUN apk add py3-pip
RUN apk add python3-dev
RUN apk add gcc
RUN apk add libffi-dev
RUN apk add musl-dev
RUN pip install pydrive2
WORKDIR /var/lib/duplicity
ENV HOME="/var/lib/duplicity"
# Configure entrypoint and command
ENTRYPOINT ["crond", "-f", "-d", "5"]
CMD []
# Add image labels
LABEL org.opencontainers.image.title="docker-backup-duplicity"
LABEL org.opencontainers.image.description="Backup solution for Docker volumes based on Duplicity"
LABEL org.opencontainers.image.licenses="AGPL-3.0-or-later"
LABEL org.opencontainers.image.url="https://github.com/Steffo99/docker-backup-duplicity"
LABEL org.opencontainers.image.authors="Stefano Pigozzi <me@steffo.eu>"
# Add duplicity to cron
COPY ./backup.sh /etc/periodic/daily/backup.sh
# Configure duplicity
ENV DUPLICITY_FULL_IF_OLDER_THAN=1M

103
README.md Normal file
View file

@ -0,0 +1,103 @@
# docker-backup-duplicity
Backup solution for Docker volumes based on Duplicity
## Usage
> **Note**: The following instructions assume Google Drive is used as a storage backend; refer to [duplicity's man page](https://duplicity.us/stable/duplicity.1.html) to find out how to configure different backends!
1. Create a new volume in Docker with the name `duplicity_credentials`:
```console
# docker volume create duplicity_credentials
```
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:
```console
# echo 'CorrectHorseBatteryStaple' >> /root/secrets/backup/passphrase.txt
```
3. [Obtain *Desktop Application* OAuth credentials from the Google Cloud Console.](https://console.cloud.google.com/apis/credentials)
4. Create a new file in the host system with the name `/root/secrets/backup/client_config.yml`, and enter the following content in it:
```console
# edit /root/secrets/backup/client_config.yml
```
```yml
client_config_backend: settings
client_config:
client_id: "YOUR_GOOGLE_CLIENT_ID_GOES_HERE"
client_secret: "YOUR_GOOGLE_CLIENT_SECRET_GOES_HERE"
save_credentials: True
save_credentials_backend: file
save_credentials_file: "/var/lib/duplicity/credentials"
get_refresh_token: True
```
5. Add the following keys to the `docker-compose.yml` file of the project you want to backup:
```console
# edit ./docker-compose.yml
```
1. If you haven't already, upgrade your `docker-compose.yml` file to version 3.9:
```yml
version: "3.9"
```
2. Connect the previously created `duplicity_credentials` volume to the project:
```yml
volumes:
duplicity_credentials:
external: true
```
3. Setup the two previously created files as Docker secrets:
```yml
secrets:
duplicity_passphrase:
file: "/root/secrets/backup/passphrase.txt"
google_client_config:
file: "/root/secrets/backup/client_config.yml"
```
4. Add the following service:
```yml
services:
backup:
image: "ghcr.io/steffo99/backup-duplicity:latest"
restart: unless-stopped
secrets:
- google_client_config
- duplicity_passphrase
volumes:
- "duplicity_credentials:/var/lib/duplicity"
# Mount whatever you want to backup in subdirectories of /mnt
- ".:/mnt/compose" # Backup the current directory?
- "data:/mnt/data" # Backup a named volume?
environment:
MODE: "backup" # Change this to "restore" to restore the latest backup
DUPLICITY_TARGET_URL: "pydrive://YOUR_GOOGLE_CLIENT_ID_GOES_HERE/Duplicity/this" # Change this to the Drive directory you want to backup files to https://man.archlinux.org/man/duplicity.1.en#URL_FORMAT
# Don't touch these, they allow the program to read the secrets
DUPLICITY_PASSPHRASE_FILE: "/run/secrets/duplicity_passphrase"
GOOGLE_DRIVE_SETTINGS: "/run/secrets/google_client_config"
```
6. Log in to Google Drive and perform an initial backup with:
```console
# docker compose run -i backup --entrypoint=/bin/sh /etc/periodic/daily/backup.sh
```
7. Properly start the container with:
```console
# docker compose up -d && docker compose logs -f
```

30
backup.sh Normal file
View file

@ -0,0 +1,30 @@
#!/bin/sh
set -e
# Get secrets from files
# Insecure, but there's not much I can do about it
# It's duplicity's fault!
export PASSPHRASE=$(cat ${DUPLICITY_PASSPHRASE_FILE})
case "$MODE" in
backup)
echo "Launched in backup mode, performing backup..." >> /dev/stderr
duplicity \
--allow-source-mismatch \
--full-if-older-than ${DUPLICITY_FULL_IF_OLDER_THAN} \
/mnt \
${DUPLICITY_TARGET_URL}
;;
restore)
echo "Launched in restore mode, restoring backup..." >> /dev/stderr
duplicity \
--force \
--allow-source-mismatch \
${DUPLICITY_TARGET_URL} \
/mnt
;;
*)
echo "No such mode." >> /dev/stderr
;;
esac

0
example/.gitignore vendored Normal file
View file

29
test.docker-compose.yml Normal file
View file

@ -0,0 +1,29 @@
version: "3.9"
secrets:
google_client_config:
file: "/root/secrets/backup/client_config.yml"
duplicity_passphrase:
file: "/root/secrets/backup/passphrase.txt"
volumes:
duplicity_credentials:
external: true
services:
backup:
image: "ghcr.io/steffo99/backup-duplicity:latest"
entrypoint: "/bin/sh"
command: "/etc/periodic/daily/backup.sh"
restart: unless-stopped
volumes:
- "./example:/mnt/example"
- "duplicity_credentials:/var/lib/duplicity"
environment:
MODE: "backup"
DUPLICITY_PASSPHRASE_FILE: "/run/secrets/duplicity_passphrase"
DUPLICITY_TARGET_URL: "pydrive://641079776729-90s4tnli0ao913ajrpv8cp3c4kkk77j5.apps.googleusercontent.com/Duplicity/this"
GOOGLE_DRIVE_SETTINGS: "/run/secrets/google_client_config"
secrets:
- google_client_config
- duplicity_passphrase