Skip to content

Instantly share code, notes, and snippets.

@zuedev
Last active December 6, 2025 16:27
Show Gist options
  • Select an option

  • Save zuedev/bdcda6ef2472acd96bb09ac544122ab6 to your computer and use it in GitHub Desktop.

Select an option

Save zuedev/bdcda6ef2472acd96bb09ac544122ab6 to your computer and use it in GitHub Desktop.
Automated Restic Backup to Backblaze B2 via Docker: A single Bash script to initialize a Restic repository (if needed) and run a full, excluded, read-only backup of a Linux host's root filesystem (`/`) to Backblaze B2 using the official Docker image and S3-compatible API.
#!/bin/bash
# --- 1. CONFIGURATION ---
# Replace these placeholders with your actual values.
# Backblaze B2 S3 Credentials
export AWS_ACCESS_KEY_ID="YOUR_B2_KEY_ID"
export AWS_SECRET_ACCESS_KEY="YOUR_B2_APPLICATION_KEY"
# Restic Repository Details
export RESTIC_REPOSITORY="s3:s3.eu-central-003.backblazeb2.com/sovereign-restic-backup"
export RESTIC_PASSWORD="YOUR_REPOSITORY_PASSWORD"
# Backup Parameters
HOST_TAG="YOUR_HOST_TAG"
BACKUP_SOURCE="/sovereign"
# Host Path to the Exclude File (This path is on the HOST machine)
HOST_EXCLUDE_FILE="/etc/restic-exclude"
# Docker Parameters
IMAGE_NAME="restic/restic:latest"
VOLUME_MOUNT="/:/sovereign:ro"
# --- 2. DYNAMIC COMMAND CONSTRUCTION (THE FIX) ---
# Check if the exclude file exists on the HOST.
# If it exists, set the flag to include it in the Restic command.
# The path used here (inside the quotes) is the path *inside the container*.
EXCLUDE_FLAG=""
if [ -f "$HOST_EXCLUDE_FILE" ]; then
echo "Exclusion file found on host at $HOST_EXCLUDE_FILE. Including in backup."
EXCLUDE_FLAG="--exclude-file ${BACKUP_SOURCE}/etc/restic-exclude"
else
echo "WARNING: Exclusion file not found at $HOST_EXCLUDE_FILE. Skipping --exclude-file flag."
fi
# --- 3. RESTIC INITIALIZATION CHECK ---
echo "Checking Restic repository status..."
# Attempt to check the repository. Redirect output to /dev/null to keep things clean.
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e RESTIC_REPOSITORY \
-e RESTIC_PASSWORD \
"${IMAGE_NAME}" snapshots &> /dev/null
INIT_STATUS=$?
# If the status is not 0 (success), attempt to initialize the repository.
if [ "$INIT_STATUS" -ne 0 ]; then
echo "Repository check failed (Exit Code: $INIT_STATUS). Attempting initialization (init)..."
# Run the initialization command
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e RESTIC_REPOSITORY \
-e RESTIC_PASSWORD \
"${IMAGE_NAME}" init
# Check the result of the 'init' command
if [ $? -ne 0 ]; then
echo "======================================================================"
echo "FATAL ERROR: Restic repository initialization failed."
echo "Please verify your B2 credentials and RESTIC_REPOSITORY path."
echo "======================================================================"
exit 1
fi
echo "Initialization successful. Proceeding to backup."
fi
# --- 4. RESTIC BACKUP ---
echo "Starting backup of ${BACKUP_SOURCE}..."
# Full backup command. Note the dynamic use of $EXCLUDE_FLAG.
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e RESTIC_REPOSITORY \
-e RESTIC_PASSWORD \
--volume "${VOLUME_MOUNT}" \
"${IMAGE_NAME}" backup "${BACKUP_SOURCE}" \
--tag "${HOST_TAG}" \
${EXCLUDE_FLAG} \
--exclude "${BACKUP_SOURCE}/proc" \
--exclude "${BACKUP_SOURCE}/sys" \
--exclude "${BACKUP_SOURCE}/dev" \
--exclude "${BACKUP_SOURCE}/run" \
--exclude "${BACKUP_SOURCE}/tmp"
if [ $? -eq 0 ]; then
echo "Backup completed successfully. 🎉"
else
echo "ERROR: Restic backup failed. ❌"
fi
# --- 5. PRUNE (Optional) ---
: '
# Prune logic remains the same (uncomment to enable)
echo "Starting prune operation..."
docker run --rm \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e RESTIC_REPOSITORY \
-e RESTIC_PASSWORD \
"${IMAGE_NAME}" forget \
--tag "${HOST_TAG}" \
--prune \
--keep-hourly 24 \
--keep-daily 7 \
--keep-monthly 12
if [ $? -eq 0 ]; then
echo "Pruning completed successfully."
else
echo "WARNING: Restic prune failed."
fi
'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment