Полуавтоматический деплой приложения из GIT-репозитория

Обсудить
Полуавтоматический деплой приложения из GIT-репозитория

На дворе не 2005 год, и уже давно пора перестать заливать обновления сайта архивами или отдельными файлами через FTP. Как же доставлять обновления?

Современный подход к развёртыванию веб-приложения подразумевает использование Docker'а вкупе с Kubernetes, а тестирование и сборка приложения перед этим происходит в пайплайнах (pipeline) какой-нибудь системы непрерывной интеграции (CI).

Но зачем все эти ресурсоёмкие сложности, если у Вас простой сайт на обычном хостинге, на котором поддержка докера не предусмотрена?

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

Почему git worktree?

Если вы привычным образом склонируете репозиторий в public_html, то рискуете оставить папку с именем .git общедоступной (а это исходный код вашего приложения). На неё придётся прописывать правила в .htaccess или прибегать к иным костылям. В любом случае это небезопасный путь.

С git worktree клон репозитория может находится в укромном местечке, а в отделённой ветке будет файл с именем .git, в котором будет указан только путь до клона.

Кроме того, имея всего один клон репозитория, вы можете выделить из него разные ветки на несколько сайтов. Например, ветка test на тестовую версию сайта, а ветка production на боевую версию.

Настройка хостинга и первичная установка приложения

Папка bin

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

mkdir $HOME/bin
export PATH=$HOME/bin:$PATH

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

export PATH=$HOME/bin:$PATH

Вы можете сделать это с помощью следующей консольной команды:

echo "export PATH=\$HOME/bin:\$PATH" > $HOME/.bash_profile

Содержимое .bash_profile будет исполняться SSH-клиентом по умолчанию при подключении.

PHP

Если в своём проекте вы используете PHP, то учтите, что по умолчанию в консоли обычно используется PHP 5.3 (введите php --version, чтобы узнать версию). Для удобства использования в консоли PHP той версии, которая вам нужна, добавьте в папку bin ссылку. На примере PHP 7.2:

cd $HOME/bin; ln /opt/php7.2/bin/php php -s

Теперь php --version вернёт PHP 7.2.15 (примечание: минорная версия может отличаться).

Также разместите в папке bin последнюю версию Composer.

Важно: не забывайте о правах на чтение/запуск исполняемых файлов в папке bin.

Сертификаты

Если ваш проект находится в закрытом git-репозитории, то хосту понадобятся права доступа.

Можно использовать логин и пароль от учётной записи с правами, но мы поступим правильно и сгенерируем Deploy key (ключ, дающий доступ к репозиторию только на чтение).

В консоли пишем:

ssh-keygen -t rsa -f id_rsa

Для каждого сервера (gitlab, bitbucket, github...) можно сгенерировать свой ключ, меняя значение id_rsa параметра -f.

В домашней папке появится папка с именем .ssh, в которой будут находиться сгенерированные приватные и публичные ключи. Создадим файл ~/.ssh/config со следующим содержимым:

Для gitlab:

Host gitlab.com
RSAAuthentication yes
IdentityFile ~/.ssh/id_rsa

Для bitbucket:

Host bitbucket.org
IdentityFile ~/.ssh/id_rsa

Для разных хостов записи с одинаковыми или разными ключами можно совместить в одном файле. Пример:Host gitlabПубличный ключ (содержимое файла id_rsa.pub) необходимо добавить в список ключей развёртывания (Deploy Keys) репозитория.Deploy KeysФорма для добавления ключа развёртывания в GitLab

GIT

На многих хостингах рунета по сей день крутится древний Centos с версией git 1.8.3. Такая старая версия git'a абсолютно нам не подходит. Команда git worktree появилась ещё в 2015 году в git 2.5, а в git 2.7 значительно расширилась по функционалу.

Но не беспокойтесь, на машинах Timeweb предустановлен git 2.7.4.

Подготовим папку ~/git для размещения в ней клонов git-репозиториев и перейдём в неё:

mkdir $HOME/git
cd $HOME/git

Клонируем репозиторий project-name в папку project-dir:

Перед выполнением команды замените путь до git-репозитория и имена ветки и проекта на свои.

git clone --mirror -b master git@gitlab.com:contributor/project-name.git project-dir

