Разработка на WordPress по-человечески, с использованием GIT

Как обычно ведётся разработка на WordPress?
Одним из двух способов:
1) Полностью на удалённом сервере
1.1 Устанавливаем wordpress на удалённом сервере
1.2 Закрываем доступ к нему через .htaccess и .htpasswd чтобы посторонние не лезли, пока он не готов
1.3 Подключаемся к сайту по FTP через FileZilla и вручную создаём тему дизайна
2) На локальном сервере, с последующей одноразовой выгрузкой
2.1 Устанавливаем wordpress на локальной машине
2.2 Через /etc/hosts прописываем строчку, чтобы адрес будущего сайта указывал на локальную машину
2.3 Разрабатываем сайт на локальной машине, обращаясь к ней по адресу будущего сайта
2.4 По готовности выгружаем сайт на боевой сервер через ftp и mysql

Однако, любой разработчик, имеющий опыт командной работы над сайтом с обменом кодом посредством git, давно привычен к гораздо лучшему. Разработка «по-человечески», с использованием удалённого git-репозитория имеет множество плюсов.

Но начать разрабатывать сайты на wordpress с использованием git-а на разных машинах не так просто, как хотелось бы.
Путём долгих поисков и большого количества набитых шишек я создал алгоритм разработки сайтов на wordpress с использованием git и минимальными проблемами.

Итак, какова задача:
1. Получить возможность работать с WordPress посредством репозитория git, выгружать изменения в удалённый репозиторий, работать командой.
2. Не иметь проблем с доменными именами, чтобы wordpress на разных доменных именах работал «как родной», хоть на site.ru, хоть на site.local
3. Иметь возможность синхронизировать базу данных на локальном и удалённом сайте без ручных манипуляций с mysqldump и более удобно, чем с помощью тормозных wordpress-плагинов.
4. Заодно, чтобы 2 раза не вставать, нужно чтобы наш сайт был более-менее защищён от взломов.

Системные требования:

Для реализации задуманного нам понадобится:
1. Операционная система Gnu/Linux на вашем ПК. Если нет, то подойдёт и Windows. В принципе, на машине с MacOS всё описанное также должно получиться, но я не проверял, так что пишите в комменты, если будете пробовать, и что-то получится (или не получится)
2. Удалённый web-сервер на Linux, с возможностью ssh-доступа, возможностью прописать свой публичный ключ, установленным там git, mysql, php, nginx/apache
3. Сервер на котором у вас будет удалённый git-репозиторий. Он может быть либо на том же самом web-сервере, либо на отдельном сервере, специально предназначенном для этого, либо это может быть сторонний сервис для хранения репозитория, такой как github или bitbucket, где вам потребуется аккаунт.

Обозначения

Прежде чем идти дальше, введём обозначения для улучшения понимания:
«Локальный ПК» — это ваша машина на которой вы будете вести разработку. Либо просто ваш рабочий ПК, либо виртуальная машина с Linux’ом.
«Сервер» — это машина, на которой ваш сайт должен будет работать
«Сервер git» — это машина, на которой у вас будет лежать репозиторий git (в данной статье подразумевается, что это тот же ПК что и «Сервер», но это не обязательно)

Подготовка ПК с Linux

Я буду предполагать, что у вас Debian-based дистрибутив, так что:
На локальном ПК запускаем от имени суперпользователя:

apt-get install git ssh

На локальном ПК от имени простого пользователя:
Сначала проверим, есть ли у вас уже ssh-ключи:

$ ls ~/.ssh/id_rsa.pub

Если эта команда выдала имя файла id_rsa.pub, значит он есть, а это и есть ключ (публичный). Если же вывелась пустота, либо сообщение «файл не найден», значит ключа у вас ещё нет, и его надо сгенерировать:

$ ssh-keygen

На все вопросы отвечаем нажатием клавиши Энтер.

Также, вам нужно установить ПО, необходимое для настройки веб-сервера, интерпретатора php и СУБД, чтобы была возможность вести разработку на WordPress. Эта тема выходит за рамки данной статьи, так как предполагается, что если вас заинтересовала работа с wordpress посредством git, ты вы, если и не можете самостоятельно поднять сайт на wordpress на своём ПК, то хотя-бы владеете гуглом, чтобы найти как это сделать 🙂

Подготовка ПК с Windows

Установим git:
1. Скачаем git с официального сайта: https://git-scm.com/download/win
2. Установим его, выбрав в инсталяторе параметры по умолчанию.

Запустим git bash и создадим ключ ssh:
3. Пуск -> Все программы -> Git -> Git Bash -> Запустить от имени администратора — откроется консоль Bash, с которой мы и будем производить все манипуляции. Для работы с git и ssh это очень удобная вещь, так как позволяет работать почти как в Linux из винды. Все дальнейшие команды надо вводить именно в ней. Про cmd надо забыть 🙂
4. Сразу же выполняем в консоли команду:

ssh-keygen

после её выполнения команда задаст пару вопросов, на которые надо отвечать нажатием энтера, и радостно сообщит вам, что ssh-ключи успешно созданы. Эти ключи понадобятся нам для того, чтобы настроить беспарольный доступ по ssh к Серверу и Серверу git

Вам нужно самостоятельно установить WAMP (windows-apache-mysql-php) или любой другой пакет серверных приложений, например Denwer, чтобы иметь возможность разрабатывать сайт на WordPress. Данные сведения выходят за рамки этой статьи.

