Привет! Если вам когда-либо приходилось управлять двумя серверами CyberPanel на базе OpenLiteSpeed, вы знаете, насколько сложно поддерживать их синхронизацию вручную. Я столкнулся с той же проблемой, пока не решил автоматизировать процесс с помощью Bash-скрипта. В данной статье мы рассмотрим, как создать Bash-скрипт для синхронизации серверов, чтобы автоматизировать процесс обмена данными. Использование таких скриптов с rsync и CyberPanel упрощает управление серверами и обеспечивает стабильную работу без лишних трудозатрат.!

Содержание

Зачем автоматизировать синхронизацию серверов CyberPanel?

Управление несколькими серверами вручную не только отнимает много времени, но и подвержено ошибкам. Автоматизируя процесс синхронизации, вы можете:

  • Сэкономить время, устраняя повторяющиеся задачи.
  • Снизить количество ошибок, вызванных ручными операциями.
  • Обеспечить согласованность на всех ваших серверах.
  • Сосредоточиться на более важных аспектах управления серверами.

Необходимые инструменты для автоматизации

Прежде чем мы начнем, убедитесь, что у вас есть:

  • Доступ по SSH к обоим серверам.
  • Учетные данные MySQL для работы с базами данных.
  • Аккаунт в Pushover для получения уведомлений.
  • Базовые знания в области Bash-скриптинга.
💡
Не забудьте сделать резервную копию ваших данных перед запуском любых скриптов, которые изменяют ваши серверы.

Пошаговое руководство по автоматизации синхронизации серверов

Разработчик пишет код
Разработчик работает с Bash скриптом | Источник: freepik.com

Шаг 1: Определите необходимые переменные


Bash-скрипт для синхронизации серверов начинается с определения необходимых переменных. Это ключевой этап, поскольку от правильности переменных зависит успех всего процесса. Это включает детали SSH, токены Pushover, учетные данные MySQL и расположение файла журнала.

# Define variables
REMOTE_USER=root
REMOTE_SERVER=<your-server-ip>
SSH_PORT=<your-ssh-port>
PUSHOVER_USER=<your-pushover-user-key>
PUSHOVER_TOKEN=<your-pushover-token>
LOG_FILE="/var/log/sync.log"
DB_USER="<your-db-user>"
DB_PASSWORD="<your-db-password>"
MYSQL_ROOT_PASSWORD="<your-mysql-root-password>"
DUMP_FILE="/tmp/alldbs.sql"
💪
Замените плейсхолдеры, такие как , на реальные данные вашего сервера.

Шаг 2: Настройте уведомления через Pushover

Я использую Pushover, чтобы получать уведомления в реальном времени на свой телефон, когда скрипт сталкивается с проблемами.

# Function to send notification using Pushover
send_notification() {
	local message=$1
	curl -s \
		--form-string "token=$PUSHOVER_TOKEN" \
		--form-string "user=$PUSHOVER_USER" \
		--form-string "message=$message" \
		https://api.pushover.net/1/messages.json
}

Почему использовать Pushover?

Pushover обеспечивает мгновенные уведомления, чтобы вы могли быстро реагировать на любые проблемы, возникающие во время синхронизации.

Шаг 3: Запись журналов в файл

Ведение журналов важно для отслеживания того, что происходит во время выполнения скрипта, особенно когда он запускается как задание cron.

# Function to write to log
log() {
	local message=$1
	echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" >> $LOG_FILE
}

Шаг 4: Проверка подключения по SSH

Перед началом процесса синхронизации скрипт проверяет подключение по SSH к удаленному серверу.

# Check SSH connection
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "exit" || {
	send_notification "SSH connection failed"
	log "SSH connection failed"
	exit 1
}

# Send notification that syncing has started
send_notification "Syncing started."
log "Syncing started."
Если подключение по SSH не удалось, скрипт завершается, чтобы предотвратить дальнейшие действия.

Шаг 5: Передача информации о пользователях и группах

Это гарантирует, что идентификаторы пользователей и групп будут согласованы на обоих серверах.

# Dump user and group information on the source server
getent passwd > /tmp/passwd_dump
getent group > /tmp/group_dump

# Transfer user and group information to the destination server
scp -P $SSH_PORT /tmp/passwd_dump /tmp/group_dump $REMOTE_USER@$REMOTE_SERVER:/tmp/ || {
	send_notification "Transfer of user/group information failed"
	log "Transfer of user/group information failed"
	exit 1
}

Синхронизация баз данных и директорий

Шаг 6: Синхронизация пользователей, групп, пользователя MySQL и установка WP-CLI

На удаленном сервере скрипт создает отсутствующих пользователей и группы, настраивает разрешения пользователя MySQL и устанавливает WP-CLI, если он еще не установлен.