где "master" – имя ветки, на которую будет переключен клон по умолчанию (если не указывать, то будет выбрана «основная ветка»).

ВАЖНО: следует указать ту ветку, которая не будет участвовать в разворачиваемых приложениях, т.к. дерево worktree нельзя создать из активной ветки. Например, если у вас есть ветки master, test, production, то следует выбрать master, а test и production будут вскоре развёрнуты.

Как и на многих хостингах, в Timeweb применяется практика с использованием папки public_html в качестве корневой папки сайта (веб-папки проекта). Если у вас мультисайтовый аккаунт (более одного сайта на хосте), то и папок public_html несколько. Например:

  • ~/www-project-name/public_html - для боевого приложения,
  • ~/www-test-project-name/public_html - для тестов.

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

Обычно веб-папка проекта не всегда совпадает с корневой папкой приложения: в веб-папке принято размещать только публичные файлы — JS-скрипты, картинки, стили, шрифты; а также файл скрипта для инициализации приложения. Весь рабочий код остаётся вне веб-папки. Эта практика приводит к единственному решению — public_html должна быть ссылкой на веб-папку проекта. Сам проект можно разместить рядом, в папке branch.

Развернём ветку production. На этом этапе уже пора добавить в админской панели свой сайт www-project-name и вместе с тем создадутся папки ~/www-project-name/public_html. Папку public_html со страницей-заглушкой нужно сразу удалить. Теперь создаём worktree в папке ~/www-project-name/branch:

cd $HOME/git/project-dir
git worktree add $HOME/www-project-name/branch production

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

ln -s $HOME/www-project-name/branch/web $HOME/www-project-name/public_html

Поскольку в моём приложении есть и ветка test, то таким же образом я разверну и её:

cd $HOME/git/project-dir
git worktree add $HOME/www-test-project-name/branch test
ln -s $HOME/www-test-project-name/branch/web $HOME/www-test-project-name/public_html

Установка приложения

На текущем этапе все файлы нужных веток репозитория проекта размещены в соответствующих каталогах:

~/www-project-name/branchproduction-ветка

~/www-test-project-name/branchtest-ветка

Осталось установить и настроить приложение. Переходим в корневую папку приложения:

cd $HOME/www-project-name/branch

Настройте конфигурационные файлы, которые, кстати, должны быть предварительно добавлены в .gitignore.

Если вы используете пакетные менеджеры, то подтяните необходимые пакеты. Применительно к Composer:

composer install --no-dev

Установите само приложение. Например, если это Yii2:

php yii init
php yii migrate

VDS Timeweb

Обновление

Приложение развёрнуто. Осталось настроить обновление приложения — вы ведь будете его поддерживать?

Для этого в папке bin создадим скрипт, который будет подгружать изменения из git-репозитория и применять их. На моём сервере это будет файл ~/bin/hi (с правами на запуск):

~/bin/hi

Содержимое файла в моём случае:

echo "Привет!"

echo "";echo "Синхронизация репозитория";
cd $HOME/git/project-dir;git fetch;

echo "";echo "Обновление production";

# переход к файлам приложения
cd $HOME/www-project-name/branch;

# сброс и подгрузка изменений
git reset --hard;git pull origin production;

# установка нужных версий зависимостей
/opt/php7.2/bin/php $HOME/bin/composer install —no-dev;
# к php нужно прописывать полные пути!

# моё приложение поддерживает миграции с бэкапами
/opt/php7.2/bin/php core migrate/up --all --backup;
# для Yii2 это будет ...php yii migrate --interactive=0

echo "";echo "Обновление test";
cd $HOME/www-test-project-name/branch;
git reset --hard;git pull origin test;
/opt/php7.2/bin/php $HOME/bin/composer install --no-dev;
/opt/php7.2/bin/php core migrate/up --all;

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

Такой способ предоставляет обновление в полуавтоматическом режиме. Однако можно настроить и полностью автоматическое обновление приложений, например, сразу после пуша изменений в соответствующую ветку. В этом вам может помочь, например, опция web-push в настройках удалённого репозитория.

Примечание:

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

git reset --hard

Поэтому пользовательские файлы и файлы конфигурации должны быть помещены в .gitignore, чтобы git их не удалил при обновлении.

VDS

Комментарии

Рекомендуем