kopia lustrzana https://github.com/borgmatic-collective/docker-borgmatic
Merge pull request #331 from Psycho0verload/s6_clean_secrets
Patch: Separation of secrets and cronpull/337/head
commit
c8f89acf5e
|
@ -3,7 +3,6 @@ BORG_PASSPHRASE=ReplaceWithYourSecretPassPhrase
|
|||
VOLUME_SOURCE=/home
|
||||
VOLUME_TARGET=./data/repository
|
||||
VOLUME_ETC_BORGMATIC=./data/borgmatic.d
|
||||
VOLUME_BORGMATIC_STATE=./data/.borgmatic
|
||||
VOLUME_BORG_CONFIG=./data/.config/borg
|
||||
VOLUME_SSH=./data/.ssh
|
||||
VOLUME_BORG_CACHE=./data/.cache/borg
|
||||
|
|
26
README.md
26
README.md
|
@ -22,9 +22,9 @@ This repository provides a Docker image for [borgmatic](https://github.com/witte
|
|||
|
||||
### Prerequisites
|
||||
Before proceeding, ensure that you have [Docker](https://www.docker.com/) installed and properly configured on your system. Refer to the [Docker documentation](https://docs.docker.com/engine/install/) for installation instructions specific to your operating system. If you want to use [docker-compose](https://docs.docker.com/compose/install/), you may also need to install it seperately.
|
||||
Alternatively, you can also use [podman](https://podman.io/docs) to run this image.
|
||||
Alternatively, you can also use [podman](https://podman.io/docs) to run this image.
|
||||
|
||||
### Getting Started
|
||||
### Getting Started
|
||||
|
||||
Run this command to create data directories required by this image under your prefered directory.
|
||||
|
||||
|
@ -80,16 +80,20 @@ You can set the following environment variables:
|
|||
|
||||
You can also provide your own crontab file. If `data/borgmatic.d/crontab.txt` exists, `BACKUP_CRON` will be ignored in preference to it. In here you can add any other tasks you want ran
|
||||
```
|
||||
0 1 * * * PATH=$PATH:/usr/bin /usr/bin/borgmatic --stats -v 0 2>&1
|
||||
0 1 * * * PATH=$PATH:/usr/local/bin /usr/local/bin/borgmatic --stats -v 0 2>&1
|
||||
```
|
||||
|
||||
Beside that, you can also pass any environment variable that is supported by borgmatic. See documentation for [borgmatic](https://torsion.org/borgmatic/) and [Borg](https://borgbackup.readthedocs.io/) and for a list of supported variables.
|
||||
|
||||
### Using Secrets (Optional)
|
||||
|
||||
You also have the option to use Docker Secrets for more sensitive information. This is not mandatory, but it adds an extra layer of security. **Note that this feature is only applicable to environment variables starting with `BORG`.**
|
||||
You also have the option of using Docker Secrets for more sensitive information. This is not mandatory, but provides an additional layer of security. **Note that this function is only applicable to environment variables that start with `BORG` or `YOUR`.**
|
||||
|
||||
For each environment variable such as `BORG_PASSPHRASE`, you can create a corresponding secret file called `BORG_PASSPHRASE_FILE`. Store the contents of the secret file in this file. The start script automatically searches for corresponding `_FILE` secrets if the environment variables are not set and loads them.
|
||||
|
||||
It is important to know that this environment variable is **not** available via `docker compose exec borgmatic sh`. Only for the automated call via the defined cron.
|
||||
|
||||
|
||||
For every environment variable like `BORG_PASSPHRASE`, you can create a corresponding secret file, named as `BORG_PASSPHRASE_FILE`. Place the content of the secret inside this file. The startup script will automatically look for corresponding `_FILE` secrets if the environment variables are not set and load them.
|
||||
|
||||
## Using Apprise for Notifications
|
||||
|
||||
|
@ -102,7 +106,7 @@ To enhance your experience with Borgmatic, we'll show you a quick example of how
|
|||
In an unmodified Borgmatic installation, your `cronjob.txt` might look something like this:
|
||||
|
||||
```
|
||||
0 1 * * * PATH=$PATH:/usr/local/bin /usr/local/bin/borgmatic --stats -v 0 2>&1
|
||||
0 1 * * * /usr/local/bin/borgmatic --stats -v 0 2>&1
|
||||
```
|
||||
|
||||
To incorporate Apprise notifications, you can modify it like this:
|
||||
|
@ -121,11 +125,11 @@ before_backup:
|
|||
|
||||
after_backup:
|
||||
- echo "Backup created."
|
||||
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com"
|
||||
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com"
|
||||
|
||||
on_error:
|
||||
- echo "Error while creating a backup."
|
||||
- apprise -vv -t "❌ FAILED" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com"
|
||||
- apprise -vv -t "❌ FAILED" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com"
|
||||
```
|
||||
|
||||
##### Note:
|
||||
|
@ -145,7 +149,7 @@ Apprise allows you to notify multiple services at the same time:
|
|||
```yaml
|
||||
after_backup:
|
||||
- echo "Backup created."
|
||||
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailto://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com,slack://token@Txxxx/Bxxxx/Cxxxx"
|
||||
- apprise -vv -t "✅ SUCCESS" -b "$(cat /tmp/backup_run.log)" "mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com,slack://token@Txxxx/Bxxxx/Cxxxx"
|
||||
```
|
||||
|
||||
### Native Apprise Configuration in Borgmatic 1.8.4+
|
||||
|
@ -160,7 +164,7 @@ apprise:
|
|||
- fail
|
||||
|
||||
services:
|
||||
- url: mailto://smtp.example.com:587?user=info@example.com&pass=YourSecurePassword&from=server@example.com
|
||||
- url: mailtos://smtp.example.com:587?user=server@example.com&pass=YourSecurePassword&from=server@example.com&to=receiver@example.com
|
||||
label: mail
|
||||
- url: slack://token@Txxxx/Bxxxx/Cxxxx
|
||||
label: slack
|
||||
|
@ -350,4 +354,4 @@ bash -c "borgmatic --init --encryption repokey-blake2"
|
|||
```
|
||||
|
||||
### Additional Reading
|
||||
[Backup Docker using borgmatic](https://www.modem7.com/books/docker-backup/page/backup-docker-using-borgmatic) - Thank you [@modem7](https://github.com/modem7)
|
||||
[Backup Docker using borgmatic](https://www.modem7.com/books/docker-backup/page/backup-docker-using-borgmatic) - Thank you [@modem7](https://github.com/modem7)
|
|
@ -1,19 +1,13 @@
|
|||
version: '3'
|
||||
services:
|
||||
borgmatic:
|
||||
container_name: borg-restore
|
||||
|
||||
cap_add:
|
||||
- SYS_ADMIN
|
||||
|
||||
volumes:
|
||||
- /host/mount/location:/restore
|
||||
|
||||
security_opt:
|
||||
- apparmor:unconfined
|
||||
- label:disable
|
||||
|
||||
devices:
|
||||
- /dev/fuse:/dev/fuse
|
||||
|
||||
command: /bin/sh
|
||||
command: /bin/sh
|
|
@ -1,4 +1,3 @@
|
|||
version: '3'
|
||||
services:
|
||||
borgmatic:
|
||||
image: ghcr.io/borgmatic-collective/borgmatic
|
||||
|
@ -7,10 +6,9 @@ services:
|
|||
- ${VOLUME_SOURCE}:/mnt/source:ro # backup source
|
||||
- ${VOLUME_TARGET}:/mnt/borg-repository # backup target
|
||||
- ${VOLUME_ETC_BORGMATIC}:/etc/borgmatic.d/ # borgmatic config file(s) + crontab.txt
|
||||
- ${VOLUME_BORGMATIC_STATE}:/root/.borgmatic # borgmatic state files
|
||||
- ${VOLUME_BORG_CONFIG}:/root/.config/borg # config and keyfiles
|
||||
- ${VOLUME_SSH}:/root/.ssh # ssh key for remote repositories
|
||||
- ${VOLUME_BORG_CACHE}:/root/.cache/borg # checksums used for deduplication
|
||||
environment:
|
||||
- TZ=${TZ}
|
||||
- BORG_PASSPHRASE=${BORG_PASSPHRASE}
|
||||
- BORG_PASSPHRASE=${BORG_PASSPHRASE}
|
|
@ -0,0 +1 @@
|
|||
#!/usr/bin/execlineb -P
|
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/with-contenv bash
|
||||
|
||||
# Function to log debugging information
|
||||
log_debug_info() {
|
||||
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
|
||||
echo "DEBUG: $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Path to the environment file
|
||||
ENV_FILE="/etc/s6-overlay/env/cron-env"
|
||||
|
||||
# Create or clear the environment file
|
||||
> "$ENV_FILE"
|
||||
|
||||
# Array to store debug information
|
||||
declare -a debug_info
|
||||
|
||||
# Loop through all environment variables that start with 'BORG' or 'YOUR'.
|
||||
for var_name in $(set | grep -E '^BORG|^YOUR' | awk -F= '{print $1}'); do
|
||||
# Retrieve the current value of each environment variable.
|
||||
var_value=$(eval echo \$$var_name)
|
||||
|
||||
# Check if the variable's name ends with '_FILE'.
|
||||
if [[ "$var_name" =~ _FILE$ ]]; then
|
||||
# Strip the '_FILE' suffix to obtain the corresponding variable name.
|
||||
original_var_name=${var_name%_FILE}
|
||||
|
||||
# Retrieve the value of the original environment variable, if it exists.
|
||||
original_var_value=$(eval echo \$$original_var_name)
|
||||
|
||||
# Ensure the *_FILE variable is valid, and the referenced file exists and is not empty.
|
||||
if [ -n "$var_value" ] && [ -s "$var_value" ]; then
|
||||
# Notify user if original variable is being overwritten.
|
||||
if [ -n "$original_var_value" ]; then
|
||||
debug_info+=("Note: $original_var_name was already set but is being overwritten by $var_name")
|
||||
fi
|
||||
|
||||
# Update the original variable with the content of the file.
|
||||
var_content=$(cat "$var_value")
|
||||
export "$original_var_name"="$var_content"
|
||||
debug_info+=("Setting $original_var_name from the content of $var_value")
|
||||
|
||||
# Add the variable to the environment file
|
||||
echo "export $original_var_name=\"$var_content\"" >> "$ENV_FILE"
|
||||
|
||||
# Unset the *_FILE environment variable.
|
||||
unset "$var_name"
|
||||
debug_info+=("Unsetting $var_name")
|
||||
|
||||
# Add the final value of the original variable
|
||||
debug_info+=("$original_var_name is now set to: $var_content")
|
||||
else
|
||||
# Issue an error if the *_FILE variable is not properly set, or the file does not exist or is empty.
|
||||
debug_info+=("Error: File $var_value does not exist or is empty.")
|
||||
fi
|
||||
else
|
||||
# Directly add non-_FILE variables to the environment file
|
||||
echo "export $var_name=\"$var_value\"" >> "$ENV_FILE"
|
||||
# Add debug info for non-_FILE variables
|
||||
debug_info+=("Variable $var_name is set to: \"$var_value\"")
|
||||
fi
|
||||
done
|
||||
|
||||
# Output all debug information at once
|
||||
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
|
||||
echo "Debug Information:"
|
||||
for info in "${debug_info[@]}"; do
|
||||
echo "$info"
|
||||
done
|
||||
fi
|
|
@ -0,0 +1 @@
|
|||
oneshot
|
|
@ -0,0 +1 @@
|
|||
/etc/s6-overlay/s6-rc.d/secrets/run
|
|
@ -1,5 +1,10 @@
|
|||
#!/command/with-contenv bash
|
||||
|
||||
# Load the environment variables from the secrets service
|
||||
if [ -f /etc/s6-overlay/env/cron-env ]; then
|
||||
source /etc/s6-overlay/env/cron-env
|
||||
fi
|
||||
|
||||
# Version variables
|
||||
borgver=$(borg --version)
|
||||
borgmaticver=$(borgmatic --version)
|
||||
|
@ -35,70 +40,18 @@ then
|
|||
echo "-----------------------------------"
|
||||
fi
|
||||
|
||||
# Enable initial debug logging based on the DEBUG_SECRETS environment variable.
|
||||
# Logs the initial values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
|
||||
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
|
||||
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
|
||||
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
|
||||
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
|
||||
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
|
||||
fi
|
||||
|
||||
# Loop through all environment variables that start with 'BORG'.
|
||||
for var_name in $(set | grep -E '^BORG|^YOUR' | awk -F= '{print $1}'); do
|
||||
# Retrieve the current value of each environment variable.
|
||||
var_value=$(eval echo \$$var_name)
|
||||
|
||||
# Check if the variable's name ends with '_FILE'.
|
||||
if [[ "$var_name" =~ _FILE$ ]]; then
|
||||
# Strip the '_FILE' suffix to obtain the corresponding variable name.
|
||||
original_var_name=${var_name%_FILE}
|
||||
|
||||
# Retrieve the value of the original environment variable, if it exists.
|
||||
original_var_value=$(eval echo \$$original_var_name)
|
||||
|
||||
# Ensure the *_FILE variable is valid, and the referenced file exists and is not empty.
|
||||
if [ -n "$var_value" ] && [ -s "$var_value" ]; then
|
||||
# Notify user if original variable is being overwritten.
|
||||
if [ -n "$original_var_value" ]; then
|
||||
echo "Note: $original_var_name was already set but is being overwritten by $var_name"
|
||||
fi
|
||||
|
||||
# Update the original variable with the content of the file.
|
||||
export "$original_var_name"=$(cat "$var_value")
|
||||
echo "Setting $original_var_name from the content of $var_value"
|
||||
|
||||
# Unset the *_FILE environment variable.
|
||||
unset "$var_name"
|
||||
echo "Unsetting $var_name"
|
||||
else
|
||||
# Issue an error if the *_FILE variable is not properly set, or the file does not exist or is empty.
|
||||
echo "Error: File $var_value does not exist or is empty."
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Enable final debug logging based on the DEBUG_SECRETS environment variable.
|
||||
# Logs the final values of BORG_PASSPHRASE and BORG_PASSPHRASE_FILE.
|
||||
if [ "${DEBUG_SECRETS}" = "true" ] || [ "${DEBUG_SECRETS}" = "1" ]; then
|
||||
echo "Before: BORG_PASSPHRASE: ${BORG_PASSPHRASE}"
|
||||
echo "Before: BORG_PASSPHRASE_FILE: ${BORG_PASSPHRASE_FILE}"
|
||||
echo "Before: YOUR_PASSPHRASE: ${YOUR_PASSPHRASE}"
|
||||
echo "Before: YOUR_PASSPHRASE_FILE: ${YOUR_PASSPHRASE_FILE}"
|
||||
fi
|
||||
|
||||
# Disable cron if it's set to disabled.
|
||||
if [[ "$CRON" = "false" ]]; then
|
||||
if [[ "$BACKUP_CRON" = "false" ]]; then
|
||||
echo "Disabling cron, removing configuration"
|
||||
# crontab -r # quite destructive
|
||||
# echo -n > /etc/crontabs/root # Empty config, doesn't look as nice with "crontab -l"
|
||||
echo "# Cron disabled" > /etc/crontabs/root
|
||||
echo "Cron is now disabled"
|
||||
# Apply default or custom cron if $CRON is unset or set (not null):
|
||||
elif [[ -v CRON ]]; then
|
||||
CRON="${CRON:-"0 1 * * *"}"
|
||||
CRON_COMMAND="${CRON_COMMAND:-"borgmatic --stats -v 0 2>&1"}"
|
||||
echo "$CRON $CRON_COMMAND" > /etc/crontabs/root
|
||||
# Apply default or custom cron if $BACKUP_CRON is unset or set (not null):
|
||||
elif [[ -v BACKUP_CRON ]]; then
|
||||
BACKUP_CRON="${BACKUP_CRON:-"0 1 * * *"}"
|
||||
CRON_COMMAND="${CRON_COMMAND:-"/usr/local/bin/borgmatic --stats -v 0 2>&1"}"
|
||||
echo "$BACKUP_CRON $CRON_COMMAND" > /etc/crontabs/root
|
||||
echo "Applying custom cron"
|
||||
# If nothing is set, revert to default behaviour
|
||||
else
|
||||
|
|
Ładowanie…
Reference in New Issue