Автоматическое обновление локальной базы с боевого сервера

Поддерживать локальную версию сайта — скучное и утомительное занятие, особенно если проект быстро развивается и большое количество людей постоянно вносят правки, публикуют новые страницы, статьи или меняют настройки. Конечно, идеальным считается процесс, в котором все изменения сначала вносятся на стейдж-сервер, а только после проверки переносятся на боевой сайт. Но на практике мало у кого хватает выдержки всегда соблюдать такой порядок, а на большинстве малых и средних проектов он и вовсе не нужен.

Поэтому в конечном итоге отправной точкой остается продакшн, базу которого нам и нужно постоянно подтягивать на локальную версию, чтобы быть в курсе последних изменений и облегчить себе работу. Эволюционным путем на нескольких проектах у меня образовался нижеприведенный вариант, и, хотя он изначально создавался для работы под Vagrant, приспособить можно подо что угодно. Комментарии, критика — приветствуется в комментариях.

Экспорт базы на live-сервере по расписанию

Самое простой шаг — добавить вот эту команду в crontab файл сервера. Она выгружает базу и упаковывает ее в архив по заданному пути и в заданное время. Я сделал выгрузку каждый день, но можно настроить любой интервал. Рекомендую серис crontab.guru для наглядности.

0 0 */1 * * wp db export - | gzip > /www/yoursite/db.sql.gz

Импорт базы в локальную среду

Все делается одной командой, которая запускает bash-скрипт. Например, для обновления базы на локальной машине Vagrant мне достаточно подключиться к ней и набрать dbupdate. Для работы в Docker окружении потребуются модификации, особенно в части работы с локальной БД.

dbupdate

#!/bin/bash

LOCAL_FILENAME="/srv/www/db.sql.gz";
REMOTE_FILENAME="/www/yoursite/db.sql.gz";

# Скачиваем архив базы с боевого сайта. Здесь указаны параметры доступа к серверу
scp -P 12345 user@11.22.33.44:${REMOTE_FILENAME} ${LOCAL_FILENAME}

# Сохраняем в переменной размер файла
SIZE=`gzip -l ${LOCAL_FILENAME} | tail -n1 | awk '{print $2}'`;

# Дропаем локальную БД
mysql -uvagrant -ppassword vagrant -e "DROP DATABASE vagrant"

# Создаем локальную БД по новой
sudo mysql -u root -ppassword << EOF
CREATE DATABASE IF NOT EXISTS vagrant;
GRANT ALL PRIVILEGES ON vagrant.* TO 'vagrant'@'localhost' IDENTIFIED BY 'password';
EOF

# Импортируем данные из дампа
pigz -dc ${LOCAL_FILENAME} | pv -s ${SIZE} --name '  Импорт БД.. ' | mysql -uvagrant -ppassword vagrant

cd /srv/www/

# Обновляем урлы (нужно только для мультисайта)
wp search-replace 'yoursite.com' 'yoursite.local' wp_blogs wp_site --network

# и еще отдельно здесь на всякий случай
wp search-replace 'https://yoursite.com' 'http://yoursite.local' wp_options

# а потом везде вообще
wp search-replace 'https://yoursite.com' 'http://yoursite.local' --network --skip-columns=guid --skip-tables=wp_users,wp_blogs,wp_site

# деактивируем плагины, которые не нужны локально
wp plugin deactivate cloudflare --network --url='yoursite.local'

# активируем нужны плагины
wp plugin activate query-monitor --url='yoursite.local'

# Чистим кэш
wp cache flush

# Удаляем файл с дампом
rm ${LOCAL_FILENAME}

А что с картинками?

Хороший вопрос. Идея тянуть сотни мегабайт картинок при каждом обновлении базы мне никогда не нравилась, поэтому берем все содержимое папки /wp-content/uploads/ напрямую с продакшена с помощью правила nginx. Минус такого подхода — нужен интернет, иначе картинок не будет, но мне кажется это того стоит.

nginx.conf

server {
 
    location ~ ^/wp-content/uploads/(.*) {
      try_files $uri @live_uploads;
    }

    location @live_uploads {
        rewrite ^/wp-content/uploads/(.*)$ https://yoursite.com/wp-content/uploads/$1 permanent;
    }

}

Не хочу каждый раз вводить пароль!

Да, это проблема. Я тоже не хочу. По-умолчанию скрипт dbupdate каждый раз будет спрашивать пароль SFTP от сервера для скачивания свежей базы. И если там отключен SFTP (а так и должно быть) — ничего не получится. Это — одна из причин, по которой я до сих пор использую Vagrant для долгосрочных проектов.

Он дает мне возможность положить свой приватный и публичный ключ внутрь виртуальной машины так, что когда локальный сервер подключается к боевому, боевой пропускает его, потому что он видит мой публичный ключ. И при этом не нужно хранить ключи нигде — они находятся только внутри виртуальной машины и фактически видны только в момент обновления базы. И пароль вводить не нужно 🙂


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

Павел Федоров

Создатель этого сайта и многих других (на WordPress, конечно же). Любит WordPress и делает на нем всякие сумасшедшие сложные штуки, которые никто в здравом уме делать не станет. Умеет работать на фрилансе, в офисе, без офиса, без оглядки и без сна. Один из немногих участников программы FSA/FLEX, кого выдворили из Америки за плохое поведение. С тех пор умеет слушать. Обожает Star Wars, Ведьмака, горные лыжи, байдарку, пешие прогулки, спонтанные путешествия и хорошую компанию. Больше не боится vim.

Добавить комментарий

%d такие блоггеры, как: