Files
xkater/sync.sh
2026-04-12 18:35:16 +07:00

447 lines
17 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ============================================
# WP-CLI Sync Script for WordPress with Docker
# ============================================
# Цвета для вывода
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# ============================================
# НАСТРОЙКИ (ИЗМЕНИТЕ ПОД СЕБЯ)
# ============================================
# Локальные настройки (хост-машина)
LOCAL_PATH="$(pwd)" # Текущая папка, где лежит скрипт (автоопределение)
# Docker настройки
# Получите имя контейнера командой: docker ps --format "table {{.Names}}\t{{.Image}}" | grep wordpress
WP_CONTAINER="wordpress" # ИЗМЕНИТЕ: имя вашего WordPress контейнера
WP_CONTAINER_PATH="/var/www/html" # Путь к WordPress внутри контейнера (обычно /var/www/html)
# Локальный URL (как вы открываете сайт в браузере)
LOCAL_URL="http://localhost:8080" # ИЗМЕНИТЕ: ваш URL и порт
# Боевые настройки (продакшен)
PROD_SSH="user@your-server.com" # ИЗМЕНИТЕ: SSH пользователь и сервер
PROD_PATH="/var/www/production" # ИЗМЕНИТЕ: путь к WordPress на сервере
PROD_URL="https://your-site.com" # ИЗМЕНИТЕ: боевой URL
# Настройки синхронизации
BACKUP_DIR="./sync_backups" # Папка для бэкапов
EXCLUDE_TABLES="wp_options" # Таблицы для исключения (через запятую)
# Например: "wp_options,wp_users"
# Команда WP-CLI для Docker
WP_CMD="docker exec -i $WP_CONTAINER wp --path=$WP_CONTAINER_PATH"
# ============================================
# ФУНКЦИИ
# ============================================
# Функция для проверки Docker контейнера
check_docker() {
info "Проверка Docker контейнера: $WP_CONTAINER"
if ! docker ps --format "table {{.Names}}" | grep -q "^$WP_CONTAINER$"; then
error "Контейнер $WP_CONTAINER не запущен. Запустите Docker и контейнер WordPress."
fi
# Проверяем WP-CLI в контейнере
if ! docker exec $WP_CONTAINER wp --info &> /dev/null; then
error "WP-CLI не найден в контейнере. Установите WP-CLI в Docker образ."
fi
success "Docker контейнер готов"
}
# Функция для вывода ошибок
error() {
echo -e "${RED}[ОШИБКА]${NC} $1"
exit 1
}
# Функция для вывода успеха
success() {
echo -e "${GREEN}[УСПЕХ]${NC} $1"
}
# Функция для вывода информации
info() {
echo -e "${BLUE}[ИНФО]${NC} $1"
}
# Функция для вывода предупреждения
warning() {
echo -e "${YELLOW}[ПРЕДУПРЕЖДЕНИЕ]${NC} $1"
}
# Функция для запроса подтверждения
confirm() {
read -p "$(echo -e ${YELLOW}[?]${NC} $1 (y/n): " )" -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
info "Отменено пользователем"
return 1
fi
return 0
}
# Функция для создания бэкапа БД
backup_db() {
local backup_name="$1"
local backup_file="${BACKUP_DIR}/${backup_name}_$(date +%Y%m%d_%H%M%S).sql"
mkdir -p "$BACKUP_DIR"
info "Создание бэкапа БД: $backup_file"
# Выполняем WP-CLI внутри контейнера, сохраняем на хост
if $WP_CMD db export - 2>/dev/null > "$backup_file"; then
success "Бэкап создан: $backup_file"
echo "$backup_file"
else
error "Не удалось создать бэкап БД"
fi
}
# Функция для импорта БД из файла
import_db() {
local backup_file="$1"
if [ ! -f "$backup_file" ]; then
error "Файл бэкапа не найден: $backup_file"
fi
info "Импорт БД из $backup_file"
# Читаем файл с хоста и передаём в контейнер
if cat "$backup_file" | $WP_CMD db import -; then
success "БД импортирована успешно"
else
error "Не удалось импортировать БД"
fi
}
# Функция для замены URL
replace_url() {
local from_url="$1"
local to_url="$2"
info "Замена URL: $from_url -> $to_url"
# Сначала проверка (dry run)
info "Проверка замены (dry run)..."
if ! $WP_CMD search-replace "$from_url" "$to_url" --dry-run; then
error "Ошибка при проверке замены URL"
fi
if confirm "Продолжить замену URL?"; then
if $WP_CMD search-replace "$from_url" "$to_url"; then
success "URL заменены успешно"
else
error "Ошибка при замене URL"
fi
fi
}
# Функция для очистки кэша
flush_cache() {
info "Очистка кэша WordPress..."
$WP_CMD cache flush
success "Кэш очищен"
}
# ============================================
# ОСНОВНЫЕ КОМАНДЫ
# ============================================
# Функция: Pull (с боевого на локальный)
do_pull() {
echo ""
echo "========================================="
echo "PULL: Боевой -> Локальный"
echo "========================================="
echo ""
# 1. Проверка соединения с боевым сервером
info "Проверка соединения с боевым сервером..."
ssh $PROD_SSH "wp core is-installed --path=$PROD_PATH" || error "Не удалось подключиться к боевому серверу"
success "Соединение с сервером установлено"
# 2. Создание бэкапа боевой БД на сервере
local timestamp=$(date +%Y%m%d_%H%M%S)
local prod_backup="prod_backup_${timestamp}.sql"
info "Создание бэкапа боевой БД на сервере..."
ssh $PROD_SSH "cd $PROD_PATH && wp db export $prod_backup" || error "Не удалось создать бэкап на сервере"
success "Бэкап создан на сервере: $prod_backup"
# 3. Скачивание бэкапа
info "Скачивание бэкапа с сервера..."
scp $PROD_SSH:$PROD_PATH/$prod_backup "$BACKUP_DIR/" || error "Не удалось скачать бэкап"
# 4. Удаление временного файла на сервере
ssh $PROD_SSH "rm $PROD_PATH/$prod_backup"
success "Бэкап скачан и временный файл удалён"
# 5. Создание бэкапа локальной БД (на всякий случай)
backup_db "local_before_pull_${timestamp}"
# 6. Импорт боевой БД в локальную среду
import_db "$BACKUP_DIR/$prod_backup"
# 7. Замена URL на локальные
replace_url "$PROD_URL" "$LOCAL_URL"
# 8. Очистка кэша
flush_cache
success "Pull завершён успешно!"
info "Локальный сайт теперь полностью соответствует боевому"
}
# Функция: Push (с локального на боевой)
do_push() {
echo ""
echo "========================================="
echo "PUSH: Локальный -> Боевой"
echo "========================================="
echo ""
# ПРЕДУПРЕЖДЕНИЕ!
warning "Эта операция ЗАМЕНИТ боевую базу данных на локальную!"
echo "Вы потеряете все новые данные на боевом сайте:"
echo " • Заказы (если есть интернет-магазин)"
echo " • Комментарии пользователей"
echo " • Новых зарегистрированных пользователей"
echo " • Изменения в настройках"
echo ""
if ! confirm "Вы уверены, что хотите продолжить?"; then
exit 0
fi
local timestamp=$(date +%Y%m%d_%H%M%S)
# 1. Создание бэкапа боевой БД
info "Создание бэкапа боевой БД перед обновлением..."
ssh $PROD_SSH "cd $PROD_PATH && wp db export backup_before_push_${timestamp}.sql" || error "Не удалось создать бэкап боевой БД"
success "Бэкап боевой БД сохранён на сервере"
# 2. Создание бэкапа локальной БД
backup_db "local_before_push_${timestamp}"
# 3. Экспорт локальной БД с заменой URL
info "Подготовка локальной БД для боевого сервера..."
local temp_backup="${BACKUP_DIR}/temp_for_prod_${timestamp}.sql"
# Экспортируем БД из контейнера
$WP_CMD db export - > "$temp_backup" || error "Не удалось экспортировать локальную БД"
# 4. Замена URL в дампе (локальный -> боевой)
info "Замена URL в дампе: $LOCAL_URL -> $PROD_URL"
sed -i "s|$LOCAL_URL|$PROD_URL|g" "$temp_backup"
# 5. Исключение некоторых таблиц (если нужно)
if [ -n "$EXCLUDE_TABLES" ] && [ "$EXCLUDE_TABLES" != "none" ]; then
info "Исключение таблиц: $EXCLUDE_TABLES"
local filtered_backup="${BACKUP_DIR}/filtered_${timestamp}.sql"
# Создаём временный файл без исключённых таблиц
local exclude_pattern=$(echo "$EXCLUDE_TABLES" | sed 's/,/\\|/g')
grep -v "CREATE TABLE \`\(${exclude_pattern}\)\`" "$temp_backup" > "$filtered_backup"
grep -v "INSERT INTO \`\(${exclude_pattern}\)\`" "$filtered_backup" > "${filtered_backup}.tmp"
mv "${filtered_backup}.tmp" "$filtered_backup"
mv "$filtered_backup" "$temp_backup"
success "Таблицы исключены"
fi
# 6. Отправка дампа на сервер
info "Отправка дампа на боевой сервер..."
scp "$temp_backup" $PROD_SSH:$PROD_PATH/ || error "Не удалось отправить дамп на сервер"
# 7. Импорт на боевом сервере
info "Импорт на боевом сервере..."
ssh $PROD_SSH "cd $PROD_PATH && wp db import $(basename $temp_backup) && rm $(basename $temp_backup)" || error "Не удалось импортировать БД на сервере"
# 8. Очистка кэша на сервере
info "Очистка кэша на боевом сервере..."
ssh $PROD_SSH "cd $PROD_PATH && wp cache flush"
# 9. Удаление временных файлов
rm "$temp_backup"
success "Push завершён успешно!"
info "Боевой сайт обновлён. Бэкап старой версии сохранён на сервере"
}
# Функция: Синхронизация файлов (Uploads через rsync)
do_sync_files() {
echo ""
echo "========================================="
echo "СИНХРОНИЗАЦИЯ ФАЙЛОВ (Uploads)"
echo "========================================="
echo ""
# Проверка наличия rsync
if ! command -v rsync &> /dev/null; then
warning "rsync не установлен. Установите rsync: brew install rsync (macOS) или apt-get install rsync (Linux)"
return 1
fi
# Пути к папкам uploads
LOCAL_UPLOADS="${LOCAL_PATH}/wp-content/uploads"
REMOTE_UPLOADS="$PROD_SSH:$PROD_PATH/wp-content/uploads"
# Проверка существования локальной папки
if [ ! -d "$LOCAL_UPLOADS" ]; then
warning "Локальная папка uploads не найдена: $LOCAL_UPLOADS"
info "Создаю папку..."
mkdir -p "$LOCAL_UPLOADS"
fi
echo "Выберите направление синхронизации:"
echo " 1) Локальный -> Боевой (отправить новые файлы на сервер)"
echo " 2) Боевой -> Локальный (скачать новые файлы с сервера)"
echo ""
read -p "Ваш выбор (1/2): " direction
case $direction in
1)
info "Синхронизация локальных файлов на боевой сервер..."
rsync -avz --progress \
--exclude="*.tmp" \
--exclude=".DS_Store" \
"$LOCAL_UPLOADS/" "$REMOTE_UPLOADS/"
success "Файлы отправлены на сервер"
;;
2)
info "Скачивание файлов с боевого сервера..."
rsync -avz --progress \
--exclude="*.tmp" \
--exclude=".DS_Store" \
"$REMOTE_UPLOADS/" "$LOCAL_UPLOADS/"
success "Файлы скачаны с сервера"
;;
*)
error "Неверный выбор"
;;
esac
}
# Функция: Показать статус
do_status() {
echo ""
echo "========================================="
echo "СТАТУС СИСТЕМЫ"
echo "========================================="
echo ""
# Docker контейнер
info "Docker контейнер:"
if docker ps --format "table {{.Names}}\t{{.Status}}" | grep -q "^$WP_CONTAINER"; then
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep "$WP_CONTAINER"
else
warning "Контейнер $WP_CONTAINER не запущен"
fi
echo ""
# Локальный WordPress
info "Локальный WordPress:"
if $WP_CMD core version &> /dev/null; then
echo " Версия: $($WP_CMD core version)"
echo " URL: $LOCAL_URL"
echo " Путь в контейнере: $WP_CONTAINER_PATH"
else
warning "WordPress не доступен в контейнере"
fi
echo ""
# Боевой сервер
info "Боевой сервер:"
if ssh $PROD_SSH "wp core version --path=$PROD_PATH" &> /dev/null; then
echo " Версия: $(ssh $PROD_SSH "wp core version --path=$PROD_PATH")"
echo " URL: $PROD_URL"
echo " Путь: $PROD_PATH"
else
warning "Не удалось подключиться к боевому серверу"
fi
}
# ============================================
# ГЛАВНОЕ МЕНЮ
# ============================================
# Очистка экрана
clear
# Приветствие
echo ""
echo "========================================="
echo " WP-CLI Sync Script for WordPress"
echo " Docker + Production Sync"
echo "========================================="
echo ""
# Проверка Docker
check_docker
# Создание папки для бэкапов
mkdir -p "$BACKUP_DIR"
# Основной цикл меню
while true; do
echo ""
echo "========================================="
echo "ГЛАВНОЕ МЕНЮ"
echo "========================================="
echo ""
echo "Текущие настройки:"
echo " 📦 Docker контейнер: $WP_CONTAINER"
echo " 🏠 Локальный URL: $LOCAL_URL"
echo " ☁️ Боевой URL: $PROD_URL"
echo " 📁 Бэкапы: $BACKUP_DIR"
echo ""
echo "Доступные действия:"
echo " 📥 1) Pull (Боевой -> Локальный) - забрать данные с сервера"
echo " 📤 2) Push (Локальный -> Боевой) - отправить данные на сервер"
echo " 📁 3) Sync Files - синхронизировать только файлы (uploads)"
echo " 4) Status - показать статус системы"
echo " 🗑️ 5) Backup - создать бэкап локальной БД"
echo " 🚪 6) Exit - выход"
echo ""
read -p "Выберите действие (1-6): " action
case $action in
1)
do_pull
;;
2)
do_push
;;
3)
do_sync_files
;;
4)
do_status
;;
5)
backup_db "manual_backup"
;;
6)
info "Выход из программы"
exit 0
;;
*)
error "Неверный выбор. Пожалуйста, выберите 1-6"
;;
esac
echo ""
read -p "Нажмите Enter, чтобы продолжить..."
clear
done