diff --git a/README.md b/README.md index 9b5658f..646867f 100644 --- a/README.md +++ b/README.md @@ -29,3 +29,58 @@ The easiest way to upgrade is to start over, removing all the volumes and therefore wiping out any configurations you have changed: `docker-compose down --volumes && docker-compose build --pull && docker-compose -p icinga-playground up -d` + +## Backup your settings + +`bash backup.sh` + +``` +Stopping Docker Compose services for a consistent backup... +[+] Stopping 7/7 +Container icinga-playground-icingadb-1 Stopped 0.7s +Container icinga-playground-director-1 Stopped 1.1s +Container icinga-playground-icingaweb-1 Stopped 2.1s +Container icinga-playground-icinga2-1 Stopped 0.8s +Container icinga-playground-init-icinga2-1 Stopped 0.0s +Container icinga-playground-icingadb-redis-1 Stopped 0.5s +Container icinga-playground-mysql-1 Stopped 1.2s +Starting backup of volumes: icinga-playground_icinga2, icinga-playground_icingaweb, icinga-playground_mysql +Creating tar archive... +./ +./mysql/ +./mysql/multi-master.info +./mysql/performance_schema/ +./mysql/performance_schema/db.opt +./mysql/aria_log_control +./mysql/mysql/ +./mysql/director/ +./mysql/icingaweb/ +./mysql/sys/ +./icinga2/ +./icinga2/etc/ +./icinga2/etc/icinga2/ +./icinga2/var/log/ +./icinga2/var/lib/ +./icingaweb/ +./icingaweb/etc/ +./icingaweb/var/ +./icingaweb/var/lib/ +./icingaweb/var/lib/icingaweb2/ +Backup successful! Archive saved to: /opt/icinga-monitoring-main/backups/icinga-playground_volumes_backup_20251025_215119.tar.gz +Starting Docker Compose services back up... +[+] Running 7/7 +Container icinga-playground-mysql-1 Healthy 8.1s +Container icinga-playground-icingadb-redis-1 Healthy 7.2s +Container icinga-playground-init-icinga2-1 Exited 1.2s +Container icinga-playground-icingaweb-1 Started 0.7s +Container icinga-playground-icingadb-1 Started 0.5s +Container icinga-playground-icinga2-1 Healthy 10.9s +Container icinga-playground-director-1 Started 0.2s +``` + +## Restore backups + +``` +bash restore.sh +Enter the full path to the backup TAR.GZ file (e.g., ./backups/icinga-playground_volumes_backup_YYYYMMDD_HHMMSS.tar.gz): ./backups/icinga-playground_volumes_backup_20251025_215119.tar.gz +``` diff --git a/backup.sh b/backup.sh new file mode 100644 index 0000000..012816e --- /dev/null +++ b/backup.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# backup.sh - Script to backup Icinga Docker Compose volumes + +# Define variables +PROJECT_NAME="icinga-playground" +BACKUP_DIR="$(pwd)/backups" +BACKUP_FILE="${BACKUP_DIR}/${PROJECT_NAME}_volumes_backup_$(date +%Y%m%d_%H%M%S).tar.gz" + +# Create backup directory if it doesn't exist +mkdir -p "$BACKUP_DIR" + +echo "Stopping Docker Compose services for a consistent backup..." +# Use -p to explicitly target the running containers +docker compose -p "${PROJECT_NAME}" stop + +# Check if services stopped successfully +if [ $? -ne 0 ]; then + echo "ERROR: Failed to stop Docker Compose services. Aborting backup." + # Attempt to start services again if stop failed, to leave things as they were + docker compose -p "${PROJECT_NAME}" start + exit 1 +fi + +echo "Starting backup of volumes: ${PROJECT_NAME}_icinga2, ${PROJECT_NAME}_icingaweb, ${PROJECT_NAME}_mysql" + +# Run a temporary container to archive the volumes, using the correct prefix +docker run --rm \ + -v "${BACKUP_DIR}:/backup" \ + -v "${PROJECT_NAME}_icinga2:/vols/icinga2:ro" \ + -v "${PROJECT_NAME}_icingaweb:/vols/icingaweb:ro" \ + -v "${PROJECT_NAME}_mysql:/vols/mysql:ro" \ + alpine /bin/sh -c "\ + echo 'Creating tar archive...'; \ + tar -cvzf /backup/$(basename "$BACKUP_FILE") -C /vols . + " + +if [ $? -eq 0 ]; then + echo "Backup successful! Archive saved to: $BACKUP_FILE" +else + echo "Backup failed during tar operation." +fi + +echo "Starting Docker Compose services back up..." +# Use -p to ensure the correct services are started +docker compose -p "${PROJECT_NAME}" start diff --git a/restore.sh b/restore.sh new file mode 100644 index 0000000..b30bd40 --- /dev/null +++ b/restore.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# restore.sh - Script to restore Icinga Docker Compose volumes from a backup + +# Define variables +PROJECT_NAME="icinga-playground" +VOLUMES_TO_MANAGE="${PROJECT_NAME}_icinga2 ${PROJECT_NAME}_icingaweb ${PROJECT_NAME}_mysql" + +# --- USER INPUT --- +# You need to provide the exact path to the backup file you want to restore. +read -p "Enter the full path to the backup TAR.GZ file (e.g., ./backups/${PROJECT_NAME}_volumes_backup_YYYYMMDD_HHMMSS.tar.gz): " BACKUP_FILE_PATH + +if [ ! -f "$BACKUP_FILE_PATH" ]; then + echo "ERROR: Backup file not found at $BACKUP_FILE_PATH. Aborting restore." + exit 1 +fi +# --- END USER INPUT --- + +echo "Stopping and removing running services..." +# Use -p to explicitly target the running containers +docker compose -p "${PROJECT_NAME}" stop +docker compose -p "${PROJECT_NAME}" rm -f + +# Safety confirmation before deleting data +read -p "WARNING: This will permanently DELETE the current data in the volumes. Continue? (yes/no): " CONFIRMATION +if [[ "$CONFIRMATION" != "yes" ]]; then + echo "Restore cancelled by user." + exit 0 +fi + +echo "Deleting existing Docker volumes: $VOLUMES_TO_MANAGE" +docker volume rm $VOLUMES_TO_MANAGE + +echo "Creating empty volumes for the restore..." +for vol in $VOLUMES_TO_MANAGE; do + docker volume create "$vol" +done + +echo "Starting restore from: $BACKUP_FILE_PATH" + +# Run a temporary container to extract the archive into the volumes +docker run --rm \ + -v "$(dirname "$BACKUP_FILE_PATH"):/backup_source" \ + -v "${PROJECT_NAME}_icinga2:/vols/icinga2" \ + -v "${PROJECT_NAME}_icingaweb:/vols/icingaweb" \ + -v "${PROJECT_NAME}_mysql:/vols/mysql" \ + alpine /bin/sh -c "\ + echo 'Extracting backup...'; \ + tar -xvpzf /backup_source/$(basename "$BACKUP_FILE_PATH") -C /vols + " + +if [ $? -eq 0 ]; then + echo "Restore successful!" +else + echo "Restore failed during tar extraction." + exit 1 +fi + +echo "Starting Docker Compose services with restored data..." +# Use -p to ensure the new services are correctly named +docker compose -p "${PROJECT_NAME}" up -d