Сразу предупреждаю:
во-первых, использовать putty для доступа к удалённым серверам в этой инструкции мы не будем. Только ssh из консоли bash, только хардкор!
во-вторых, использовать какие-то GUI-утилиты для работы с git мы тоже не будем (а для удалённого git-а это даже не получится), поскольку, пользуясь консольным git-ом, вы потом с лёгкостью сможете перейти на GUI, но не наоборот.

Слеши в путях в Window я буду писать так «/» (например, «c:/windows/system32»), потому что Windows умеет работать и с «\» и с «/», в терминале git bash, с которым мы будем работать, использует именно такие слеши.

Создание папок проекта

На локальном ПК:
1. Выберем любое место, которое удобно, например /var/www (для linux) или c:/server/ (для windows) и создадим там папку проекта, допустим mysite.local (в Linux для этого понадобится иметь права на запись в /var/www). В дальнейшем я буду называть эту папку «папка проекта»
2. В этой папке создадим папку www (в неё мы будем класть wordpress)
3. Также, рядом создадим папку mysqldump (в неё скрипт обмена данными будет складывать копии базы)

В результате у вас должна получиться примерно такая структура (в linux):
/var/www/mysite.local
/var/www/mysite.local/www
/var/www/mysite.local/mysqldump

Или, в windows, вот такая:
c:/server/mysite.local
c:/server/mysite.local/www
c:/server/mysite.local/mysqldump

4. Перейдем в папку с проектом. В дальнейшем все команды будем выполнять из неё
В Linux:

cd /var/www/mysite.local

В Windows (из консоли git bash):

cd /c/server/mysite.local

5. Создадим файл mysqldump/.gitkeep:

touch ./mysqldump/.gitkeep

Этот файл понадобится для того, чтобы папка mysqldump добавилась в репозиторий, при том, что её содержимое (кроме этого файла) в репозиторий добавлено не будет.

Установка WordPress и необходимых плагинов на локальном ПК

1. Распакуем архив с wordpress (https://wordpress.org/download/) на локальный сервер в папку www, которую вы создали ранее, придумаем ему произвольное локальное доменное имя, например mysite.local.
1.1. Пропишем это доменное имя в /etc/hosts (в linux) или c:/windows/system32/drivers/etc/hosts (в windows), добавив вот такую строчку в начало файла:

127.0.0.1      mysite.local

1.2. Настроим веб-сервер, чтобы доменное имя указанное в hosts вело к папке mysite.local/www, куда установлен wordpress. Описание того как настроить виртуальный хост на сервере, выходит за рамки данной статьи, это слишком простая и общеизвестная информация, и вы наверняка её уже проделывали, раз занимаетесь разработкой сайтов на WordPress (ну а нет — так гугл в помощь :))
1.3. Создадим базу данных, важно назвать её так же, как вы назовёте базу на удалённом сервере. Поскольку, при использовании shared-хостинга, именование баз данных может быть ограничено, у вас может не получиться создать на удалённом сервере базу с любым названием, так что, в случае с шаред хостингом, проверьте, какие имена можно давать базам данных, и если имена ограничены (например должны включать в себя имя вашего аккаунта), то базу на локальном ПК нужно создать такую же.
1.4. Проведём стандартную установку WordPress зайдя по адресу http://mysite.local (или какой там у вас домен?)
2. Установим необходимые плагины:
2.1. Limit login attempts — для ограничения попыткой логина и защиты от брутфорса
2.2. Anti-Malware Security and Brute-Force Firewall — плагин позволяющий проводить сканирование файлов на наличие вредоносных скриптов, а также, включающий свою защиту от брутфорса (придётся зарегистрироваться для обновления определений вирусов)
2.3. Stop Spammers — защита от массовой регистрации спам-пользователей (если у вас на сайте будет открыта регистрация для всех)
2.4. Wordfence Security — мощная система безопасности для WordPress (придётся зарегистрироваться)

Внесение изменений в код для полноценной работы с разными доменами