# Create missing users and groups on the destination server, check and setup MySQL user, and check and install wp-cli
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "
	while IFS=: read -r username x uid gid x x x; do
		id -u \$username &>/dev/null || (groupadd -g \$gid \$username; useradd -u \$uid -g \$gid \$username)
	done < /tmp/passwd_dump
	while IFS=: read -r groupname x gid x; do
		getent group \$groupname &>/dev/null || groupadd -g \$gid \$groupname
	done < /tmp/group_dump
	rm /tmp/passwd_dump /tmp/group_dump
	
	# Check and setup MySQL user
	mysql -uroot -p$MYSQL_ROOT_PASSWORD -e \"SELECT 1 FROM mysql.user WHERE user = '$DB_USER'\" | grep -q 1 || {
		mysql -uroot -p$MYSQL_ROOT_PASSWORD -e \"
			CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD';
			GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'localhost';
			FLUSH PRIVILEGES;
		\"
	}
	
	# Check and install wp-cli
	command -v wp &>/dev/null || {
		curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
		chmod +x wp-cli.phar
		mv wp-cli.phar /usr/local/bin/wp
	}
" || {
	send_notification "User/group creation or MySQL user setup or wp-cli installation failed"
	log "User/group creation or MySQL user setup or wp-cli installation failed"
	exit 1
}

Шаг 7: Резервное копирование базы данных и передача

Сделайте резервную копию всех баз данных на исходном сервере и импортируйте их на удаленный сервер.

# Dump all local databases
mysqldump -u$DB_USER -p$DB_PASSWORD --all-databases > $DUMP_FILE || {
	send_notification "MySQL dump failed"
	log "MySQL dump failed"
	exit 1
}

# Transfer the dump file to the remote server
scp -P $SSH_PORT $DUMP_FILE $REMOTE_USER@$REMOTE_SERVER:$DUMP_FILE || {
	send_notification "Transfer of dump file failed"
	log "Transfer of dump file failed"
	exit 1
}

# Import the dump file on the remote server
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "mysql -u$DB_USER -p$DB_PASSWORD < $DUMP_FILE" || {
	send_notification "MySQL import failed"
	log "MySQL import failed"
	exit 1
}
✔️
Синхронизация базы данных успешно завершена!

Шаг 8: Синхронизация директорий с помощью rsync

Используйте rsync для зеркалирования определенных директорий с исходного сервера на целевой.

# Sync specified directories using rsync
for dir in /usr/local/lsws/ /home/ /etc/cyberpanel/ /etc/letsencrypt/ /etc/pure-ftpd/ /etc/firewalld/ /usr/local/lscp/ /usr/local/CyberCP/ /usr/local/CyberPanel/; do
	rsync -avP --delete -e "ssh -p $SSH_PORT" $dir $REMOTE_USER@$REMOTE_SERVER:$dir || {
		send_notification "Rsync failed for directory $dir"
		log "Rsync failed for directory $dir"
		exit 1
	}
done
💪
Этот шаг гарантирует, что оба сервера имеют идентичные конфигурации.

Завершение процесса синхронизации

Шаг 9: Очистка кеша LiteSpeed на удаленном сервере

Очистите кеш LiteSpeed для каждой установки WordPress на целевом сервере.

# Flush LiteSpeed Cache on the remote server for all WordPress installations
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "
	find /home/ -type f -name wp-config.php | while read wp_config; do
		wp_path=\$(dirname \"\$wp_config\")
		wp --allow-root --path=\"\$wp_path\" litespeed-purge all || {
			echo \"Error: Unable to purge LiteSpeed Cache for \$wp_path\"
		}
	done
" || {
	send_notification "LiteSpeed Cache flush failed"
	log "LiteSpeed Cache flush failed"
	exit 1
}

Шаг 10: Очистка и перезагрузка

Наконец, удалите дамп базы данных с обоих серверов и перезагрузите удаленный сервер.

# Remove the dump file from both local and remote servers
rm $DUMP_FILE
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "rm $DUMP_FILE"

# Reboot the remote server
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "reboot" || true

# Send notification that syncing has completed successfully
send_notification "Synchronization completed successfully. Remote server is rebooting."
log "Synchronization completed successfully. Remote server is rebooting."
💡
Удаленный сервер перезагружается, чтобы изменения вступили в силу.

Полный скрипт для простой настройки

Вот полный скрипт для настройки автоматической синхронизации. Не забудьте заменить все плейсхолдеры на реальные данные вашего сервера.

#!/bin/bash
# Define variables
REMOTE_USER=root
REMOTE_SERVER=<your-server-ip>
SSH_PORT=<your-ssh-port>
PUSHOVER_USER=<your-pushover-user-key>
PUSHOVER_TOKEN=<your-pushover-token>
LOG_FILE="/var/log/sync.log"
DB_USER="<your-db-user>"
DB_PASSWORD="<your-db-password>"
MYSQL_ROOT_PASSWORD="<your-mysql-root-password>"
DUMP_FILE="/tmp/alldbs.sql"

