Разработчики программ рано или поздно сталкиваются с задачей автоматического развертывания проектов на удаленном ресурсе. Причем часто пользуются облачными серверами из-за простоты их аренды и удобства масштабирования аппаратных ресурсов, включая дисковое пространство. В этом материале рассмотрим один из вариантов деплоя React-приложений. В качестве примера также рассмотрим альтернативу с архивом.
Нам понадобится собственный gitlab-хостинг с доступом для разработчиков как для пользователей (без защищенного канала SSH), проект на React с регулярным обновлением, поддержкой FTP и хостинг для домена на Timeweb Cloud. Еще потребуется платформа node.js и скомпилированный проект на рабочем компьютере. Решим следующую задачу – реагировать на изменение в репозитории, и:
Проверяем git-хуки терминальной командой git help hooks
. Сразу отметим, что их делят на клиентские и серверные. Первые исполняются на компьютере пользователя, а вторые на хосте. Клиентские размещены по адресу .git/hooks
. Чтобы любой из них стал функционировать, необходимо удалить .sample
. В нашем случае для организации автообновления репозитория будет работать pre-push
, срабатывающий перед запуском копирования информации на удаленный хост.
В gitlab серверные хуки называют WebHooks. Их используют, например, когда поступает какой-то запрос вроде обновления репозитория и его отправляют по заданному HTTP-адресу. Такой подход упрощает отслеживание событий, происходящих внутри проекта, позволяет своевременно и полноценно обрабатывать их при деплое приложений.
Функционал web-хостинга позволяет реализовать следующее:
Подключение к репозиторию организуем при помощи логина и пароля. Ниже будет использован этот способ аутентификации как базовый. Перейдем к созданию репозитория для проекта React после обработки. С этой целью в каталоге с исходниками сгенерируем файл build.bash
, после этого разместим в нем:
#!/bin/sh
cd /var/www/html/my-app/
npm run-script build
cd /var/www/html/my-app/build/
git init
git add .
git commit -m 'build'
git push -f --set-upstream https://login:password@git.address.domain/my-app-build.git master
Приведенный перечень команд позволит перейти в каталог проекта React, запустить компиляцию, а затем вернуться в папку билда и создать локальный репозиторий. В итоге происходит копирование билда на удаленный хост с принудительной перезаписью информации в репозитории.
Теперь зайдет в каталог с хуками (.git/hooks
) и там создадим pre-push
, а в него включим содержание:
#!/bin/sh
nohup /var/www/html/my-app/build.bash &
Отметим, что символ &
в команде nohup
нужен для скрытия вывода терминала. В нашем случае не работает контроль версий, соответственно, при перезаписи репозитория будут стерты все ранее внесенные и потом удаленные комментарии. Созданный репозиторий работает в качестве «точки реагирования», необходимой для итоговой стадии деплоя реакт-приложений. Завершим процедуру преобразованием обоих файлов в исполняемые:
chmod 775 /var/www/html/my-app/build.bash /var/www/html/my-app/.git/hooks/pre-push
Теперь при формировании WebHook для проекта на gitlab зададим URL-скрипт, секретный токен, идентифицирующий источник, пометим push
. И напишем PHP-скрипт, размещенный в корневой папке веб-хостинга. Назовем его _deploy-client.php
и включим в него код:
//запись информации о последнем запросе в тестовый файл
file_put_contents(dirname(__FILE__)."/".basename(__FILE__, ".php").".txt", print_r($_SERVER, true));
//проверка того, что запрос пришел с нужного git-хостинга и токен верен
if($_SERVER["REMOTE_ADDR"] != "xxx.xxx.xxx.xxx" || $_SERVER["HTTP_X_GITLAB_TOKEN"] != "sdf51s65dg1sd31fs3df1w6rg")
exit();
//если скрипт дошел до этого места, то можно разворачивать
//директория, в которую копируем
$sDir = dirname(__FILE__)."/client";
//удаление старой версии билда
shell_exec("rm -rf $sDir/* $sDir/.[^.]*");
//клонирование репозитория с билдом в нужную директорию
shell_exec("git clone https://login:password@git.address.domain/my-app-build.git $sDir/");
Суть технологии заключается в замене репозитория с билдом на архив. Все, что от вас требуется, это исправить содержимое файла build.bash
:
#!/bin/sh
cd /var/www/html/tilda.local/htdocs/my-app/
npm run-script build
cd build
zip -r build.zip *
curl --data-binary @build.zip https://domain.zone/__deploy/client.php?token=token
Обратите внимание, что в нашем примере мы указали формат создаваемого архива ZIP. Еще нужно немного изменить скрипт деплоя на веб-хостинге:
//записываем информацию о последнем запросе в файл
file_put_contents(dirname(__FILE__)."/".basename(__FILE__, ".php").".txt", print_r($_SERVER, true).print_r($_FILES, true));
//сверка токенов
if($_GET["token"] != "token")
exit();
//POST-данные записываем в файл (там архив)
file_put_contents(dirname(__FILE__)."/build.zip", file_get_contents('php://input'));
//директория, в которую разворачиваем
$sDir = $_SERVER["DOCUMENT_ROOT"]."/client";
//удаляем все из директории
shell_exec("rm -rf $sDir/* $sDir/.[^.]*");
//распаковываем архив в директорию
shell_exec("unzip -d $sDir/ build.zip ");
Отметим, что деплой React-приложения при использовании хука post-commit возможен без git-сервера.
Как и в случае с хостингом, нам понадобится готовый проект React, который мы и будет деплоить на виртуальную машину. Например, в локальной среде создадим новое приложение:
npx create-react-app react-deploy
Команда запускает пакет Node без загрузки на компьютер. Скрипт create-react-app
инсталлирует все необходимые зависимости и создает проект в каталоге react-deploy
. На выполнение этой процедуры уйдет несколько минут. Результат система отобразит на экране:
Success! Created react-deploy at your_file_path/react-deploy
Inside that directory, you can run several commands:
npm start
Starts the development server.
npm build
Bundles the app into static files for production.
npm test
Starts the test runner.
npm eject
Removes this tool and copies build dependencies, configuration files
and scripts into the app directory. If you do this, you can’t go back!
We suggest that you begin by typing:
cd react-deploy
npm start
Happy hacking!
После создания проекта его нужно преобразовать в производственную сборку. Поможет на в этом команда:
npm run build
Ее действие заключается в компиляции JavaScript и активов в build
каталог. В нем будут лежать скомпилированные и минимизированные версии всех файлов, входящих в проект. Этого достаточно для последующих действий.
Под наш эксперимент проще арендовать готовую виртуальную машину VPS с предустановленной операционкой Ubuntu. На нем понадобится установить веб-сервер Nginx и вручную указать, где надо хранить файлы развертываемого проекта. Сначала определим, какой каталог используется в качестве корневого «по умолчанию». Для этого подключимся к удаленному хосту по защищенному каналу SSH:
ssh username@server_ip
Там по пути /etc/nginx/sites-enabled
найдем конфигурационный файл веб-сервера и просмотрим его содержимое:
cat /etc/nginx/sites-enabled/your_domain
При отсутствии подключенного SSL-сертификата увидим примерно такой вывод:
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}
Нас интересует строка, где присутствует название текущего аккаунта – root. Именно по тому пути и будут располагаться файлы проекта после развертывания.
Наиболее безопасным способом переноса файлов проекта на виртуальную машину VPS считается команда scp. При наличии настроенного ключа SSH, она будет использовать его по умолчанию. В противном случае система предложит ввести логин и пароль. Скопируем все файлы при помощи знака *
:
scp -r ./build/* username@server_ip:/var/www/your_domain/html
Команда во время выполнения задачи выводит на экран название скопированных файлов, процент завершения операции, скорость передачи. Пример:
asset-manifest.json 100% 1092 22.0KB/s 00:00
favicon.ico 100% 3870 80.5KB/s 00:00
index.html 100% 3032 61.1KB/s 00:00
logo192.png 100% 5347 59.9KB/s 00:00
logo512.png 100% 9664 69.5KB/s 00:00
manifest.json 100% 492 10.4KB/s 00:00
robots.txt 100% 67 1.0KB/s 00:00
main.ab7136cd.chunk.css 100% 943 20.8KB/s 00:00
main.ab7136cd.chunk.css.map 100% 1490 31.2KB/s 00:00
runtime-main.1caef30b.js.map 100% 12KB 90.3KB/s 00:00
3.9fbaa076.chunk.js 100% 3561 67.2KB/s 00:00
2.82f639e7.chunk.js.map 100% 313KB 156.1KB/s 00:02
runtime-main.1caef30b.js 100% 2372 45.8KB/s 00:00
main.e8c17c7d.chunk.js.map 100% 2436 50.9KB/s 00:00
3.9fbaa076.chunk.js.map 100% 7690 146.7KB/s 00:00
2.82f639e7.chunk.js 100% 128KB 226.5KB/s 00:00
2.82f639e7.chunk.js.LICENSE.txt 100% 1043 21.6KB/s 00:00
main.e8c17c7d.chunk.js 100% 1045 21.7KB/s 00:00
logo.103b5fa1.svg 100% 2671 56.8KB/s 00:00
Наш тестовый проект состоит из статических файлов, поэтому на сервере не требуется установка и настройка какого-либо компилятора. Все будет работать за счет функционала обычного браузера. Откроем используемый и введем IP-адрес сервера или его доменное имя, если оно подключено. В результате должны увидеть результат выполнения приложения.
По итогу перечисленных выше операций мы получили функционал авторазвертывания React-проектов на заданном в настройках сайте. Опробуйте технологию на мощностях провайдера Timeweb Cloud, отдельно от своих рабочих хостов. Важно учитывать, что компиляцию мы проводим на компьютере разработчика.
Кстати, в своем официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.
Спасибо большое за такую короткую и максимально эффективную статью. Целый день провозился с деплоем на сервер приложения, пока не наткнулся на этот сайт и не сделал за 3 команды)