Бэкап Docker Compose: автоматизация через Bash и Crontab

Золотые правила автообновления Docker
За 20 лет работы я усвоил железное правило: данные без бэкапа — это данные, которых уже нет. Сегодня разберём, как правильно бэкапить Docker Compose приложения с помощью Bash скриптов и Crontab. Никаких платных решений — только открытый код и проверенные временем инструменты.

Что нужно бэкапить в Docker Compose инфраструктуре

Когда новички думают о бэкапе Docker контейнеров, они часто забывают о критичных компонентах. Вот полный список того, что должно попасть в резервную копию:

  • Docker volumes — здесь живут ваши базы данных, загруженные файлы, конфигурации
  • Файлы docker-compose.yml и .env — конфигурация всей инфраструктуры
  • Bind mounts — примонтированные директории с хоста
  • Образы контейнеров (опционально) — если используете кастомные образы
  • Сетевые настройки — для сложных конфигураций

Забудьте про бэкап самих контейнеров — это бессмысленно. Контейнеры эфемерны, важны только данные и конфигурация.

Пример 1: Базовый скрипт бэкапа Docker Compose

Начнём с простого, но функционального скрипта, который покрывает 80% задач. Этот скрипт я использую для своих домашних проектов уже 3 года — ни одного сбоя.

#!/bin/bash
# Файл: /opt/scripts/docker-backup-basic.sh
# Базовый скрипт бэкапа Docker Compose

set -euo pipefail  # Прерывать при ошибках

# ============= КОНФИГУРАЦИЯ =============
COMPOSE_DIR="/opt/myapp"
BACKUP_ROOT="/backups/docker"
BACKUP_RETENTION_DAYS=30
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="${BACKUP_ROOT}/${DATE}"

# ============= СОЗДАНИЕ ДИРЕКТОРИИ =============
mkdir -p "$BACKUP_DIR"

echo "$(date) - Начало бэкапа в $BACKUP_DIR"

# ============= БЭКАП КОНФИГУРАЦИИ =============
echo "Сохранение docker-compose.yml и .env файлов..."
cd "$COMPOSE_DIR" || exit 1
cp docker-compose.yml "$BACKUP_DIR/"
[ -f .env ] && cp .env "$BACKUP_DIR/"

# Сохранение списка запущенных контейнеров
docker-compose ps > "$BACKUP_DIR/containers-state.txt"

# ============= БЭКАП VOLUMES =============
echo "Бэкап Docker volumes..."

# Получаем список всех volumes проекта
VOLUMES=$(docker volume ls --format '{{.Name}}' | grep "$(basename $COMPOSE_DIR)")

for volume in $VOLUMES; do
    echo "Бэкапим volume: $volume"
    docker run --rm \
        -v "${volume}:/source:ro" \
        -v "${BACKUP_DIR}:/backup" \
        alpine \
        tar czf "/backup/${volume}.tar.gz" -C /source .
done

# ============= БЭКАП BIND MOUNTS =============
echo "Бэкап bind mounts..."
if [ -d "${COMPOSE_DIR}/data" ]; then
    tar czf "${BACKUP_DIR}/bind-mounts.tar.gz" -C "${COMPOSE_DIR}" data
fi

# ============= СОЗДАНИЕ АРХИВА =============
echo "Создание итогового архива..."
cd "$BACKUP_ROOT" || exit 1
tar czf "${DATE}.tar.gz" "${DATE}"
rm -rf "${DATE}"  # Удаляем временную директорию

# ============= ОЧИСТКА СТАРЫХ БЭКАПОВ =============
echo "Удаление бэкапов старше ${BACKUP_RETENTION_DAYS} дней..."
find "$BACKUP_ROOT" -name "*.tar.gz" -type f -mtime +${BACKUP_RETENTION_DAYS} -delete

echo "$(date) - Бэкап завершён: ${BACKUP_ROOT}/${DATE}.tar.gz"
echo "Размер: $(du -h ${BACKUP_ROOT}/${DATE}.tar.gz | cut -f1)"

Установка и запуск базового скрипта