# Function to send notification using Pushover
send_notification() {
	local message=$1
	curl -s \
		--form-string "token=$PUSHOVER_TOKEN" \
		--form-string "user=$PUSHOVER_USER" \
		--form-string "message=$message" \
		https://api.pushover.net/1/messages.json
}

# Function to write to log
log() {
	local message=$1
	echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" >> $LOG_FILE
}

# Check SSH connection
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "exit" || {
	send_notification "SSH connection failed"
	log "SSH connection failed"
	exit 1
}

# Send notification that syncing has started
send_notification "Syncing started."
log "Syncing started."

# Dump user and group information on the source server
getent passwd > /tmp/passwd_dump
getent group > /tmp/group_dump

# Transfer user and group information to the destination server
scp -P $SSH_PORT /tmp/passwd_dump /tmp/group_dump $REMOTE_USER@$REMOTE_SERVER:/tmp/ || {
	send_notification "Transfer of user/group information failed"
	log "Transfer of user/group information failed"
	exit 1
}

# Create missing users and groups on the destination server, check and setup MySQL user, and check and install wp-cli
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "
	while IFS=: read -r username x uid gid x x x; do
		id -u \$username &>/dev/null || (groupadd -g \$gid \$username; useradd -u \$uid -g \$gid \$username)
	done < /tmp/passwd_dump
	while IFS=: read -r groupname x gid x; do
		getent group \$groupname &>/dev/null || groupadd -g \$gid \$groupname
	done < /tmp/group_dump
	rm /tmp/passwd_dump /tmp/group_dump
	
	# Check and setup MySQL user
	mysql -uroot -p$MYSQL_ROOT_PASSWORD -e \"SELECT 1 FROM mysql.user WHERE user = '$DB_USER'\" | grep -q 1 || {
		mysql -uroot -p$MYSQL_ROOT_PASSWORD -e \"
			CREATE USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD';
			GRANT ALL PRIVILEGES ON *.* TO '$DB_USER'@'localhost';
			FLUSH PRIVILEGES;
		\"
	}
	
	# Check and install wp-cli
	command -v wp &>/dev/null || {
		curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
		chmod +x wp-cli.phar
		mv wp-cli.phar /usr/local/bin/wp
	}
" || {
	send_notification "User/group creation or MySQL user setup or wp-cli installation failed"
	log "User/group creation or MySQL user setup or wp-cli installation failed"
	exit 1
}

# Dump all local databases
mysqldump -u$DB_USER -p$DB_PASSWORD --all-databases > $DUMP_FILE || {
	send_notification "MySQL dump failed"
	log "MySQL dump failed"
	exit 1
}

# Transfer the dump file to the remote server
scp -P $SSH_PORT $DUMP_FILE $REMOTE_USER@$REMOTE_SERVER:$DUMP_FILE || {
	send_notification "Transfer of dump file failed"
	log "Transfer of dump file failed"
	exit 1
}

# Import the dump file on the remote server
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "mysql -u$DB_USER -p$DB_PASSWORD < $DUMP_FILE" || {
	send_notification "MySQL import failed"
	log "MySQL import failed"
	exit 1
}

# Sync specified directories using rsync
for dir in /usr/local/lsws/ /home/ /etc/cyberpanel/ /etc/letsencrypt/ /etc/pure-ftpd/ /etc/firewalld/ /usr/local/lscp/ /usr/local/CyberCP/ /usr/local/CyberPanel/; do
	rsync -avP --delete -e "ssh -p $SSH_PORT" $dir $REMOTE_USER@$REMOTE_SERVER:$dir || {
		send_notification "Rsync failed for directory $dir"
		log "Rsync failed for directory $dir"
		exit 1
	}
done

# Flush LiteSpeed Cache on the remote server for all WordPress installations
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "
	find /home/ -type f -name wp-config.php | while read wp_config; do
		wp_path=\$(dirname \"\$wp_config\")
		wp --allow-root --path=\"\$wp_path\" litespeed-purge all || {
			echo \"Error: Unable to purge LiteSpeed Cache for \$wp_path\"
		}
	done
" || {
	send_notification "LiteSpeed Cache flush failed"
	log "LiteSpeed Cache flush failed"
	exit 1
}

# Remove the dump file from both local and remote servers
rm $DUMP_FILE
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "rm $DUMP_FILE"

# Reboot the remote server
ssh -p $SSH_PORT $REMOTE_USER@$REMOTE_SERVER "reboot" || true

# Send notification that syncing has completed successfully
send_notification "Synchronization completed successfully. Remote server is rebooting."
log "Synchronization completed successfully. Remote server is rebooting."
✔️
Все готово! Теперь ваши серверы будут синхронизироваться автоматически.

Заключение

Автоматизация синхронизации между двумя серверами CyberPanel с OpenLiteSpeed стала для меня настоящим прорывом. Это не только экономит время, но и гарантирует, что оба сервера всегда актуальны без ручного вмешательства. Надеюсь, это руководство поможет вам упростить управление серверами. Удачной синхронизации!