1. Создадим в корне сайта (то есть mysite.local/www/) файл wp-domains.php (взять его можно здесь: https://github.com/MihanEntalpo/WordpressGitTools/blob/master/wp-domains.php)

Содержимое файла:

<?php
//Проверим, не запускался ли данный скрипт ранее:
if (defined("WP_DOMAINS_INITIALIZED")) return;
define("WP_DOMAINS_INITIALIZED", 1);
 
//Домены на котором может работать сайт, локальные и удалённые,
//*********************************
//*** УКАЖИТЕ ЗДЕСЬ СВОИ ДОМЕНЫ ***
//*********************************
$domains_enabled = array(
    "mysite.local",
    "www.mysite.local",
    "mysite-test.hosting.ru",
    "mysite.ru",
    "www.mysite.ru"
);
 
//Добавим в массив $_SERVER все необходимые для проверки ключи,
//которых там может не быть
$_SERVER = array_replace(
    array(
        "HTTPS"=>"", "HTTP_HTTPS"=>"", "REQUEST_SCHEME"=>"", "SERVER_PORT"=>""
    ),
    $_SERVER
);
 
//Проверим, используется ли https?
$https =
    ((!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off')
        || (!empty($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] != 'off')
        || $_SERVER['REQUEST_SCHEME'] == 'https'
        || $_SERVER['SERVER_PORT'] == 443) ? true : false;
 
//Составим адрес хоста
$site_addr = ($https ? "https://" : "http://") . $_SERVER['HTTP_HOST'] . "/";
 
//Заменим адрес хоста на тот, что мы вычислили
if (!defined("WP_HOME")) define("WP_HOME", $site_addr);
if (!defined("WP_SITEURL")) define("WP_SITEURL", $site_addr);
 
//Добавим обработчик выдачи сайта, который будет заменять во всех ссылках
//домены на текущий домен
ob_start(function($data) use ($domains_enabled, $https) {
    $current_host = $_SERVER['HTTP_HOST'];
    $replace = array();
    $scheme = $https ? "https" : "http";
    foreach($domains_enabled as $domain)
    {
        if ($current_host == $domain) continue;
        $replace["http://$domain/"] = "$scheme://$current_host/";
        $replace["https://$domain"] = "$scheme://$current_host";
        $replace["//$domain/"] = "//$current_host/";
        $replace["//$domain"] = "//$current_host";
    }
    return str_replace(array_keys($replace), array_values($replace), $data);
});

2. В начале файла в список доменов $domains_enabled включим все домены, на которых будет работать сайт. Это нужно потому, что wordpress, при редактировании страниц, вписывает в текст абсолютные ссылки на страницы и объекты вашего сайта. А ссылки эти могут включать в себя любые домены из тех, на которых может работать сайт. Чтобы, кликнув по ссылке на странице локального сайта, не перейти на боевой, или наоборот, функция в конце wp-domains.php, завёрнутая в ob_start, перед выдачей WordPress’ом страницы заменит все ссылки на неправильные домены вашим текущим доменом.
Допустим, вписываем туда домены «mysite.local», «www.mysite.local», «mysite.ru», «www.mysite.ru».

3. В начале файлов: wp-config.php, wp-load.php, в самом начале вставим такую строчку:

<?php require_once(__DIR__ . "/wp-domains.php");

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

Теперь нужно проверить ваш сайт, работает ли он как следует с данными изменениями.

Открываем в браузере http://mysite.local (или какой там у вас локальный домен) и убеждаемся что он работает.

Настройка git

На локальном ПК:
1. Создадим файл .gitignore в папке проекта, и запишем в него следующий код:

/www/wp-content/ai1wm-backups/
www/wp-content/wflogs/
*.log
*.sql
*.sql.gz
error-logs.txt

Изображения (папка uploads) мы не будем исключать из репозитория, потому что, по сути, изображения являются частью сайта, а не просто загружаемым пользователем контентом. При изменении изображений на удалённом сервере (на боевом) мы также будем добавлять их в репозиторий с помощью инструмента rgit, описанного далее

2. Инициализируем репозиторий, добавим в него все файлы и закоммитим
На локальном ПК:

$ git init
$ git add .
$ git commit -m "Initial commit"

3. Добудем публичные ключи для вашего локального ПК и для сервера, чтобы в дальнейшем использовать их для беспарольного доступа к git и к серверу.

3.1. На вашем локальном ПК (в windows или linux) выполним:

ls ~/.ssh/id_rsa.pub

Если в результате будет отображено имя файла, значит всё в порядке, публичный ключ у вас есть.
Если же вместо имени файла будет подобное сообщение:

ls: невозможно получить доступ к ~/.ssh/id_rsa.pub1: Нет такого файла или каталога

значит ключа у вас нет, и нужно его создать простым способом:
(Также, не важно, в linux или windows)

ssh-keygen -t rsa -b 4096 -o -a 100

После выполнения данной команды будет выдано два вопроса: где хранить файл, и какой пароль на него задать. На оба вопроса рекомендую отвечать нажатием Энтер, ничего не вводя.

Теперь посмотрим содержимое публичного ключа:

cat ~/.ssh/id_rsa.pub

данная команда выдаст вам что-то вроде этого:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLuC89TPgs4pX1TjRxsDKZUpBalOC3KS71bUnt/XKx3tFvDqMag0xQpdVCHwWcj1/Q+m//56w9DYTOGXXGBysnNNwIk4oifv6X4voZ/rL0/Aulaxyr+zJX4bJpXqxxeSNVLdqqTOlg84+kqrtSAzx1wAiByV4awZU5RSA+U0P225P9R0BMoBA1rD7+9+b3NBYDYDSk0X8+OjS6HDgqntY9OiMMBV3GvPw+cQd4ha9RM8tou8ZrgTRRNCt7gxO1Oxfn0D7P+8UyZenu3EyIWwnVovhCuSelyaw3WnICEDFxJ3ZLBg42M2TGOLveSheVyRgal1HLVdX9e+mu+Vp5zpH1 user@LinuxPc

Вот эта абра-кадабра и есть публичный ключ вашего локального компьютера, её надо скопировать полностью от слова «ssh-rsa» до слова «user@LinuxPc», вместо которого должно быть «вашПользователь@ИмяХоста».
В дальнейшем, когда я буду писать «вставьте публичный ключ вашего локального ПК» это будет значить что нужно вставить как раз вот этот набор символов.

3.2. Зайдём на ваш сервер по SSH и проделаем там тот же набор действий что и на локальном ПК (предыдущий пункт 3.1.), в результате получим второй публичный ключ, а этот раз — публичный ключ сервера. Его тоже скопируйте себе куда-нибудь.

3.3. Если у вас ещё нет беспарольного доступа по SSH на ваш сервер с вашего локального ПК, самое время его получить:
Заходим по SSH на ваш сервер (какой там у вас домен и пользователь?):

ssh myuser@myserver.ru

На сервере вы должны перейти в пользователя, от имени которого будет работать ваш веб-сервер, обычно его зовут www-data.
Для этого вам надо перейти в суперпользователя, а из него уже в пользователя www-data.
Если у вас на сервере debian или другой дистрибутив, в котором есть команда su, а sudo изначально не настроено, запускаем:

su
su www-data

Если же у вас на сервере ubuntu, то команда будет немного другой:

sudo su www-data

После перехода в пользователя www-data нужно открыть файл с ключами авторизации SSH текстовым редактором:

nano ~/.ssh/authorized_keys

после того как редактор откроется, вам нужно будет вставить туда публичный ключ вашего локального ПК. Причем он должен быть размещён на отдельной пустой строке. После завершения нужно нажать Ctrl+O чтобы сохранить изменения и Ctrl+X чтобы выйти.
Для проверки вы можете отключиться от сервера и попробовать подключиться к нему вновь с помощью команды с локального ПК:
(какой там у вас домен?)

ssh www-data@myserver.com

Если всё сделано правильно, то вам удастся подключиться к серверу от имени пользователя www-data без ввода пароля (тем более что он у www-data скорее всего даже и не задан, поэтому с паролем зайти не получится)

4. Создадим удалённый репозиторий где-нибудь, где вам это доступно.
Вам нужен репозиторий, доступный и с вашей машины, и с «боевого» сервера.
Варианты:
а) Создать репозиторий на bitbucket.com — почти как гитхаб, только лучше, ведь в нём можно создавать приватные репозитории
б) Создать репозиторий на каком-то своём сервере, пусть даже на самом боевом.
в) Создать репозиторий на github.com — легко и удобно, минус в том что там он будет публичным

