#!/bin/bash # start.sh: Initializes the cron schedule and starts the daemon. # Exit immediately if any command fails set -e # --- 0. Sanitize and Persist ALL Environment Variables --- # Create a profile script that will be sourced by all new shells. # This ensures that `docker exec` sessions get the sanitized environment. ENV_SCRIPT="/etc/profile.d/00-rustic-env.sh" echo "# This file is auto-generated by start.sh" > "${ENV_SCRIPT}" echo "# It sanitizes and exports variables for all shell sessions." >> "${ENV_SCRIPT}" # List of all variables that need sanitization VARS_TO_SANITIZE=( "CONTAINER_ROLE" "RUSTIC_PASSWORD" "CRON_SCHEDULE" "S3_ENDPOINT" "S3_BUCKET" "S3_REGION" "AWS_ACCESS_KEY_ID" "AWS_SECRET_ACCESS_KEY" "RANDOM_DELAY_SECONDS" "N8N_WEBHOOK_URL" "BACKUP_PATHS" "PRUNE_POLICY" "CHECK_ARGS" "CACHE_CLEANUP_DAYS" ) for VAR_NAME in "${VARS_TO_SANITIZE[@]}"; do # Using indirect expansion to get the value of the variable named by VAR_NAME VAR_VALUE="${!VAR_NAME}" # Sanitize the value by removing double quotes SANITIZED_VALUE=${VAR_VALUE//\"/} # Export the sanitized variable back to the current script's environment export "${VAR_NAME}"="${SANITIZED_VALUE}" # Write the export command to the profile script for future sessions echo "export ${VAR_NAME}=\"${SANITIZED_VALUE}\"" >> "${ENV_SCRIPT}" done chmod +x "${ENV_SCRIPT}" echo "Environment sanitized and persisted." # --- Persist environment for Cron --- # Save the sanitized environment to a file that the cron daemon will read. printenv > /etc/environment echo "Environment saved for cron." # --- 1. Determine Container Role --- # Default to "backup" role if not specified CONTAINER_ROLE=${CONTAINER_ROLE:-"backup"} # --- 2. Validate Core Variables --- if [ -z "$RUSTIC_PASSWORD" ]; then echo "ERROR: RUSTIC_PASSWORD environment variable is not set." exit 1 fi # --- 3. S3 Configuration & Bucket Check --- # Check for S3 variables. If they exist, configure rustic and check the bucket. if [ -n "$S3_ENDPOINT" ] && [ -n "$S3_BUCKET" ] && [ -n "$AWS_ACCESS_KEY_ID" ] && [ -n "$AWS_SECRET_ACCESS_KEY" ]; then echo "S3 environment variables detected. Configuring rustic and checking bucket..." # Set a default region if not provided S3_REGION=${S3_REGION:-"us-east-1"} # --- Create rustic config file --- mkdir -p /etc/rustic cat < /etc/rustic/rustic.toml [repository] repository = "opendal:s3" password = "${RUSTIC_PASSWORD}" [repository.options] endpoint = "${S3_ENDPOINT}" bucket = "${S3_BUCKET}" region = "${S3_REGION}" access_key_id = "${AWS_ACCESS_KEY_ID}" secret_access_key = "${AWS_SECRET_ACCESS_KEY}" EOF echo "Rustic config created at /etc/rustic/rustic.toml" # --- Check and Create S3 Bucket --- echo "Configuring MinIO client for endpoint: ${S3_ENDPOINT}" mc alias set s3_storage "${S3_ENDPOINT}" "${AWS_ACCESS_KEY_ID}" "${AWS_SECRET_ACCESS_KEY}" --api S3v4 if mc ls "s3_storage/${S3_BUCKET}" > /dev/null 2>&1; then echo "Bucket '${S3_BUCKET}' already exists." else echo "Bucket '${S3_BUCKET}' not found. Creating it..." mc mb "s3_storage/${S3_BUCKET}" echo "Bucket '${S3_BUCKET}' created successfully." fi else echo "WARNING: S3 environment variables (S3_ENDPOINT, S3_BUCKET, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) are not fully set." echo "Skipping S3 configuration and bucket creation. Rustic might fail if not configured otherwise." fi # --- 4. Role-based Execution --- if [ "$CONTAINER_ROLE" = "backup" ]; then echo "--- Starting in Backup Mode ---" if [ -z "$CRON_SCHEDULE" ]; then echo "ERROR: CRON_SCHEDULE environment variable is not set for backup mode." exit 1 fi # Create Dynamic Crontab CRONTAB_FILE="/var/spool/cron/crontabs/root" echo "Creating crontab with full PATH..." # Define the PATH for the cron environment to ensure all binaries are found. echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" > "${CRONTAB_FILE}" # Add the cron job, redirecting all output to the container's stdout/stderr echo "${CRON_SCHEDULE} /usr/local/bin/backup.sh > /proc/1/fd/1 2>&1" >> "${CRONTAB_FILE}" chmod 600 ${CRONTAB_FILE} # Start Cron Daemon echo "Starting cron daemon in foreground..." exec /usr/sbin/cron -f -L 8 elif [ "$CONTAINER_ROLE" = "prune" ]; then echo "--- Starting in Prune (maintenance) Mode ---" if [ -z "$CRON_SCHEDULE" ]; then echo "ERROR: CRON_SCHEDULE environment variable is not set for prune mode." exit 1 fi CRONTAB_FILE="/var/spool/cron/crontabs/root" echo "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" > "${CRONTAB_FILE}" echo "${CRON_SCHEDULE} /usr/local/bin/prune.sh > /proc/1/fd/1 2>&1" >> "${CRONTAB_FILE}" chmod 600 ${CRONTAB_FILE} echo "Starting cron daemon in foreground..." exec /usr/sbin/cron -f -L 8 elif [ "$CONTAINER_ROLE" = "restore" ]; then echo "--- Starting in Restore Mode ---" echo "The container is now running and ready for restore operations." echo "To restore a backup, run the following command:" echo " docker exec -it ${HOSTNAME} /usr/local/bin/restore.sh" echo "--------------------------------------------------------" # Keep container alive exec tail -f /dev/null else echo "ERROR: Invalid CONTAINER_ROLE specified: '${CONTAINER_ROLE}'. Use 'backup' or 'restore'." exit 1 fi