Table of Contents
First time setup
-
Create a new directory somewhere on your system to use to store data related to GA Backup; it can be anywhere, but for the purposes of this guide, it'll be referred to as
$ga_config_dir, and will be located in/srv/docker/ga_backup:ga_config_dir="/srv/docker/ga_backup" mkdir --verbose --parents "$ga_config_dir" -
Create a directory for storing secrets, and make sure you're the only user with access to it:
mkdir --verbose --parents "$ga_config_dir/secrets" chmod go-rwx "$ga_config_dir/secrets" -
Generate the encryption password and store it in the secrets directory as a file with the name of
ga_passphrase.txt:cat "/dev/urandom" | LC_ALL="C" tr --delete --complement '[:graph:]' | head --bytes 32 > "$ga_config_dir/secrets/ga_passphrase.txt" -
Use the Google Cloud Console to create new OAuth credentials for a Desktop Application, then download the resulting JSON credential file and move it inside the secrets directory with the name
ga_gdrive_client_secret.json:# Example. Source file location might vary depending on your system. mv --verbose ./client_secret* "$ga_config_dir/secrets/ga_gdrive_client_secret.json" -
Create a new Docker volume with the name
ga_cache, which will be used to temporarily store previous backups in a series:docker volume create "ga_cache" -
Create a new Docker volume with the name
ga_credentials, which will be use to store Google Drive API credentials:docker volume create "ga_credentials" -
Open the
ga_gdrive_client_secret.jsonand copy somewhere the value of.installed.client_id; let's call this$ga_gdrive_client_id:{ "installed": { "client_id": "641079776729-da3fi7a2kgk5jkutsjdcnhugqolu40mo.apps.googleusercontent.com", // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // copy this part // [...] } } -
Find in your browser the Google Drive directory you want to store backups in, open it, and copy the final part of the URL; let's call this
$ga_gdrive_directory:https://drive.google.com/drive/u/0/folders/1_AAAAAAAAAA-BBBBBBBBBBBBBBBBBBBB ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ copy this part -
Create a
compose.include.ymlfile in the$ga_config_dirdirectory with the following contents, taking care to manually replace$ga_gdrive_client_idand$ga_gdrive_directorywith the values you've acquired in the previous steps:# Must be volumes to be able to import this from other compose files volumes: ga_credentials: name: &ga_credentials "ga_credentials" external: true ga_cache: name: &ga_cache "ga_cache" external: true # Since they are sensitive files, they should be secrets secrets: ga_passphrase: name: &ga_passphrase "ga_passphrase" file: "./secrets/ga_passphrase.txt" ga_gdrive_client_secret: name: &ga_gdrive_client_secret "ga_gdrive_client_secret" file: "./secrets/ga_gdrive_client_secret.json" services: # The backup utility itself ga: image: "forge.steffo.eu/steffo/ga-backup:latest" restart: unless-stopped network_mode: host stdin_open: true tty: true volumes: - # Mount the credentials volume type: volume source: *ga_credentials target: "/var/lib/duplicity" - # Mount the cache volume type: volume source: *ga_cache target: "/usr/lib/duplicity/.cache/duplicity" - # Mount the current working directory to backup it. # Note that this breaks if launching the compose project from outside the working directory. type: bind source: "${PWD}" target: "/mnt" secrets: - source: *ga_passphrase - source: *ga_gdrive_client_secret environment: MODE: "backup" DUPLICITY_TARGET_URL: "gdrive://$ga_gdrive_client_id/${COMPOSE_PROJECT_NAME}?myDriveFolderID=$ga_gdrive_directory" DUPLICITY_PASSPHRASE_FILE: "/run/secrets/ga_passphrase" GOOGLE_CLIENT_SECRET_JSON_FILE: "/run/secrets/ga_gdrive_client_secret" GOOGLE_CREDENTIALS_FILE: "/var/lib/duplicity/google_credentials" GOOGLE_OAUTH_LOCAL_SERVER_HOST: "localhost" GOOGLE_OAUTH_LOCAL_SERVER_PORT: "8080" -
Briefly launch a shell in the container:
docker compose run --interactive --rm --entrypoint=sh ga -
Pretend to launch a backup to trigger the Google Drive authentication flow, then complete the authentication and immediately terminate the shell:
/etc/periodic/daily/backup.shPlease visit this URL to authorize this application: https://accounts.google.com/o/oauth2/authNote
For authentication to work correctly after Google's removal of the OOB Flow, your
http://localhost:8080address might be required to match thehttp://localhost:8080of the GA Backup container.This is not an issue if you can launch a browser on the same machine you're configuring GA Backup on, but it might be troublesome for non-graphical servers, where this is not possible.
To bypass the issue, you can temporarily set up an SSH tunnel towards the server for the duration of the setup process:
ssh -L 8080:8080 yourserver -
You should be done! Make sure backups are appearing in the Google Drive directory you've configured.
Backing up Compose project directories
Tip
The basic idea is to store all files related to a project in the directory containing
compose.yml, then backing that up.
-
Add the following to your
compose.ymlfile:include: - path: "/srv/docker/realms_duplicity/compose.include.yml" -
Take up the project:
docker compose upWarning
For the backup to work properly, you MUST be in the directory of the project to backup when running the command.