Деплой React проекта на web-хостинг без Node.js

13.03.2021 / devops
Реализуем деплой React проекта на целевой сайт, с компиляцией на локальной машине и последующей заливкой билда на сайт

Сделал web-приложение с использованием React. На локальной машине все хорошо: красиво и правильно работает с backend. Теперь надо как-то заливать на удаленный сервер. В моем распоряжении есть только web-хостинг ... будем придумывать.

Сейчас (10.2022) я использую CI/CD конвейер для задач поставки ПО при помощи современных средств (Gitlab & Docker Swarm), но на момент написания статьи были другие условия.

В чем проблема?

Как происходит работа с React: разработчик пишет код на js/ts/jsx/tsx/x, а затем этот код транспилируется в конкретную версию JavaScript:

React workflow

То есть прежде чем быть исполненным браузером, код проекта должен пройти не побоюсь этого слова компиляцию! А значит нужен компилятор.

Решение

git hooks

Внезпно обнаруживаем git хуки и читаем вывод команды терминала git help hooks. Стоит заметить что:

git хуки бывают клиентскими (выполняются на машине разработчика) и серверными (выполняются на сервере).

Реализация клиентских хуков расположена по адресу .git/hooks относительно репозитория. Здесь представлены не все возможные хуки, а лишь часть. Чтобы пример хука заработал достаточно из имени файла удалить точку с расширением .sample.

Судя по git help hooks наиболе подходящим вариантом для реагирования на обновление репозитория, а точнее на предстоящее обновление, является хук pre-push, который срабатывает непосредственно перед отправкой данных на удаленный репозиторий.

Серверные хуки в контексте gitlab называются WebHooks. Кратко: при поступлении какого-либо события в проект (например обновление репозитория), может быть отправлен http запрос по любому указанному в настройках адресу. Это дает возможность отслеживать определенные события с проектом и реагировать на них.

При помощи git hook мы можем:

При отправке изменений в репозиторий запустить скрипт, который скомпилирует проект и отправит его на сервер.

Подготовка

Создадим файл build.bash (в любом месте, но я создал его прямо в репозитории с исходниками) и поместим туда следующее:

#!/bin/sh

cd /home/byurrer/my-project/
npm run-script build

# дальше будет код отправки скомпилированного кода

Здесь осуществляется переход в директорию React проекта и его компиляция. Способы отправки скомпилированных данных рассмотрим позже.

Перейдем в директорию с хуками в репозитории .git/hooks и создадим файл pre-push со следующим содержимым:

#!/bin/sh

nohup /home/byurrer/my-project/build.bash &

nohup в начале и & в конце команды нужны чтобы скрыть вывод терминала

Оба файла должны быть исполняемым:

chmod 775 /home/byurrer/my-project/build.bash
chmod 775 /home/byurrer/my-project/.git/hooks/pre-push

Деплой на хостинг по ssh

Хостинг на reg.ru, самый дешевый, но даже здесь можно зайти на сервер по ssh, а это значит что мы можем использовать rsync:

$ rsync --delete -avz -e "ssh -i ~/.ssh/key" --progress /home/byurrer/my-project/front/build/ root@ip:/var/www/htdocs/

В этом скрипте rsync войдет на сервер по ssh ключу, скопирует все файлы из локальной директории в директорию на удаленном сервере, удалив при этом все файлы на удаленном сервере, которых нет на локальном (в указанной директории).

Можно скопировать этот код в конец нашего build.bash и наслаждаться автоматическим деплоем :)

Деплой на хостинг по ftp

Но предположим что мы используем консервативный LAMP web-хостинг, тогда можно заливать по FTP при помощи lftp аналогично rsync. Почитать можно здесь, а нормальную документацию удалось найти только так:

$ man lftp

В итоге срипт будет выглядеть так:

# логинимся на ftp сервере
$ lftp login:password@ftp-server
# переход в дирекорию на удаленном сервере, куда будет происходить заливка
$ cd htdocs
# переход в директорию на локальном сервере, откуда будет происходить заливка
$ lcd /home/byurrer/my-project/front/build/
# команда клонирования из локального на удаленный
$ mirror --reverse --delete --verbose --allow-chown --parallel=2

Аналогично: можно скопировать этот код в конец нашего build.bash и наслаждаться.

Итог

В итоге имеем автоматическое развертывание React проекта на сайт, размещенный на web-хостинге. В данном случае компиляция осуществляется на машине разработчика, а деплой осуществляется автоматически при помощи git hooks и rsync/lftp.