first commit
This commit is contained in:
447
sync.sh
Normal file
447
sync.sh
Normal file
@@ -0,0 +1,447 @@
|
||||
#!/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
|
||||
Reference in New Issue
Block a user