#!/bin/bash # --- Configuration --- # The root directory where your docker-compose.yml and data folders are located BACKUP_SOURCE_DIR="$(pwd)" # The target directory for the backup tarball (must exist on the host) BACKUP_TARGET_DIR="$(pwd)/backup" # The name of the backup file (without extension) BACKUP_NAME="mealie_backup" # Data volumes specified in your docker-compose.yml DATA_VOLUMES=( "mealie-data" "mealie-pgdata" ) # Configuration file CONFIG_FILE="docker-compose.yml" # --- Script Logic --- TIMESTAMP=$(date +%Y%m%d_%H%M%S) TARBALL_FILENAME="${BACKUP_NAME}_${TIMESTAMP}.tar.gz" FULL_TARBALL_PATH="${BACKUP_TARGET_DIR}/${TARBALL_FILENAME}" TEMP_DIR="mealie_backup_content" echo "Starting Mealie backup at ${TIMESTAMP}..." echo "----------------------------------------" # 1. 🛑 STOP CONTAINERS for Data Integrity echo "1. Stopping Mealie services to ensure data consistency..." # Stop the services gracefully using the docker-compose file docker compose -f "${CONFIG_FILE}" stop mealie postgres if [ $? -ne 0 ]; then echo "❌ Error: Could not stop one or more services. Aborting backup." >&2 exit 1 fi echo "Services successfully stopped." echo "---" # 2. Create a temporary directory to structure the backup content echo "2. Creating temporary structure: ${TEMP_DIR}/" mkdir -p "${TEMP_DIR}" # 3. Copy the configuration file and data volumes echo " Copying configuration file: ${CONFIG_FILE}" cp "${CONFIG_FILE}" "${TEMP_DIR}/" for volume in "${DATA_VOLUMES[@]}"; do SOURCE_PATH="${BACKUP_SOURCE_DIR}/${volume}" if [ -d "${SOURCE_PATH}" ]; then echo " Copying data volume: ${volume}/" # Using 'cp -r' to copy the entire data folder cp -r "${SOURCE_PATH}" "${TEMP_DIR}/" else echo "Warning: Data volume ${volume} not found! Skipping." >&2 fi done echo "---" # 4. Create the target directory and the compressed tarball mkdir -p "${BACKUP_TARGET_DIR}" echo "3. Creating tarball: ${FULL_TARBALL_PATH}" tar -czf "${FULL_TARBALL_PATH}" "${TEMP_DIR}" # 5. Cleanup the temporary directory echo "4. Cleaning up temporary files." rm -rf "${TEMP_DIR}" echo "---" # 6. ✅ RESTART CONTAINERS echo "5. Restarting Mealie services with 'docker compose up -d'..." docker compose -f "${CONFIG_FILE}" up -d mealie postgres if [ $? -ne 0 ]; then echo "⚠️ Warning: Services may not have restarted correctly. Check logs manually." >&2 else echo "✅ Services restarted successfully." fi echo "---" # 7. Verification and final output if [ -f "${FULL_TARBALL_PATH}" ]; then SIZE=$(du -h "${FULL_TARBALL_PATH}" | awk '{print $1}') echo "🎉 **Backup Successful!** File saved to: ${FULL_TARBALL_PATH} (${SIZE})" else echo "❌ **Backup Failed!** Tarball was not created." >&2 exit 1 fi