Выбирайте что вам по душе, я же буду рассказывать про третий вариант, так как он даёт наибольшую гибкость и независимость.

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

Вариант с использованием репозитория на bitbucket

4.1.а. Зарегистрироваться на bitbucket.org, либо, если вы уже зарегистрированы, то авторизоваться.
4.2.а. На левой панели нажать на «плюсик» и в появившейся панели выбрать «Репозиторий»

Нажимаем плюсик

Выбираем создание репозитория

4.3.а. Вводим название репозитория и нажимаем кнопку

4.4.а. На странице репозитория вы можете, во-первых получить адрес репозитория, по которому вы можете его, например, склонировать командой git clone <адрес> (запишите этот адрес, ещё пригодится), а, во-вторых, открыть настройки.

4.5.а. На странице настроек нужно выбрать пункт «Access keys» (или «ключи доступа»), затем нажимаем кнопку добавления ключа:

Появится примерно такое окно:

4.6.a. Вводим произвольное название ключа и сам публичный ключ вашего локального ПК:

4.7.а. Повторяем предыдущие два пункта чтобы ввести ещё и публичный ключ вашего удалённого сервера (полученный на этапе 3.3)

Теперь и на вашем локальном ПК и на сервере будет доступ к репозиторию без ввода логина и пароля.
Не забудьте скопировать адрес репоизтория, который было видно на этапе 4.4.а, пригодится.
Выглядеть он должен примерно так:

git@bitbucket.org:MihanEntalpo/mysite.git

где вместо «MihanEntalpo» будет ваш логин в bitbucket.org, а вместо «mysite» будет название вашего репозитория.

Вариант со своим личным сервером для git-репозитория

Если вы воспользовались bitbucket’ом, то этот блок можете пропускать

Для размещения git-репозитория можно использовать виртуальный сервер, купленный, например на vscale.io. Цены там сравнимы с ценами на shared-хостинг, от 200 рублей в месяц, и на этом сервере вы царь и бог.
В дальнейшем, как и договаривались, я буду называть его сервер git

4.1.б. Создадим пользователя git и перейдём в него:
На git-сервере выполняем от рута:

# adduser git
# su git

4.2.б. Создадим папку для нового bare-репозитория, и внутри неё репозиторий:

mkdir /home/git/mysite.git
cd /home/git/mysite.git
git init --bare

4.3.б. Добавим доступ по ssh к пользователю git без пароля

На git-сервере от имени пользователя git:
Убедимся в том что папка ~/.ssh существует:

mkdir -p ~/.ssh

Откроем файл с ключами:

$ nano /home/git/.ssh/authorized_keys

Откроется текстовый редактор, где на одну строку надо вставить скопированный вами ранее публичный ключ от локального ПК, а на другую — скопированный ключ от сервера, и сохранить файл, нажав Ctrl+O. Выход — Ctrl+X

Нужно запомнить адрес репозитория для использования с git’ом, в данном случае он будет представлять собой что-то вроде:

git@gitserver.ru:/home/git/mysite.git

где вместо «gitserver.ru» — доменное имя вашего git-сервера, а mysite.git — имя папки git-репозитория.

5. Добавим данный репозиторий как удалённый (remote) в ваш локальный репозиторий.
Если ваш сервер имеет адрес mysite.ru, а репозиторий mysite.git, то команда будет такой:
На локальном ПК:

$ git remote add origin git@mysite.ru:mysite.git

5.1. Выгрузим все изменения из вашего локального репозитория в удалённый:

$ git push

6. Настроим сайт на боевом сервере:

6.1. Дадим пользователю вашего боевого сайта беспарольный доступ к репозиторию git:
Допустим, пользователя зовут remoteuser:
На сервере:
Если ещё нет ssh-ключа:

ssh-keygen

Выведем публичный ключ:

cat ~/.ssh/id_rsa.pub

Данный ключ нужно записать туда же, куда вы записывали свой личный ключ 3.3.

6.2. Склонируем репозиторий в папку /var/www/mysite.ru:
На сервере:

$ cd /var/www
$ git clone git@mysite.ru:mysite.git mysite.ru

На сервере:
6.3. Создадим базу данных с тем же логином и паролем, что на локальном сервере, загрузим в неё дамп базы с локального сервера
Это остаётся вам в качестве домашнего задания 🙂

Создадим полезные в работе скрипты

Несколько скриптов, без которых данная статья была бы невозможна: rgit, mysqltool, gcb. Все эти скрипты нужно располагать рядом с папкой www в вашей папке с сайтом.

1. Создадим скрипт в корне проекта «rgit» — предназначен для дистанционного выполнения команд git на удалённом сервере.
Можно было бы навесить хуки гита для автоматического обновления боевого сайта, однако, в случае с WordPress это будет неудобно, потому что сайт могут править и на боевом сервере, устанавливать там плагины, обновлять сам wordpress. А когда сайт заработает, то не просто «могут» а «обязательно будут».

На вашей локальной машине создадим скрипт rgit в папке проекта:

nano ./rgit

В файл добавим следующий код (разумеется, логин пользователя, адрес сервера, и папку вашего проекта на сервере нужно поменять):

#!/bin/bash
ARGS=$(printf '"%s" ' "$@")
CMD="cd /var/www/mysite.ru &amp;&amp; git $ARGS"
ssh remoteuser@mysite.ru "$CMD"

Делаем этот скрипт выполняемым:

chmod +x ./rgit

Теперь любую команду git-а, которую вы можете запустить в локальном репозитории, вы также можете запустить и в удалённом, никуда не подключаясь и не переходя, практически не меняя команды, только вместо «git» вы будете начинать команду с «./rgit».
Например:

Где нужно выполнить команду Команды
Локальный сервер git pull git push git reset —hard git checkout mybranch
Удалённый сервер ./rgit pull ./rgit push ./rgit reset —hard ./rgit checkout mybranch

Как и было сказано, команда отличается только началом.
Что нам это даёт: мы можем находясь в локальном репозитории командовать также и удалённым.
Пример работы:

Добавляем изменения локальных файлов в коммит

git add .

Создаём коммит с локальными изменениями

git commit -m "Upgrade wordpress to a new version"

Добавим изменения удалённых файлов в коммит

./rgit add .

Создадим коммит на удалённой машине

./rgit commit -m "Uploaded new photo"

Выгрузим удалённые изменения в репозиторий

./rgit push

Загрузим изменения из репозитория в локальный репозиторий

git pull

Выгрузим изменения из локального репозитория

git push

Загрузим изменения из репозитория на удалённый сервер

./rgit pull

2. Скрипт mysqltool.php
Этот скрипт гораздо больше по объёму, поэтому приводить здесь его полный текст не буду, его нужно скачать из репозитория: https://github.com/MihanEntalpo/WordpressGitTools/blob/master/mysqltool.php
Данный скрипт предназначен для удобных операций с базой данных, локальной и удалённой. С помощью него вы в одну команду сделаете дамп базы на локальном или удалённом сервере, выгрузите локальную базу на удалённый сервер, или загрузите базу с удалённого сервера на локальный. И всё это без колдовства с mysql, mysqldump, ssh ручным вводом паролей и команд.
Вся работа со скриптом mysqltool.php выполняется на вашем Локальном ПК, когда команда требует выполнения дампа или загрузки БД на Серверном ПК, скрипт автоматически вызывает свою копию, лежащую на Серверном ПК посредством ssh.

Примеры команд:
Снять образ локальной базы данных:

./mysqltool.php dump local

Снять образ удалённой базы данных:

./mysqltool.php dump remote

Снять образ удалённой базы данных, и загрузить её вместо локальной базы.

./mysqltool.php pull

Снять образ локальной базы данных, и загрузить её вместо удалённой базы.

./mysqltool.php push

Запросить справку по работе со скриптом можно вызвав его без параметров, либо командой:

./mysqltool.php help

С помощью данного инструмента можно значительно облегчить себе работу с базой данных. Когда вы что-то меняли на «боевом» сервере, то перед началом работы на локальном можно выполнить ./mysqltool.php pull, а по окончанию работы, после выгрузки изменений в файлах через git, можно выгрузить и базу данных с помощью ./mysqltool.php push

Перед каждым разрушительным изменением, таким как push и pull делается дамп той базы, которая будет заменена, так что вы сможете её восстановить при необходимости.

Конфигурация скрипта:
Для конфигурации рядом со скриптом нужно положить файл mysqltool.conf.php примерно со следующим текстом:

<!--?php
return array(
    "remote" =--> array(
        "sshhost" =&gt; "remoteuser@mysite.ru",
        "folder" =&gt; "/var/www/mysite.ru"
    )
);

Где sshhost — Это логин@хост для доступа по ssh к вашему боевому сайту, а folder — путь к папке с сайтом. Логин, пароль, и хост базы данных скрипт сам возьмёт из конфигурации wordpress.

