447 lines
17 KiB
Bash
447 lines
17 KiB
Bash
#!/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 |