Добавлены скрипты для работы с дампами БД
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 7s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 7s
- Создан скрипт dump-db.sh для создания дампов (по умолчанию из .env.prod) - Создан скрипт restore-db.sh для восстановления дампов (по умолчанию в .env.local) - Создан скрипт list-dumps.sh для просмотра списка дампов - Добавлена директория database-dumps/ для хранения дампов - Обновлен .gitignore для исключения дампов и env файлов - Исправлен контекст сборки в docker-compose.yml для backend - Добавлено автоматическое ограничение количества дампов (максимум 10)
This commit is contained in:
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,6 +1,13 @@
|
||||
.env
|
||||
.env.local
|
||||
.env.prod
|
||||
*.log
|
||||
main
|
||||
dist/
|
||||
node_modules/
|
||||
*.tar
|
||||
|
||||
# Database dumps
|
||||
database-dumps/*.sql
|
||||
database-dumps/*.sql.gz
|
||||
!database-dumps/.gitkeep
|
||||
|
||||
0
database-dumps/.gitkeep
Normal file
0
database-dumps/.gitkeep
Normal file
62
database-dumps/README.md
Normal file
62
database-dumps/README.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Database Dumps
|
||||
|
||||
Эта директория содержит дампы базы данных для разработки и тестирования.
|
||||
|
||||
## Использование
|
||||
|
||||
### Создание дампа
|
||||
|
||||
```bash
|
||||
# Дамп из production БД (по умолчанию .env.prod)
|
||||
./dump-db.sh
|
||||
|
||||
# Дамп с именем
|
||||
./dump-db.sh production-backup
|
||||
|
||||
# Дамп из локальной БД
|
||||
./dump-db.sh --env-file .env.local
|
||||
|
||||
# Дамп из другого окружения
|
||||
./dump-db.sh --env-file .env.prod my-backup
|
||||
```
|
||||
|
||||
### Просмотр дампов
|
||||
|
||||
```bash
|
||||
./list-dumps.sh
|
||||
```
|
||||
|
||||
### Восстановление дампа
|
||||
|
||||
```bash
|
||||
# Восстановление в локальную БД (по умолчанию .env.local)
|
||||
./restore-db.sh dump_20240101_120000.sql.gz
|
||||
|
||||
# Восстановление в production БД
|
||||
./restore-db.sh --env-file .env.prod dump_20240101_120000.sql.gz
|
||||
|
||||
# Можно указать имя без расширения
|
||||
./restore-db.sh dump_20240101_120000
|
||||
```
|
||||
|
||||
## Поведение по умолчанию
|
||||
|
||||
- **Создание дампа**: использует `.env.prod` (production БД)
|
||||
- **Восстановление**: использует `.env.local` (локальная БД)
|
||||
|
||||
Это можно изменить с помощью параметра `--env-file`.
|
||||
|
||||
## Важно
|
||||
|
||||
⚠️ **Восстановление дампа удалит все данные в целевой базе данных!**
|
||||
|
||||
Всегда проверяйте, в какую БД вы восстанавливаете данные.
|
||||
|
||||
## Формат файлов
|
||||
|
||||
Дампы сохраняются в формате:
|
||||
- `dump_YYYYMMDD_HHMMSS.sql.gz` - автоматическое имя с датой/временем
|
||||
- `имя_дампа.sql.gz` - именованный дамп
|
||||
|
||||
Все дампы автоматически сжимаются с помощью gzip.
|
||||
|
||||
@@ -25,8 +25,8 @@ services:
|
||||
# Backend сервер (Go)
|
||||
backend:
|
||||
build:
|
||||
context: ./play-life-backend
|
||||
dockerfile: Dockerfile
|
||||
context: .
|
||||
dockerfile: ./play-life-backend/Dockerfile
|
||||
ports:
|
||||
- "${PORT:-8080}:8080"
|
||||
environment:
|
||||
|
||||
119
dump-db.sh
Executable file
119
dump-db.sh
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Скрипт для создания дампа базы данных
|
||||
# Использование:
|
||||
# ./dump-db.sh [имя_дампа] # Дамп из .env.prod
|
||||
# ./dump-db.sh --env-file .env.local [имя] # Дамп из указанного файла
|
||||
# ./dump-db.sh production-backup # Именованный дамп из .env.prod
|
||||
|
||||
set -e
|
||||
|
||||
# Значения по умолчанию
|
||||
DEFAULT_ENV_FILE=".env.prod"
|
||||
ENV_FILE="$DEFAULT_ENV_FILE"
|
||||
DUMP_NAME=""
|
||||
|
||||
# Парсим аргументы
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--env-file)
|
||||
ENV_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
if [ -z "$DUMP_NAME" ]; then
|
||||
DUMP_NAME="$1"
|
||||
else
|
||||
echo "❌ Ошибка: Неизвестный аргумент: $1"
|
||||
echo "Использование: ./dump-db.sh [--env-file FILE] [имя_дампа]"
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Загружаем переменные окружения из указанного файла
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
export $(cat "$ENV_FILE" | grep -v '^#' | grep -v '^$' | xargs)
|
||||
echo "📋 Используется файл окружения: $ENV_FILE"
|
||||
else
|
||||
echo "⚠️ Файл $ENV_FILE не найден, используются значения по умолчанию"
|
||||
fi
|
||||
|
||||
DB_HOST=${DB_HOST:-localhost}
|
||||
DB_PORT=${DB_PORT:-5432}
|
||||
DB_USER=${DB_USER:-playeng}
|
||||
DB_PASSWORD=${DB_PASSWORD:-playeng}
|
||||
DB_NAME=${DB_NAME:-playeng}
|
||||
|
||||
# Создаем директорию для дампов, если её нет
|
||||
mkdir -p database-dumps
|
||||
|
||||
# Генерируем имя файла с датой и временем, если не указано
|
||||
if [ -z "$DUMP_NAME" ]; then
|
||||
DUMP_NAME="dump_$(date +%Y%m%d_%H%M%S).sql"
|
||||
else
|
||||
DUMP_NAME="$DUMP_NAME.sql"
|
||||
fi
|
||||
|
||||
DUMP_PATH="database-dumps/$DUMP_NAME"
|
||||
|
||||
echo "🗄️ Создание дампа базы данных..."
|
||||
echo " База: $DB_NAME"
|
||||
echo " Хост: $DB_HOST:$DB_PORT"
|
||||
echo " Пользователь: $DB_USER"
|
||||
echo " Файл: $DUMP_PATH"
|
||||
|
||||
# Создаем дамп через docker-compose, если контейнер запущен
|
||||
if docker-compose ps db 2>/dev/null | grep -q "Up"; then
|
||||
echo " Используется docker-compose..."
|
||||
docker-compose exec -T db pg_dump -U "$DB_USER" -d "$DB_NAME" > "$DUMP_PATH"
|
||||
elif command -v pg_dump &> /dev/null; then
|
||||
# Или напрямую через pg_dump, если БД доступна локально
|
||||
echo " Используется локальный pg_dump..."
|
||||
PGPASSWORD="$DB_PASSWORD" pg_dump -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" > "$DUMP_PATH"
|
||||
elif command -v docker &> /dev/null; then
|
||||
# Используем Docker образ postgres для создания дампа
|
||||
# Используем latest для совместимости с разными версиями сервера
|
||||
echo " Используется Docker (postgres:latest)..."
|
||||
# Используем --network host для доступа к удаленным хостам
|
||||
docker run --rm -i --network host \
|
||||
-e PGPASSWORD="$DB_PASSWORD" \
|
||||
postgres:latest \
|
||||
pg_dump -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" > "$DUMP_PATH"
|
||||
else
|
||||
echo "❌ Ошибка: pg_dump не найден, docker-compose не запущен и Docker недоступен"
|
||||
echo " Установите PostgreSQL клиент или Docker"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Сжимаем дамп
|
||||
echo " Сжатие дампа..."
|
||||
gzip -f "$DUMP_PATH"
|
||||
DUMP_PATH="${DUMP_PATH}.gz"
|
||||
|
||||
echo "✅ Дамп успешно создан: $DUMP_PATH"
|
||||
echo " Размер: $(du -h "$DUMP_PATH" | cut -f1)"
|
||||
|
||||
# Ограничиваем количество дампов (максимум 10)
|
||||
MAX_DUMPS=10
|
||||
DUMP_COUNT=$(ls -1 database-dumps/*.sql.gz 2>/dev/null | wc -l | tr -d ' ')
|
||||
|
||||
if [ "$DUMP_COUNT" -gt "$MAX_DUMPS" ]; then
|
||||
echo ""
|
||||
echo "🧹 Очистка старых дампов (максимум $MAX_DUMPS)..."
|
||||
# Сортируем по дате модификации (новые первыми) и удаляем самые старые
|
||||
OLD_DUMPS=$(ls -1t database-dumps/*.sql.gz 2>/dev/null | tail -n +$((MAX_DUMPS + 1)))
|
||||
if [ -n "$OLD_DUMPS" ]; then
|
||||
REMOVED_COUNT=0
|
||||
for old_dump in $OLD_DUMPS; do
|
||||
rm -f "$old_dump"
|
||||
REMOVED_COUNT=$((REMOVED_COUNT + 1))
|
||||
echo " Удален: $(basename "$old_dump")"
|
||||
done
|
||||
echo " Удалено дампов: $REMOVED_COUNT"
|
||||
echo " Осталось дампов: $MAX_DUMPS"
|
||||
fi
|
||||
fi
|
||||
|
||||
35
list-dumps.sh
Executable file
35
list-dumps.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Скрипт для просмотра списка доступных дампов
|
||||
|
||||
DUMP_DIR="database-dumps"
|
||||
|
||||
if [ ! -d "$DUMP_DIR" ]; then
|
||||
echo "❌ Директория дампов не найдена: $DUMP_DIR"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 Доступные дампы базы данных:"
|
||||
echo ""
|
||||
|
||||
# Показываем дампы с информацией о размере и дате
|
||||
if ls "$DUMP_DIR"/*.sql.gz 2>/dev/null | grep -q .; then
|
||||
ls -lh "$DUMP_DIR"/*.sql.gz 2>/dev/null | awk '{
|
||||
filename = $9
|
||||
gsub(/.*\//, "", filename)
|
||||
printf " %-40s %8s %s %s %s\n", filename, $5, $6, $7, $8
|
||||
}'
|
||||
echo ""
|
||||
echo "Всего дампов: $(ls -1 "$DUMP_DIR"/*.sql.gz 2>/dev/null | wc -l | tr -d ' ')"
|
||||
echo ""
|
||||
echo "Для восстановления используйте:"
|
||||
echo " ./restore-db.sh <имя_дампа.sql.gz> # В .env.local"
|
||||
echo " ./restore-db.sh --env-file .env.prod <имя_дампа> # В указанный файл"
|
||||
else
|
||||
echo " (нет дампов)"
|
||||
echo ""
|
||||
echo "Для создания дампа используйте:"
|
||||
echo " ./dump-db.sh # Из .env.prod"
|
||||
echo " ./dump-db.sh --env-file .env.local [имя] # Из указанного файла"
|
||||
fi
|
||||
|
||||
136
restore-db.sh
Executable file
136
restore-db.sh
Executable file
@@ -0,0 +1,136 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Скрипт для восстановления базы данных из дампа
|
||||
# Использование:
|
||||
# ./restore-db.sh [имя_дампа.sql.gz] # Восстановление в .env.local
|
||||
# ./restore-db.sh --env-file .env.prod [имя_дампа] # Восстановление в указанный файл
|
||||
# ./restore-db.sh production-backup.sql.gz # Восстановление в .env.local
|
||||
|
||||
set -e
|
||||
|
||||
# Значения по умолчанию
|
||||
DEFAULT_ENV_FILE=".env.local"
|
||||
ENV_FILE="$DEFAULT_ENV_FILE"
|
||||
DUMP_FILE=""
|
||||
|
||||
# Парсим аргументы
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--env-file)
|
||||
ENV_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
if [ -z "$DUMP_FILE" ]; then
|
||||
DUMP_FILE="$1"
|
||||
else
|
||||
echo "❌ Ошибка: Неизвестный аргумент: $1"
|
||||
echo "Использование: ./restore-db.sh [--env-file FILE] [имя_дампа.sql.gz]"
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Загружаем переменные окружения из указанного файла
|
||||
if [ -f "$ENV_FILE" ]; then
|
||||
export $(cat "$ENV_FILE" | grep -v '^#' | grep -v '^$' | xargs)
|
||||
echo "📋 Используется файл окружения: $ENV_FILE"
|
||||
else
|
||||
echo "⚠️ Файл $ENV_FILE не найден, используются значения по умолчанию"
|
||||
fi
|
||||
|
||||
DB_HOST=${DB_HOST:-localhost}
|
||||
DB_PORT=${DB_PORT:-5432}
|
||||
DB_USER=${DB_USER:-playeng}
|
||||
DB_PASSWORD=${DB_PASSWORD:-playeng}
|
||||
DB_NAME=${DB_NAME:-playeng}
|
||||
|
||||
# Проверяем наличие дампа
|
||||
if [ -z "$DUMP_FILE" ]; then
|
||||
echo "❌ Ошибка: Укажите имя дампа"
|
||||
echo "Использование: ./restore-db.sh [--env-file FILE] [имя_дампа.sql.gz]"
|
||||
echo ""
|
||||
echo "Доступные дампы:"
|
||||
ls -lh database-dumps/*.sql.gz 2>/dev/null | awk '{print " " $9}' | sed "s|database-dumps/||g" || echo " (нет дампов)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Определяем полный путь к файлу
|
||||
if [[ "$DUMP_FILE" =~ ^/ ]]; then
|
||||
# Абсолютный путь
|
||||
FULL_DUMP_PATH="$DUMP_FILE"
|
||||
else
|
||||
# Относительный путь
|
||||
if [[ "$DUMP_FILE" == *.sql.gz ]] || [[ "$DUMP_FILE" == *.sql ]]; then
|
||||
FULL_DUMP_PATH="database-dumps/$DUMP_FILE"
|
||||
else
|
||||
# Пробуем с расширениями
|
||||
if [ -f "database-dumps/$DUMP_FILE.sql.gz" ]; then
|
||||
FULL_DUMP_PATH="database-dumps/$DUMP_FILE.sql.gz"
|
||||
elif [ -f "database-dumps/$DUMP_FILE.sql" ]; then
|
||||
FULL_DUMP_PATH="database-dumps/$DUMP_FILE.sql"
|
||||
else
|
||||
FULL_DUMP_PATH="database-dumps/$DUMP_FILE"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f "$FULL_DUMP_PATH" ]; then
|
||||
echo "❌ Ошибка: Файл дампа не найден: $FULL_DUMP_PATH"
|
||||
echo ""
|
||||
echo "Доступные дампы:"
|
||||
ls -lh database-dumps/*.sql.gz 2>/dev/null | awk '{print " " $9}' | sed "s|database-dumps/||g" || echo " (нет дампов)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⚠️ ВНИМАНИЕ: Это действие удалит все данные в базе $DB_NAME!"
|
||||
echo " Хост: $DB_HOST:$DB_PORT"
|
||||
echo " Пользователь: $DB_USER"
|
||||
read -p " Продолжить? (yes/no): " confirm
|
||||
|
||||
if [ "$confirm" != "yes" ]; then
|
||||
echo "❌ Отменено."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "🔄 Восстановление базы данных из дампа..."
|
||||
echo " База: $DB_NAME"
|
||||
echo " Хост: $DB_HOST:$DB_PORT"
|
||||
echo " Файл: $FULL_DUMP_PATH"
|
||||
|
||||
# Распаковываем, если сжат
|
||||
TEMP_DUMP="/tmp/restore_$$.sql"
|
||||
if [[ "$FULL_DUMP_PATH" == *.gz ]]; then
|
||||
echo " Распаковка дампа..."
|
||||
gunzip -c "$FULL_DUMP_PATH" > "$TEMP_DUMP"
|
||||
else
|
||||
cp "$FULL_DUMP_PATH" "$TEMP_DUMP"
|
||||
fi
|
||||
|
||||
# Восстанавливаем через docker-compose, если контейнер запущен
|
||||
if docker-compose ps db 2>/dev/null | grep -q "Up"; then
|
||||
echo " Используется docker-compose..."
|
||||
# Очищаем базу и восстанавливаем
|
||||
docker-compose exec -T db psql -U "$DB_USER" -d postgres -c "DROP DATABASE IF EXISTS $DB_NAME;"
|
||||
docker-compose exec -T db psql -U "$DB_USER" -d postgres -c "CREATE DATABASE $DB_NAME;"
|
||||
docker-compose exec -T db psql -U "$DB_USER" -d "$DB_NAME" < "$TEMP_DUMP"
|
||||
elif command -v psql &> /dev/null; then
|
||||
# Или напрямую через psql
|
||||
echo " Используется локальный psql..."
|
||||
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -c "DROP DATABASE IF EXISTS $DB_NAME;"
|
||||
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -c "CREATE DATABASE $DB_NAME;"
|
||||
PGPASSWORD="$DB_PASSWORD" psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" < "$TEMP_DUMP"
|
||||
else
|
||||
echo "❌ Ошибка: psql не найден и docker-compose не запущен"
|
||||
echo " Запустите docker-compose или установите PostgreSQL клиент"
|
||||
rm -f "$TEMP_DUMP"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Удаляем временный файл
|
||||
rm -f "$TEMP_DUMP"
|
||||
|
||||
echo "✅ База данных успешно восстановлена из дампа!"
|
||||
|
||||
Reference in New Issue
Block a user