Делаем скрипт выполняемым (поскольку в нём есть shabang, его можно запускать «просто так», не указывая в начале команды «php «):

chmod +x ./mysqltool.php

Рядом со скриптом также должна лежать папка mysqldump (которую мы как раз для него создавали вначале). В эту папку скачиваются дампы локальной и удалённой базы.
Также, рядом со скриптом должна быть папка www с сайтом wordpress, пока изменить её нельзя (её название зашито в скрипт), чуть позже я добавлю возможность указывать наименование папки в конфигурационном файле. В этой папке скрипт ищет файл wp-config.php, и извлекает из него конфигурацию базы данных. Это позволяет не хранить логин/пароль и название БД в конфигурационном файле скрипта, а обойтись уже существующим wp-config.php

3. Скрипт ./gcb
Данный скрипт предназначен для упрощения работы с ветками. Данный скрипт также можно взять из репозитория: https://github.com/MihanEntalpo/WordpressGitTools/blob/master/gcb
Эксплуатация:
Получить список локальных и удалённых веток, узнать текущую ветку:

./gcb

Создать новую ветку, причём как в локальном так и в удалённом репозитории, чтобы команда git push, запущеная в другой ветке нежели master выгружала изменения в аналогичную ветку на сервере.

./gcb new_branch_name

Переключиться на существующую ветку:

./gcb development

4. Добавим все эти скрипты в репозиторий и выгрузим их в удалённый репозиторий:

git add .
git commit -m "Added some usefull scripts"
git pull
git push

Итоги:

В результате данной инструкции можно перейти на разработку на wordpress с использованием git в команде, перестать мучаться с выгрузкой по FTP, и с ручным переносом баз данных.
Остаются правда некоторые неудобства, связанные, опять же, с базой, в частности: при работе командой нужно заранее связываться друг с другом и предупреждать о том, кто выгружает базу данных, а кто её себе загрузит, так как частично базу изменить нельзя, только полностью одним махом.
Тем не менее, способ вполне рабочий, и сильно облегчает жизнь. Может и вам пригодится.