# Создаём директории
mkdir -p /opt/scripts /backups/docker

# Сохраняем скрипт
nano /opt/scripts/docker-backup-basic.sh
# Вставляем код выше

# Делаем исполняемым
chmod +x /opt/scripts/docker-backup-basic.sh

# Тестовый запуск
/opt/scripts/docker-backup-basic.sh

# Проверяем результат
ls -lh /backups/docker/

Пример 2: Продвинутый скрипт с остановкой контейнеров

Для баз данных (PostgreSQL, MySQL, MongoDB) простого копирования volumes недостаточно — можно получить повреждённые данные. Правильный способ — остановить контейнеры или использовать нативные инструменты дампа.

#!/bin/bash
# Файл: /opt/scripts/docker-backup-advanced.sh
# Продвинутый <a href="https://it-apteka.com/ustanovka-n8n-v-lxc-kontejner-proxmox-polnaja-instrukcija-ot-a-do-ja/"  data-wpil-monitor-id="353">скрипт с остановкой контейнеров</a> и дампом БД

set -euo pipefail

# ============= КОНФИГУРАЦИЯ =============
COMPOSE_DIR=&quot;/opt/myapp&quot;
BACKUP_ROOT=&quot;/backups/docker&quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;${BACKUP_ROOT}/${DATE}&quot;
LOG_FILE=&quot;/var/log/docker-backup.log&quot;

