Поддерживать локальную версию сайта — скучное и утомительное занятие, особенно если проект быстро развивается и большое количество людей постоянно вносят правки, публикуют новые страницы, статьи или меняют настройки. Конечно, идеальным считается процесс, в котором все изменения сначала вносятся на стейдж-сервер, а только после проверки переносятся на боевой сайт. Но на практике мало у кого хватает выдержки всегда соблюдать такой порядок, а на большинстве малых и средних проектов он и вовсе не нужен.
Поэтому в конечном итоге отправной точкой остается продакшн, базу которого нам и нужно постоянно подтягивать на локальную версию, чтобы быть в курсе последних изменений и облегчить себе работу. Эволюционным путем на нескольких проектах у меня образовался нижеприведенный вариант, и, хотя он изначально создавался для работы под 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 для долгосрочных проектов.
Он дает мне возможность положить свой приватный и публичный ключ внутрь виртуальной машины так, что когда локальный сервер подключается к боевому, боевой пропускает его, потому что он видит мой публичный ключ. И при этом не нужно хранить ключи нигде — они находятся только внутри виртуальной машины и фактически видны только в момент обновления базы. И пароль вводить не нужно 🙂
Напишите в комментариях, какой процесс используете вы и с какими подводными камнями сталкиваетесь — будет очень интересно узнать!