62 комментария

  • Ответить Stepan |

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

    • Ответить mihanentalpo |

      Спасибо. Вообще, собирался пройтись по статье ещё раз и более детально расписать некоторые ньюансы. Если вопросы остались — не обязательно ждать, пока я улучшу статью, можно их задать здесь 🙂

      • Ответить Stepan |

        Отлично! Очень оперативно, спасибо. Да я собственно и не надеялся получить ответ поэтому и не стал задавать вопросы, я как раз сейчас пытаюсь настроить связку, все трудности и неразрешимые моменты опишу здесь, буду рад помощи. Но так как делаю это впервые, скорей всего процесс подзатянется.

        • Ответить mihanentalpo |

          Ну как, удалось настроить окружение для работы с git-ом в вродпрессе? Или возникли непреодолимые проблемы?

  • Ответить Stepan |

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

    • Ответить mihanentalpo |

      Если putty, тогда понятно почему проблемы. Это ты значит из винды работаешь 🙂 Вообще инструкция рассчитана что работаь будешь из Linux, или хотя-бы у тебя будет виртуальная машина с Linux’ом, откуда и будешь выполнять команды.
      С виндой всё несколько сложнее. Чтобы создать приватный и открытый ключ в винде, используется программка puttygen (если не ошибаюсь).
      adduser git — надо запускать от суперпользователя, у простого смертного разумеется доступа не будет к такой команде.
      Вообще, руководство для новичков, наверное, получилось сложноватое, писал его в расчёте на людей, которые с wordpress и linux’овой консолью уже поработали, но не учёл, что сайты на WordPress можно и под виндой делать 🙂
      В общем, попробую расписать более подробно не очевидные вещи.

  • Ответить Stepan |

    Да, работаю из под винды, с линуксом я к сожалению на вы, новичок это точно, с worpress-ом знаком. Был бы признателен за более подробное разъяснение. Благодаря твоей статье вероятно поставлю Linux второй системой ну или виртуалку подниму.

    • Ответить mihanentalpo |

      Я решил расширить статью, добавив в неё инструкции о том, как настроить всё тоже самое из Windows, не устанавливая Linux на виртуалку. Не уверен что напишу быстро, но по паре абзацев в день будет.

  • Ответить Stepa |

    Привет! Опять застрял я. Есть скайп голосом переговорить? Если есть минутка. Объясню в чем затык.

    • Ответить mihanentalpo |

      Есть почта (указана справа), можно на неё написать или здесь в комментах. Комменты для того и нужны чтобы ты написал о своей проблеме, я ответил — а потом другие с такой же проблемой смогли это прочитать и воспользоваться.

    • Ответить mihanentalpo |

      Отлично! Для будущих поколений будет полезно, если ты напишешь в чем была проблема, и как ты её решил.

      • Ответить Stepa |

        Ok, напишу чуть позже) Еще вопрос: nano ./rgit, непонятно, с nano у меня проблема возникла, по сути это редактор, а rgit по сути просто файл который делаем впоследствии исполняющим? или я чего то недопонимаю? А если так git config core.editor notepad разница будет?

        • Ответить mihanentalpo |

          да, nano — текстовый редактор, можно вместо него пользоваться чем угодно, вместо notepad рекомендую notepad++
          rgit — это файл, который делается исполняемым. Так что всё правильно ты понимаешь

  • Ответить Stepa |

    И кстати откуда взялся такой путь:ssh remoteuser@mysite.ru «cd /var/www/mysite.ru && git $@», ну понятно логин сервер свои но откуда в пути появилось var? ни на локалке ни на серваке нет, в статье тоже до этого момента не было.

    • Ответить mihanentalpo |

      Всё правильно. Этот скрипт подключается по SSH к твоему удалённому серверу, и выполняет на нём команду cd /var/www/mysite.ru && git $@, а в папке /var/www/mysite.ru у тебя на боевом сервере будет лежать сайт. Настройка боевого сервера это пункт 6 и его подпункты в разделе «Настройка git», в частности, команда git clone для клонирования репозитория в нужную папку (в примере это /var/www) выполняется в пункте 6.2

  • Ответить Stepa |

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

  • Ответить Stepa |

    Вобщем почти все осилил осталось только разобаться с путями, настроить ветки, и протестить все скрипты.

  • Ответить Dimas |

    Автору респект и уважуха! Подскажи, на какой системе Linux все это проделывал? На Ubuntu Server 17.04 запнулся тут: git commit -m "Initial commit" а запнулся вот так:

    Initial: command not found

    [1]- Exit 129 git commit -m
    [2]+ Exit 127 Initial commit

    Не подскажет ни кто синтаксис для ubuntu

  • Ответить mihanentalpo |

    Реализовывал всё это на Debian, однако, работать должно в любой linux-системе. Это же bash и это же git.
    Судя по твоим ошибкам, у тебя после -m не были проставлены кавычки.
    Должно быть именно: git commit -m «initial commit» (к слову, в кавычках, вместо initial commit можно написать «первый коммит» или что угодно ещё, это просто текст коммита).
    Покажи конкретную команду которую ты вводил

  • Ответить Dimas |

    2. Инициализируем репозиторий, добавим в него все файлы и закоммитим
    На локальном ПК:

    $ git init
    $ git add .
    $ git commit -m "Initial commit"

    • Ответить mihanentalpo |

      Если эта команда не срабатывает — скинь скриншот терминала, в котором ты её ввел и тебе вернулся ответ об ошибке.

  • Ответить Dimas |

    root@vkhatange:/var/www/vkhatange.click.local# ./rgit push
    Welcome to LTD BeGet SSH Server ‘rex’
    fatal: No configured push destination.
    Either specify the URL from the command-line or configure a remote repository using

    git remote add

    and then push using the remote name

    git push

    Что я где не докрутил?

    • Ответить mihanentalpo |

      Эта ошибка означает что ты на удалённом репозитории не настроил remote-репозиторий, то есть не подключил туда аккаунт bitbucket’а (например)

  • Ответить Dimas |

    Победил! 🙂 А это что:
    Cloning into ‘вхатанге.рф’…
    ssh: Could not resolve hostname \320\262\321\205\320\260\321\202\320\260\320\275\320\263\320\265.\321\200\321\204: Name or service not known
    fatal: The remote end hung up unexpectedly

  • Ответить Dimas |

    Базу все равно придется руками править? Там же постоянные ссылки и вообще имена доменов разные…

    • Ответить mihanentalpo |

      Для базы дан mysqltool.php — инструмент для переноса базы. Для имён доменов файл wp-domains.php, написано же всё!

  • Ответить Dimas |

    Хочу поблагодарить автора за потраченное на меня время. Домучали git вместе. Настривал все с нуля раз 5 это точно. В итоге по совету Михаила посмотрел в сторону Syncthing, т.к для моей задачи он подходит больше, чем git и остановился на нем, но знания ни когда лишними не бывают. Спасибо, Михаил!

  • Ответить Дмитрий |

    Можно немного поподробней про скрипт mysqltool.php
    его нужно положить рядом с www как на боевом сервере так и на локальном ?
    На каком из серверов (локальном или боевом) выполнять все эти команды :
    Примеры команд:
    Снять образ локальной базы данных:

    ./mysqltool.php dump local
    Снять образ удалённой базы данных:

    ./mysqltool.php dump remote
    Снять образ удалённой базы данных, и загрузить её вместо локальной базы.

    ./mysqltool.php pull
    Снять образ локальной базы данных, и загрузить её вместо удалённой базы.

    ./mysqltool.php push
    Запросить справку по работе со скриптом можно вызвав его без параметров, либо командой:

    ./mysqltool.php help

    • Ответить mihanentalpo |

      Привет 🙂
      1) mysqltool.php должен лежать рядом с папкой www (если положить его внутрь — придётся защищать его от доступа из веба, с помощью настроек веб-сервера, что нам ни к чему). Вообще, папка www нужна mysqltool’у для того, чтобы, взяв из неё wp-config.php, извлечь оттуда информацию для подключения к базе данных — таким образом не нужно хранить логины-пароли где-то кроме wp-config.php
      2) Сейчас вспомнил, что папка должна называться ИМЕННО www, иначе он её не найдёт. Это, очевидно, неправильное решение, так как папку можно захотеть назвать как угодго, поэтому это я в ближайшее время поправлю. Добавлю опцию конфигурации, позволяющую задать произвольную папку.
      3) Лежать скрипт должен и на сервере и на клиенте, так как все команды, требующие удалённого выполнения («снять образ удалённой базы», «снять образ локальной базы и залить на удалёнку») выполняются скриптом с помощью ssh, он просто вызывает свою собственную копию на сервере.
      4) Рядом должен лежать конфиг-файл mysqltool.conf.php, где должен быть указан ssh-сервер и папка, в которой лежит удалённый mysqltool.php и www рядом с ним — чтобы локальный mysqltool.php знал, как вызывать своего удалённого собрата по ssh, и в какой папке он лежит.
      5) Рядом с mysqltool.php (и на сервере и на клиенте) должна быть папка mysqldump, доступная для записи (её пока тоже нельзя изменить, добавлю возможность менять её через конфиг-файл), туда будут складываться дампы.
      6) Выполнять команды нужно на ЛОКАЛЬНОМ хосте, так как он знает как подключиться к удалённому. А вот удалённый к твоему локальному подключиться скорее всего не сможет.

      Вообще всё заточено на то, что mysqltool.php и его друзья будут в git-репозитории и поэтому и на сервере и на локалхосте автоматически будут одни и те же файлы и настройки.
      Единственный минус здесь — нео

  • Ответить Дмитрий |

    спасибо за разъяснение, очень доступно и понятно, у меня всё получилось, правда папка у меня не www, я сам поправил в коде скрипта.

  • Ответить Дмитрий |

    ну и после замены базы данных для разработке на локальном серваке нужно поменять адрес сайта на localhost (в базе данных):
    UPDATE wp_posts SET post_content = REPLACE(post_content, ‘z-site.ru’, ‘localhost’);
    UPDATE wp_posts SET guid = REPLACE(guid, ‘z-site.ru’, ‘localhost’);
    UPDATE wp_options SET option_value = REPLACE(option_value, ‘z-site.ru’, ‘localhost’);
    UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, ‘z-site.ru’, ‘localhost’);

    • Ответить mihanentalpo |

      На самом деле, если ты пользуешься правильно настроенным файлом wp-domains.php, то в этих манипуляциях нет нужды. Всё будет работать и так.

  • Ответить Дмитрий |

    Привет! Спасибо за статью. У меня вопрос по поводу дампов баз. Я может не совсем все понимаю, но при указанном способе перенос базы данных осуществляется напрямую (локальные серверы -> боевой сервер и наоборот), что вызывает некоторые трудности, например откат к предыдущей структуре базы при откате к предыдущему коммиту. Нет ли смыла поместить дамп базы под версионный контроль (на bitbacket например) и загружать базу на любой сервер после сравнения версий дампов? Т.е. каждый конкретный дамп ввести в соответствие конкретному коммиту?
    Приблизительная логика:
    1. Сделать дамп на локальной машине с помощью php-скрипта.
    2. Закоммитить изменения и спуллить их на bitbacket .
    3. На сервере слить коммит
    4. Запустить скрипт, который выгрузит из дампа базу.

    • Ответить mihanentalpo |

      Привет. Да, можно поместить базы под версионный контроль. В принципе, сейчас всё что останавливает тебя от этого — это .gitignore. Достаточно убрать оттуда пункт mysqldump, и все дампы баз будут попадать в коммиты. В принципе даже можно сделать скрипт для автоматического разворота последнего дампа, пришедшего после git pull.
      Однако, данная система действий не совсем подходит для того основного режима работы, в котором обычно используется wordpress. А именно:
      1. Сначала ведёшь разработку на локальном сервере
      2. Потом выгружаешь на боевой и показываешь клиенту
      3. Клиент заходит на сервер и начинает разбираться в админке, смотреть что там есть, загружать файлы, писать статьи. В какой-то момент он просит тебя сделать доработки.
      4. Ты делаешь доработки на локальном сервере, однако, если они затрагивают изменение БД, то как тебе перенести их к клиенту?
      4.1. Первый вариант — иметь некую сложную систему миграций, которая позволяет выделять изменения в отдельные блоки и применять их без разрушения БД клиента. Но в рамках wordpress, где каждый плагин может делать с базой неизвестно что, этот путь слишком сложен.
      4.2. Второй вариант — перед тем как начать делать доработку, ты говоришь пользователю: не вносите пока больше изменений. Делаешь mysqltool.php pull, и вот у тебя уже полная копия БД клиента. Также, как мы знаем, кроме БД есть ещё и файлы, например, изображений. Чтобы получить их, ты выполняешь ./rgit add . && ./rgit commit -m «Изменения клиента» && ./rgit push && git pull.
      Теперь у тебя, буквально в 2 действия, появилась полная копия удалённого сайта с базой. Вносишь свои изменения, правишь базу (например, пользователь попросил удалить из статей все ссылки на сторонние ресурсы, которые он по ошибке вставил), после чего делаешь git add . && git commit -m «Мои мощные изменения» && git push && ./rgit pull && mysqltool.php push, и всё, у клиента на боевом сервере полная рабочая копия сайта с твоими доработками, и его данными, которые он вносил на момент начала твоих доработок.

  • Ответить Дмитрий |

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

    • Ответить mihanentalpo |

      Спасибо за комментарий, на самом деле сама статья в порядке, это глючит модуль подсветки синтаксиса 🙂 После пересохранения статьи всё начинает отображаться как надо. Заодно исправил конструкции вида &quot;

    • Ответить mihanentalpo |

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

  • Ответить mihanentalpo |

    Привет. Проверил, вроде с кодом всё норм. Укажи пожалуйста на примеры блоков которые неправильно расставлены

Оставить комментарий