# Функция логирования
log() {
    echo &quot;$(date &#039;+%Y-%m-%d %H:%M:%S&#039;) - $1&quot; | tee -a &quot;$LOG_FILE&quot;
}

# ============= СОЗДАНИЕ СТРУКТУРЫ =============
mkdir -p &quot;$BACKUP_DIR&quot;/{volumes,configs,dumps}

log &quot;=== Начало бэкапа ===&quot;

# ============= ПРОВЕРКА DOCKER =============
if ! docker ps &gt; /dev/null 2&gt;&amp;1; then
    log &quot;ERROR: Docker недоступен!&quot;
    exit 1
fi

cd &quot;$COMPOSE_DIR&quot; || exit 1

# ============= БЭКАП КОНФИГУРАЦИЙ =============
log &quot;Сохранение конфигураций...&quot;
cp docker-compose.yml &quot;$BACKUP_DIR/configs/&quot;
[ -f .env ] &amp;&amp; cp .env &quot;$BACKUP_DIR/configs/&quot;
docker-compose config &gt; &quot;$BACKUP_DIR/configs/docker-compose-resolved.yml&quot;

# ============= ДАМП POSTGRESQL =============
log &quot;Создание дампа PostgreSQL...&quot;
docker-compose exec -T postgres pg_dumpall -U postgres | \
    gzip &gt; &quot;$BACKUP_DIR/dumps/postgres-dump.sql.gz&quot;

# Или для конкретной БД
# docker-compose exec -T postgres pg_dump -U postgres mydb | \
#     gzip &gt; &quot;$BACKUP_DIR/dumps/mydb.sql.gz&quot;

# ============= ДАМП MYSQL =============
log &quot;Создание дампа MySQL...&quot;
docker-compose exec -T mysql mysqldump -u root -p&quot;${MYSQL_ROOT_PASSWORD}&quot; --all-databases | \
    gzip &gt; &quot;$BACKUP_DIR/dumps/mysql-dump.sql.gz&quot;

# ============= ДАМП MONGODB =============
log &quot;Создание дампа MongoDB...&quot;
docker-compose exec -T mongodb mongodump --archive --gzip | \
    cat &gt; &quot;$BACKUP_DIR/dumps/mongodb-dump.archive.gz&quot;

# ============= ОСТАНОВКА КОНТЕЙНЕРОВ =============
log &quot;Остановка контейнеров для консистентного бэкапа...&quot;
docker-compose stop

# ============= БЭКАП VOLUMES =============
log &quot;Бэкап всех volumes...&quot;
VOLUMES=$(docker volume ls --format &#039;{{.Name}}&#039; | grep &quot;$(basename $COMPOSE_DIR)&quot;)

for volume in $VOLUMES; do
    log &quot;Бэкап volume: $volume&quot;
    docker run --rm \
        -v &quot;${volume}:/source:ro&quot; \
        -v &quot;${BACKUP_DIR}/volumes:/backup&quot; \
        alpine \
        tar czf &quot;/backup/${volume}.tar.gz&quot; -C /source .
done

# ============= ЗАПУСК КОНТЕЙНЕРОВ =============
log &quot;Запуск контейнеров обратно...&quot;
docker-compose start

# Ждём готовности
sleep 10

# Проверяем, что всё запустилось
if docker-compose ps | grep -q &quot;Exit&quot;; then
    log &quot;WARNING: Некоторые контейнеры не запустились!&quot;
fi

# ============= СОЗДАНИЕ ФИНАЛЬНОГО АРХИВА =============
log &quot;Создание итогового архива...&quot;
cd &quot;$BACKUP_ROOT&quot; || exit 1
tar czf &quot;${DATE}.tar.gz&quot; &quot;${DATE}&quot;
BACKUP_SIZE=$(du -h &quot;${DATE}.tar.gz&quot; | cut -f1)
rm -rf &quot;${DATE}&quot;

# ============= ОЧИСТКА СТАРЫХ БЭКАПОВ =============
log &quot;Очистка старых бэкапов (&gt;30 дней)...&quot;
find &quot;$BACKUP_ROOT&quot; -name &quot;*.tar.gz&quot; -type f -mtime +30 -delete

log &quot;=== Бэкап завершён успешно ===&quot;
log &quot;Файл: ${BACKUP_ROOT}/${DATE}.tar.gz&quot;
log &quot;Размер: ${BACKUP_SIZE}&quot;

Пример 3: Скрипт бэкапа без остановки контейнеров

Для production систем, которые нельзя останавливать, используем «горячий» бэкап через нативные инструменты баз данных без downtime.

#!/bin/bash
# Файл: /opt/scripts/docker-backup-hot.sh
# Горячий бэкап без остановки контейнеров

set -euo pipefail

COMPOSE_DIR=&quot;/opt/myapp&quot;
BACKUP_ROOT=&quot;/backups/docker&quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=&quot;${BACKUP_ROOT}/${DATE}&quot;

mkdir -p &quot;$BACKUP_DIR&quot;/{dumps,configs}

echo &quot;$(date) - Горячий бэкап без остановки сервисов&quot;

cd &quot;$COMPOSE_DIR&quot; || exit 1

# ============= КОНФИГУРАЦИИ =============
cp docker-compose.yml .env &quot;$BACKUP_DIR/configs/&quot; 2&gt;/dev/null || true

# ============= POSTGRESQL HOT <a class="wpil_keyword_link" href="https://it-apteka.com/category/rezervnoe-kopirovanie/"   title="Резервное копирование" data-wpil-keyword-link="linked"  data-wpil-monitor-id="47">BACKUP</a> =============
# Используем pg_dump вместо копирования файлов
docker-compose exec -T postgres pg_dump -Fc -U postgres mydb \
    &gt; &quot;$BACKUP_DIR/dumps/postgres-mydb.dump&quot;

# Или все базы
docker-compose exec -T postgres pg_dumpall -U postgres \
    | gzip &gt; &quot;$BACKUP_DIR/dumps/postgres-all.sql.gz&quot;

# ============= MYSQL HOT BACKUP =============
docker-compose exec -T mysql sh -c \
    &#039;mysqldump -u root -p&quot;$MYSQL_ROOT_PASSWORD&quot; --single-transaction --quick --all-databases&#039; \
    | gzip &gt; &quot;$BACKUP_DIR/dumps/mysql-all.sql.gz&quot;

# ============= MONGODB HOT BACKUP =============
docker-compose exec -T mongodb mongodump --archive --gzip \
    &gt; &quot;$BACKUP_DIR/dumps/mongodb.archive.gz&quot;

# ============= REDIS SNAPSHOT =============
# Форсируем сохранение и копируем RDB файл
docker-compose exec -T redis redis-cli BGSAVE
sleep 5

docker-compose exec -T redis sh -c &#039;cat /data/dump.rdb&#039; \
    &gt; &quot;$BACKUP_DIR/dumps/redis-dump.rdb&quot;

# ============= БЭКАП UPLOADED FILES =============
# Если есть volume с файлами пользователей
docker run --rm \
    -v myapp_uploads:/source:ro \
    -v &quot;${BACKUP_DIR}:/backup&quot; \
    alpine \
    tar czf /backup/uploads.tar.gz -C /source .

# ============= АРХИВИРОВАНИЕ =============
cd &quot;$BACKUP_ROOT&quot;
tar czf &quot;${DATE}.tar.gz&quot; &quot;${DATE}&quot;
rm -rf &quot;${DATE}&quot;

echo &quot;$(date) - Бэкап завершён: ${BACKUP_ROOT}/${DATE}.tar.gz&quot;

Пример 4: Скрипт с отправкой бэкапа в облако

Локальные бэкапы — это хорошо, но что если сгорит сервер? Правильный подход — дублировать бэкапы в облако. Покажу интеграцию с популярными сервисами.

#!/bin/bash
# Файл: /opt/scripts/docker-backup-cloud.sh
# Бэкап с отправкой в облако (AWS S3, Backblaze B2, rsync)

set -euo pipefail

# ============= КОНФИГУРАЦИЯ =============
COMPOSE_DIR=&quot;/opt/myapp&quot;
BACKUP_ROOT=&quot;/backups/docker&quot;
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE=&quot;${BACKUP_ROOT}/${DATE}.tar.gz&quot;

# Настройки облачных хранилищ
S3_BUCKET=&quot;s3://my-backups-bucket/docker/&quot;
B2_BUCKET=&quot;b2://my-backup-bucket/docker/&quot;
REMOTE_SERVER=&quot;backup@backup-server.com:/backups/docker/&quot;

# <a class="wpil_keyword_link" href="https://t.me/it_apteka_com/34"   title="Telegram" data-wpil-keyword-link="linked"  data-wpil-monitor-id="268">Telegram</a> уведомления
TELEGRAM_BOT_TOKEN=&quot;your-bot-token&quot;
TELEGRAM_CHAT_ID=&quot;your-chat-id&quot;

# ============= ФУНКЦИИ =============
send_telegram() {
    curl -s -X POST &quot;https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage&quot; \
        -d chat_id=&quot;${TELEGRAM_CHAT_ID}&quot; \
        -d text=&quot;$1&quot; &gt; /dev/null
}

# ============= СОЗДАНИЕ БЭКАПА =============
echo &quot;$(date) - Создание локального бэкапа...&quot;
send_telegram &quot;🔄 Начало бэкапа Docker на $(hostname)&quot;

mkdir -p &quot;${BACKUP_ROOT}/tmp&quot;
TEMP_DIR=&quot;${BACKUP_ROOT}/tmp/${DATE}&quot;
mkdir -p &quot;$TEMP_DIR&quot;

cd &quot;$COMPOSE_DIR&quot; || exit 1

# Конфигурации
cp docker-compose.yml .env &quot;$TEMP_DIR/&quot; 2&gt;/dev/null || true

# Дампы БД
docker-compose exec -T postgres pg_dumpall -U postgres | \
    gzip &gt; &quot;$TEMP_DIR/postgres.sql.gz&quot;

# Volumes
VOLUMES=$(docker volume ls --format &#039;{{.Name}}&#039; | grep &quot;$(basename $COMPOSE_DIR)&quot;)
for volume in $VOLUMES; do
    docker run --rm \
        -v &quot;${volume}:/source:ro&quot; \
        -v &quot;${TEMP_DIR}:/backup&quot; \
        alpine \
        tar czf &quot;/backup/${volume}.tar.gz&quot; -C /source .
done

# Создание архива
cd &quot;${BACKUP_ROOT}/tmp&quot;
tar czf &quot;$BACKUP_FILE&quot; &quot;${DATE}&quot;
rm -rf &quot;${TEMP_DIR}&quot;

BACKUP_SIZE=$(du -h &quot;$BACKUP_FILE&quot; | cut -f1)
echo &quot;Локальный бэкап создан: $BACKUP_FILE ($BACKUP_SIZE)&quot;

# ============= ОТПРАВКА В AWS S3 =============
if command -v aws &amp;&gt; /dev/null; then
    echo &quot;Отправка в AWS S3...&quot;
    if aws s3 cp &quot;$BACKUP_FILE&quot; &quot;${S3_BUCKET}&quot; --storage-class STANDARD_IA; then
        echo &quot;✓ Успешно загружено в S3&quot;
        send_telegram &quot;✅ Бэкап загружен в S3: ${BACKUP_SIZE}&quot;
    else
        echo &quot;✗ Ошибка загрузки в S3&quot;
        send_telegram &quot;❌ Ошибка загрузки в S3&quot;
    fi
fi

# ============= ОТПРАВКА В BACKBLAZE B2 =============
if command -v b2 &amp;&gt; /dev/null; then
    echo &quot;Отправка в Backblaze B2...&quot;
    if b2 upload-file my-backup-bucket &quot;$BACKUP_FILE&quot; &quot;docker/${DATE}.tar.gz&quot;; then
        echo &quot;✓ Успешно загружено в B2&quot;
    else
        echo &quot;✗ Ошибка загрузки в B2&quot;
    fi
fi

# ============= ОТПРАВКА НА УДАЛЁННЫЙ СЕРВЕР =============
if command -v rsync &amp;&gt; /dev/null; then
    echo &quot;Отправка на удалённый сервер через rsync...&quot;
    if rsync -avz --progress &quot;$BACKUP_FILE&quot; &quot;$REMOTE_SERVER&quot;; then
        echo &quot;✓ Успешно скопировано на удалённый сервер&quot;
        send_telegram &quot;✅ Бэкап скопирован на backup-server&quot;
    else
        echo &quot;✗ Ошибка копирования на удалённый сервер&quot;
        send_telegram &quot;❌ Ошибка копирования на backup-server&quot;
    fi
fi

# ============= ОЧИСТКА ЛОКАЛЬНЫХ БЭКАПОВ =============
echo &quot;Очистка локальных бэкапов старше 7 дней...&quot;
find &quot;$BACKUP_ROOT&quot; -maxdepth 1 -name &quot;*.tar.gz&quot; -type f -mtime +7 -delete

# Очистка в S3 (оставляем последние 30 дней)
if command -v aws &amp;&gt; /dev/null; then
    aws s3 ls &quot;${S3_BUCKET}&quot; | while read -r line; do
        FILE_DATE=$(echo &quot;$line&quot; | awk &#039;{print $1}&#039;)
        FILE_NAME=$(echo &quot;$line&quot; | awk &#039;{print $4}&#039;)
        if [ -n &quot;$FILE_DATE&quot; ] &amp;&amp; [ -n &quot;$FILE_NAME&quot; ]; then
            AGE_DAYS=$(( ($(date +%s) - $(date -d &quot;$FILE_DATE&quot; +%s)) / 86400 ))
            if [ $AGE_DAYS -gt 30 ]; then
                echo &quot;Удаление старого бэкапа из S3: $FILE_NAME&quot;
                aws s3 rm &quot;${S3_BUCKET}${FILE_NAME}&quot;
            fi
        fi
    done
fi

echo &quot;$(date) - Бэкап завершён успешно&quot;
send_telegram &quot;✅ Бэкап Docker завершён успешно
Размер: ${BACKUP_SIZE}
Сервер: $(hostname)&quot;

Установка AWS CLI для работы с S3

# Установка AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

# Настройка credentials
aws configure
# AWS Access Key ID: ваш_ключ
# AWS Secret Access Key: ваш_секрет
# Default region name: eu-central-1
# Default output format: json

# Проверка
aws s3 ls

Пример 5: Настройка Crontab для автоматического бэкапа

Скрипты готовы, теперь автоматизируем их запуск через cron. Покажу несколько стратегий бэкапа для разных сценариев.

# Открываем crontab для редактирования
crontab -e

# ============= ВАРИАНТ 1: ЕЖЕДНЕВНЫЙ БЭКАП В 3 НОЧИ =============
0 3 * * * /opt/scripts/docker-backup-basic.sh >> /var/log/docker-backup-cron.log 2>&1

# ============= ВАРИАНТ 2: КАЖДЫЕ 6 ЧАСОВ =============
0 */6 * * * /opt/scripts/docker-backup-hot.sh >> /var/log/docker-backup-cron.log 2>&1

# ============= ВАРИАНТ 3: ЕЖЕДНЕВНО + ОБЛАКО В ВОСКРЕСЕНЬЕ =============
# Ежедневный локальный бэкап в 02:00
0 2 * * * /opt/scripts/docker-backup-basic.sh >> /var/log/docker-backup-cron.log 2>&1

# Недельный бэкап в облако каждое воскресенье в 04:00
0 4 * * 0 /opt/scripts/docker-backup-cloud.sh >> /var/log/docker-backup-cron.log 2>&1

# ============= ВАРИАНТ 4: СТРАТЕГИЯ 3-2-1 =============
# 3 копии данных, 2 разных носителя, 1 offsite
# Ежедневно в 01:00 - локальный бэкап
0 1 * * * /opt/scripts/docker-backup-basic.sh >> /var/log/docker-backup-cron.log 2>&1

# Ежедневно в 02:00 - на второй диск
0 2 * * * rsync -a /backups/docker/ /mnt/backup-disk/docker/ >> /var/log/docker-backup-cron.log 2>&1

# Еженедельно в воскресенье 03:00 - в облако
0 3 * * 0 /opt/scripts/docker-backup-cloud.sh >> /var/log/docker-backup-cron.log 2>&1

# ============= ПРОВЕРКА CRONTAB =============
# Список всех задач
crontab -l

# Просмотр логов cron
tail -f /var/log/docker-backup-cron.log

# Или системные логи cron
grep CRON /var/log/syslog | tail -20

Расписание cron: шпаргалка по синтаксису

# Формат: минута час день_месяца месяц день_недели команда
# * * * * * команда
# │ │ │ │ │
# │ │ │ │ └─── день недели (0-7, 0 и 7 = воскресенье)
# │ │ │ └───── месяц (1-12)
# │ │ └─────── день месяца (1-31)
# │ └───────── час (0-23)
# └─────────── минута (0-59)

# Примеры популярных расписаний:

# Каждый день в 02:30
30 2 * * *

# Каждый понедельник в 05:00
0 5 * * 1

# Первого числа каждого месяца в 00:00
0 0 1 * *

# Каждые 12 часов
0 */12 * * *

# Каждые 30 минут
*/30 * * * *

# Рабочие дни (пн-пт) в 18:00
0 18 * * 1-5

# Выходные (сб-вс) в 10:00
0 10 * * 6,7

Продвинутый скрипт восстановления из бэкапа

Бэкап без возможности восстановления — это не бэкап. Вот скрипт для быстрого recovery после сбоя.

#!/bin/bash
# Файл: /opt/scripts/docker-restore.sh
# Восстановление из бэкапа

set -euo pipefail

# ============= ПАРАМЕТРЫ =============
if [ $# -lt 1 ]; then
    echo "Использование: $0 <путь_к_бэкапу.tar.gz>"
    echo "Пример: $0 /backups/docker/20240120_030000.tar.gz"
    exit 1
fi

BACKUP_FILE="$1"
RESTORE_DIR="/opt/restore-$(date +%Y%m%d_%H%M%S)"
COMPOSE_DIR="/opt/myapp"

# ============= ПРОВЕРКИ =============
if [ ! -f "$BACKUP_FILE" ]; then
    echo "ERROR: Файл бэкапа не найден: $BACKUP_FILE"
    exit 1
fi

echo "Восстановление из: $BACKUP_FILE"
echo "Директория восстановления: $RESTORE_DIR"
read -p "Продолжить? (yes/no): " CONFIRM

if [ "$CONFIRM" != "yes" ]; then
    echo "Отменено пользователем"
    exit 0
fi

# ============= РАСПАКОВКА БЭКАПА =============
echo "Распаковка бэкапа..."
mkdir -p "$RESTORE_DIR"
tar xzf "$BACKUP_FILE" -C "$RESTORE_DIR" --strip-components=1

# ============= ОСТАНОВКА ТЕКУЩИХ КОНТЕЙНЕРОВ =============
echo "Остановка текущих контейнеров..."
cd "$COMPOSE_DIR" || exit 1
docker-compose down -v  # -v удалит volumes

# ============= ВОССТАНОВЛЕНИЕ КОНФИГУРАЦИЙ =============
echo "Восстановление конфигураций..."
cp "$RESTORE_DIR"/configs/* "$COMPOSE_DIR/" 2>/dev/null || \
    cp "$RESTORE_DIR"/*.yml "$COMPOSE_DIR/" 2>/dev/null || true

# ============= СОЗДАНИЕ VOLUMES =============
echo "Создание volumes из docker-compose.yml..."
cd "$COMPOSE_DIR"
docker-compose up --no-start

# ============= ВОССТАНОВЛЕНИЕ VOLUMES =============
echo "Восстановление данных volumes..."
for volume_backup in "$RESTORE_DIR"/volumes/*.tar.gz "$RESTORE_DIR"/*.tar.gz; do
    if [ -f "$volume_backup" ]; then
        volume_name=$(basename "$volume_backup" .tar.gz)
        echo "Восстановление volume: $volume_name"
        
        docker run --rm \
            -v "${volume_name}:/target" \
            -v "$RESTORE_DIR":/backup \
            alpine \
            sh -c "cd /target && tar xzf /backup/$(basename $volume_backup)"
    fi
done

# ============= ВОССТАНОВЛЕНИЕ ДАМПОВ БД =============
if [ -d "$RESTORE_DIR/dumps" ]; then
    echo "Запуск контейнеров для восстановления БД..."
    docker-compose up -d
    
    # Ждём готовности БД
    echo "Ожидание готовности баз данных..."
    sleep 15
    
    # PostgreSQL
    if [ -f "$RESTORE_DIR/dumps/postgres-dump.sql.gz" ]; then
        echo "Восстановление PostgreSQL..."
        gunzip < "$RESTORE_DIR/dumps/postgres-dump.sql.gz" | \
            docker-compose exec -T postgres psql -U postgres
    fi
    
    # MySQL
    if [ -f "$RESTORE_DIR/dumps/mysql-dump.sql.gz" ]; then
        echo "Восстановление MySQL..."
        gunzip < "$RESTORE_DIR/dumps/mysql-dump.sql.gz" | \
            docker-compose exec -T mysql mysql -u root -p"${MYSQL_ROOT_PASSWORD}"
    fi
    
    # MongoDB
    if [ -f "$RESTORE_DIR/dumps/mongodb-dump.archive.gz" ]; then
        echo "Восстановление MongoDB..."
        gunzip < "$RESTORE_DIR/dumps/mongodb-dump.archive.gz" | \
            docker-compose exec -T mongodb mongorestore --archive --drop
    fi
else
    # Если дампов нет, просто запускаем контейнеры
    echo "Запуск контейнеров..."
    docker-compose up -d
fi

# ============= ПРОВЕРКА =============
echo ""
echo "============= СТАТУС ВОССТАНОВЛЕНИЯ ============="
docker-compose ps
echo ""
echo "Восстановление завершено!"
echo "Проверьте работоспособность приложения"
echo "Временные файлы в: $RESTORE_DIR"
echo ""
read -p "Удалить временные файлы? (yes/no): " CLEANUP

if [ "$CLEANUP" = "yes" ]; then
    rm -rf "$RESTORE_DIR"
    echo "Временные файлы удалены"
fi
Поделитесь:

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Прокрутить вверх