Перейти к содержанию

Восстановление системы

Процедуры восстановления Р13.Орбита из резервной копии при сбоях или после проблемного обновления.

Внимание

Восстановление из резервной копии перезапишет текущие данные. Убедитесь, что у вас есть актуальная резервная копия перед началом.


Сценарии восстановления

Сценарий 1: Откат после неудачного обновления

Когда использовать: - После обновления система не запускается - Новая версия работает некорректно - Обнаружены критические ошибки в новой версии

Что восстанавливаем: - Docker контейнер предыдущей версии - База данных метаданных (если были миграции)


Сценарий 2: Полное восстановление после сбоя

Когда использовать: - Повреждение базы данных метаданных - Потеря конфигурационных файлов - Полный сбой сервера

Что восстанавливаем: - Все компоненты системы - Конфигурация - База данных метаданных - Docker контейнер


Сценарий 3: Частичное восстановление

Когда использовать: - Потеря только конфигурации - Повреждение только определенных доменов - Нужно восстановить конкретный чат или датасет

Что восстанавливаем: - Только поврежденные компоненты


Быстрый откат после обновления

Способ 1: Откат к предыдущему Docker образу

Самый быстрый способ восстановления:

# Остановить текущий контейнер
docker stop orbita

# Удалить контейнер
docker rm orbita

# Запустить предыдущую версию
docker run -d \
  --name orbita \
  --restart unless-stopped \
  -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  -v $(pwd)/logs:/app/logs \
  your-registry.company.com/orbita:1.2.5  # Предыдущая версия

# Проверить работоспособность
curl http://localhost:8000/health

Время восстановления: 1-2 минуты


Способ 2: Использование snapshot контейнера

Если создавали snapshot перед обновлением:

# Остановить текущий контейнер
docker stop orbita
docker rm orbita

# Запустить из snapshot
docker run -d \
  --name orbita \
  --restart unless-stopped \
  -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  -v $(pwd)/logs:/app/logs \
  orbita-backup-20260120  # Имя snapshot

# Проверить
curl http://localhost:8000/health

Время восстановления: 30 секунд - 1 минута


Способ 3: Откат через Docker Compose

Если используете Docker Compose:

# 1. Отредактировать docker-compose.yml
nano docker-compose.yml

# Изменить версию образа:
# image: your-registry.company.com/orbita:1.2.5  # Старая версия

# 2. Пересоздать контейнер
docker-compose up -d orbita

# 3. Проверить
docker-compose logs -f orbita

Время восстановления: 1-2 минуты


Полное восстановление системы

Шаг 1: Подготовка

# Остановить текущий контейнер (если запущен)
docker stop orbita 2>/dev/null || true
docker rm orbita 2>/dev/null || true

# Создать временную директорию для восстановления
mkdir -p /tmp/orbita-restore
cd /tmp/orbita-restore

Шаг 2: Распаковка резервной копии

# Найти последнюю резервную копию
ls -lht /backups/orbita/*.tar.gz | head -1

# Или конкретную резервную копию
BACKUP_FILE="/backups/orbita/20260120_020000.tar.gz"

# Распаковать
tar -xzf "$BACKUP_FILE"

# Проверить содержимое
ls -la
# Должны увидеть: .env, domains/, metadata.sql, VERSION

Шаг 3: Восстановление конфигурации

# Создать рабочую директорию (если не существует)
mkdir -p ~/orbita

# Восстановить конфигурационные файлы
cp .env ~/orbita/
cp -r domains/ ~/orbita/
[ -f docker-compose.yml ] && cp docker-compose.yml ~/orbita/

# Проверить права доступа
chmod 600 ~/orbita/.env

Шаг 4: Восстановление базы данных метаданных

Для PostgreSQL:

# Проверить что PostgreSQL запущен
docker ps | grep postgres-metadata

# Удалить текущую БД (осторожно!)
docker exec -it postgres-metadata psql -U orbita_user -c "DROP DATABASE IF EXISTS orbita;"
docker exec -it postgres-metadata psql -U orbita_user -c "CREATE DATABASE orbita;"

# Восстановить из резервной копии
docker exec -i postgres-metadata psql -U orbita_user orbita < metadata.sql

# Проверить восстановление
docker exec postgres-metadata psql -U orbita_user orbita -c "\dt"

Для SQLite:

# Создать директорию если не существует
mkdir -p ~/.orbita

# Восстановить файл БД
cp metadata.db ~/.orbita/metadata.db

# Проверить целостность
sqlite3 ~/.orbita/metadata.db "PRAGMA integrity_check;"

Шаг 5: Запуск Р13.Орбита

# Перейти в рабочую директорию
cd ~/orbita

# Прочитать версию из резервной копии
cat /tmp/orbita-restore/VERSION

# Запустить контейнер с этой версией
VERSION=$(cat /tmp/orbita-restore/VERSION)

docker run -d \
  --name orbita \
  --restart unless-stopped \
  -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  -v $(pwd)/logs:/app/logs \
  your-registry.company.com/orbita:$VERSION

Шаг 6: Верификация восстановления

# Проверить что контейнер запущен
docker ps | grep orbita

# Проверить health check
curl http://localhost:8000/health

# Проверить версию
curl http://localhost:8000/health | jq '.version'

# Проверить логи
docker logs orbita --tail 50

# Проверить подключение к БД
docker exec orbita python -c "from orbita_core.database.connection import get_metadata_engine; engine = get_metadata_engine(); print('DB connection OK')"

Шаг 7: Очистка

# Удалить временную директорию
rm -rf /tmp/orbita-restore

# Проверить что всё работает
curl http://localhost:8000/docs

Общее время восстановления: 5-10 минут


Частичное восстановление

Восстановление только конфигурации

# Распаковать резервную копию
tar -xzf /backups/orbita/latest.tar.gz -C /tmp/restore

# Восстановить только .env
cp /tmp/restore/.env ~/orbita/

# Восстановить только домены
cp -r /tmp/restore/domains/ ~/orbita/

# Перезапустить контейнер
docker restart orbita

Восстановление конкретного домена

# Распаковать резервную копию
tar -xzf /backups/orbita/latest.tar.gz -C /tmp/restore

# Восстановить конкретный домен
cp /tmp/restore/domains/ecommerce.yaml ~/orbita/domains/

# Перезапустить
docker restart orbita

Восстановление БД без остановки сервиса

Не рекомендуется для production, но возможно для dev/test:

# Создать временную БД
docker exec postgres-metadata psql -U orbita_user -c "CREATE DATABASE orbita_temp;"

# Восстановить во временную БД
docker exec -i postgres-metadata psql -U orbita_user orbita_temp < metadata.sql

# Переключить (требует остановки приложения)
docker stop orbita
docker exec postgres-metadata psql -U orbita_user -c "ALTER DATABASE orbita RENAME TO orbita_old;"
docker exec postgres-metadata psql -U orbita_user -c "ALTER DATABASE orbita_temp RENAME TO orbita;"
docker start orbita

# После проверки удалить старую БД
docker exec postgres-metadata psql -U orbita_user -c "DROP DATABASE orbita_old;"

Восстановление после миграции данных

Если миграция данных прошла неудачно:

# 1. Откатить миграцию Alembic (внутри контейнера)
docker exec orbita alembic downgrade -1

# 2. Если откат миграции не помог - полное восстановление БД
# Следуйте процедуре "Шаг 4: Восстановление базы данных метаданных"

# 3. Откатить версию Docker образа
# Следуйте процедуре "Быстрый откат после обновления"

Восстановление на новом сервере

При переносе на новый сервер:

Шаг 1: Подготовка нового сервера

# Установить Docker
curl -fsSL https://get.docker.com | sh

# Создать директорию Р13.Орбита
mkdir -p ~/orbita
cd ~/orbita

Шаг 2: Перенос резервной копии

# Скопировать резервную копию с старого сервера
scp old-server:/backups/orbita/latest.tar.gz /tmp/

# Или загрузить из облачного хранилища
# rclone copy remote:orbita-backups/latest.tar.gz /tmp/

Шаг 3: Восстановление

Следуйте процедуре "Полное восстановление системы" выше.


Шаг 4: Настройка сети

# Обновить IP адреса в .env если изменились
nano ~/orbita/.env

# Обновить CLICKHOUSE_HOST, METADATA_DB_URL и другие сетевые параметры

# Перезапустить
docker restart orbita

Точки восстановления (Recovery Points)

RTO (Recovery Time Objective)

Целевое время восстановления:

Сценарий RTO Описание
Откат Docker образа 1-2 мин Быстрый откат к предыдущей версии
Восстановление конфигурации 2-5 мин Восстановление только .env и domains/
Восстановление БД метаданных 5-10 мин Восстановление БД из SQL дампа
Полное восстановление 10-15 мин Восстановление всех компонентов
Восстановление на новом сервере 30-60 мин Включая установку Docker и настройку

RPO (Recovery Point Objective)

Максимальная потеря данных:

Стратегия резервирования RPO Риск
Ежечасное 1 час Минимальный
Ежедневное (02:00) 24 часа Средний
Еженедельное 7 дней Высокий
Только перед обновлением Переменный Очень высокий

Рекомендация: Ежедневное резервирование для production (RPO = 24 часа).


Проверка восстановления

Контрольный список после восстановления

  • Docker контейнер запущен (docker ps | grep orbita)
  • Health check работает (curl http://localhost:8000/health)
  • Версия корректная (curl http://localhost:8000/health | jq '.version')
  • API отвечает (curl http://localhost:8000/docs)
  • Подключение к ClickHouse работает
  • Подключение к БД метаданных работает
  • CLI подключается к API
  • Простой запрос выполняется успешно
  • Сохраненные датасеты доступны
  • История чатов восстановлена
  • Визуализации работают
  • Логи не содержат критических ошибок

Тестовый запрос

# Запустить CLI и проверить работу
docker run -it --rm \
  --network host \
  your-registry.company.com/orbita:latest \
  orbita-cli chat --mode api --api-url http://localhost:8000

# В CLI выполнить:
# > покажи список доменов
# > /datasets
# > /chats

Если все команды работают - восстановление успешно!


Частые проблемы при восстановлении

Проблема: База данных не восстанавливается

Ошибка: ERROR: database "orbita" already exists

Решение:

# Удалить существующую БД
docker exec postgres-metadata psql -U orbita_user -c "DROP DATABASE orbita;"

# Создать заново
docker exec postgres-metadata psql -U orbita_user -c "CREATE DATABASE orbita;"

# Восстановить из резервной копии
docker exec -i postgres-metadata psql -U orbita_user orbita < metadata.sql


Проблема: Версия не совпадает

Ошибка: Восстановили БД от версии 1.3.0, а запускаете контейнер 1.2.5

Решение:

# Проверить версию в резервной копии
cat /tmp/restore/VERSION

# Запустить именно эту версию
docker run -d \
  --name orbita \
  -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  your-registry.company.com/orbita:1.3.0  # Версия из резервной копии


Проблема: Конфликт портов

Ошибка: port is already allocated

Решение:

# Проверить что использует порт 8000
sudo lsof -i :8000

# Остановить старый контейнер
docker stop orbita
docker rm orbita

# Или использовать другой порт
docker run -d \
  --name orbita \
  -p 8001:8000 \  # Изменить на 8001
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  your-registry.company.com/orbita:latest


Проблема: Отсутствуют volumes

Ошибка: no such file or directory: /app/domains

Решение:

# Проверить что директории существуют
ls -la ~/orbita/domains/

# Создать если отсутствуют
mkdir -p ~/orbita/domains ~/orbita/logs

# Восстановить из резервной копии
tar -xzf /backups/orbita/latest.tar.gz -C ~/orbita/


Скрипт автоматического восстановления

#!/bin/bash
# /usr/local/bin/orbita-restore.sh

set -e

BACKUP_FILE="$1"

if [ -z "$BACKUP_FILE" ]; then
    echo "Usage: $0 <backup-file.tar.gz>"
    exit 1
fi

if [ ! -f "$BACKUP_FILE" ]; then
    echo "Error: Backup file not found: $BACKUP_FILE"
    exit 1
fi

echo "Starting Р13.Орбита restore from: $BACKUP_FILE"

# Создать временную директорию
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

# Распаковать резервную копию
echo "Extracting backup..."
tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"

# Остановить текущий контейнер
echo "Stopping current container..."
docker stop orbita 2>/dev/null || true
docker rm orbita 2>/dev/null || true

# Восстановить конфигурацию
echo "Restoring configuration..."
mkdir -p ~/orbita
cp "$TEMP_DIR/.env" ~/orbita/
cp -r "$TEMP_DIR/domains" ~/orbita/
[ -f "$TEMP_DIR/docker-compose.yml" ] && cp "$TEMP_DIR/docker-compose.yml" ~/orbita/

# Восстановить БД
echo "Restoring database..."
if [ -f "$TEMP_DIR/metadata.sql" ]; then
    docker exec postgres-metadata psql -U orbita_user -c "DROP DATABASE IF EXISTS orbita;"
    docker exec postgres-metadata psql -U orbita_user -c "CREATE DATABASE orbita;"
    docker exec -i postgres-metadata psql -U orbita_user orbita < "$TEMP_DIR/metadata.sql"
elif [ -f "$TEMP_DIR/metadata.db" ]; then
    mkdir -p ~/.orbita
    cp "$TEMP_DIR/metadata.db" ~/.orbita/metadata.db
fi

# Запустить контейнер
echo "Starting Р13.Орбита..."
VERSION=$(cat "$TEMP_DIR/VERSION" 2>/dev/null || echo "latest")
cd ~/orbita

docker run -d \
  --name orbita \
  --restart unless-stopped \
  -p 8000:8000 \
  --env-file .env \
  -v $(pwd)/domains:/app/domains \
  -v $(pwd)/logs:/app/logs \
  your-registry.company.com/orbita:$VERSION

# Проверить
echo "Verifying restoration..."
sleep 5
if curl -s http://localhost:8000/health > /dev/null; then
    echo "Restore completed successfully!"
    curl http://localhost:8000/health | jq
else
    echo "Warning: Health check failed. Check logs: docker logs orbita"
fi

Использование:

chmod +x /usr/local/bin/orbita-restore.sh

# Восстановить из резервной копии
/usr/local/bin/orbita-restore.sh /backups/orbita/20260120_020000.tar.gz

Следующие шаги