Deploy React SPA to Ubuntu with Nginx through Gitlab CI/CD

For applications created by create-react-app

Peter Bazov
8 min readMar 25, 2020

Цель

В данной статье описано, как настроить автоматическое развертывание React-приложения, созданного через create-reac-app, используя функционал GitLab CI/CD. Процесс будет запускаться публикацией изменений на GitLab в ветки master и staging. При публикации в ветку develop будет происходить сборка проекта без развертывания. При этом React-приложение будет скомпилировано в статические JS, HTML и CSS файлы, которые будут раздаваться с помощью HTTP-сервера Nginx. Учтено, что роутинг реализован на стороне React-приложения.

До начала работы

Инструкция предполагает, что для хранения исходного кода вы используете GitLab и владеете виртуальным сервером под управлением Ubuntu с доступом по SSH через не-root пользователя с sudo правами. Если ваш сервер не настроен, то можете воспользоваться инструкцией:

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

Если у вас еще нет React-приложения, то создайте его:

npx create-react-app APPLICATION_NAME
cd APPLICATION_NAME
yarn start

В открывшейся вкладке браузера вы должны увидеть:

Подробные инструкции здесь:

Создайте репозиторий на GitLab, свяжите его с проектом и опубликуйте изменения:

git remote add origin git@gitlab.com:user/APPLICATION_NAME.git
git push origin master

Создание Runner

Чтобы GitLab имел возможность запускать CI/CD, требуется установить программу “gitlab-runner” и зарегистрировать хотя бы один Runner. Каждый Runner, это очередь, которая может выполнять CI/CD скрипты. Если у вас уже настроен Runner, можете перейти к следующему этапу.

Установить программу “gitlab-runner” можно по инструкции:

Зарегистрировать Runner для Ubuntu можно по инструкции:

Когда регистрация попросит вас указать теги, напишите:

web,react

В качестве Runner-executor используйте docker. В Docker-image укажите:

node:12.6.1

Установка и настройка Nginx

Установите nginx и проведите первоначальную настройку по инструкции:

Доработайте файл “/etc/nginx/sites-enabled/default”. Не забудьте изменить “APPLICATION_NAME” на имя вашего React-приложения.

Данная настройка указывает HTTP-серверу отдавать файлы из папки приложения по их URL. Если файл не найден, сервер отдает файл index.html. Это позволяет:

  • Корректно отдавать статические ресурсы (JS, CSS и другие).
  • Для всех остальных URL отдавать файл index.html с React-приложением для корректного роутинга на стороне клиента.

Проверьте отредактированные файлы на предмет ошибок:

sudo nginx -t

В случае успеха вы должны увидеть сообщения:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Перезапустите Nginx командой:

sudo systemctl restart nginx

Настройка CI/DI в проекте

В корне проекта, находясь в ветке master, создайте файл .gitlab-ci.yml со следующим содержанием:

Ниже указано подробное описание всех ключей в файле.

image — Docker image, в котором будет происходить компиляция проекта и его развертывание. Если его не указать, то будет использоваться image, который указан стандартным для Runner-а.

stages — определяет список и порядок этапов. Действия, выполняемые на каждом из этапов, указаны ниже в файле. Этапам можно давать произвольные имена. Этапы выполняются последовательно друг за другом и видны на вкладке CI/CD в проекте GitLab.

build_test, build_staging и build_production — определяют этап сборки проекта для test, staging и production окружений.

deploy_staging, deploy_production — определяют этап развертывания проекта для staging и production окружений.

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

*.only.refs — связывает экземпляр этапа с конкретной веткой репозитория. Например, при публикации изменений в ветку staging последовательно будут запущены этапы build_staging и deploy_staging.

*.environment — указывает на окружение, которое определяет значения переменных окружения на момент выполнения скрипта. Их настройка описана далее в инструкции.

.builds — определяет общую для всех окружений часть этапа сборки. .build.tags — указывает на Runner, в котором нужно запускать скрипт. .build.artifacts — указывает на папки и файлы, которые должны быть перенаправлены в следующий этап. .builds.script — включает в себе команды для сборки боевой версии проекта. .builds.before_script — определяет подготовительные действия для сборки:

  • Команда unset CI выключает строгий режим сборки проекта. При включенном режиме Warning-и приравниваются к ошибкам. Если в вашем проекте нет Warning-ов при сборке, можете убрать эту строку.
  • Далее идет заполнение файла .env значениями переменных окружения, которые необходимы для сборки. Если в вашем проекте нет переменных окружения, можете не заполнять .env файл.

.deploys — определяет общую для всех окружений часть этапа развертывания. .deploys.tags — указывает на Runner, в котором нужно запускать скрипт. .deploys.only.variables — указывает скрипту начать выполнение только в том случае, если перечисленные переменные окружения заполнены. .deploys.before_script — настраивает возможность подключиться к серверу по SSH. .deploys.script — подключается к серверу по SSH и копирует проект в публичную папку Nginx. На сервере хранится 5 последних версий приложения, актуальная указывается через символическую ссылку current.

Подробнее про формат файла “.gitlab-ci.yml” можно прочитать здесь:

Запуск CI/CD

Сделайте commit и отправьте изменения в ветку master. В проекте на GitLab-е зайдите в пункт меню CI/CD -> Pipelines. Вы должны увидеть, что GitLab начал выполнение скрипта.

Нажмите на статус running. Вы перейдете к подробному виду просмотра этапов. Не удивляйтесь, что здесь будет только этап build_production. Этап deploy_production не был запланирован, так как не заданы необходимые переменные окружения:

При нажатии на этап откроется страница с логом выполнения этапа. Дождитесь окончания сборки проекта. Вы увидите следующий лог:

После этого выполнение скрипта будет помечено статусом passed:

Переменные окружения

Файл “.gitlab-ci.yml”, указанный в инструкции, не зависит от конкретного проекта и настраивается через переменные окружения в GitLab. Откройте ваш проект и зайдите в пункт меню Settings -> CI/CD. Раскройте раздел Variables:

Вы увидите таблицу со следующими колонками:

  • Type — тип переменной. Доступные значения — переменная и файл.
  • Key — название, под которым переменная будет доступна в скрипте “.gitlab-ci.yml”.
  • Value — значение переменной.
  • State — защищена ли переменная. Если да, то её значение будет доступно только при выполнении скрипта, который был запущен из protected ветки или protected тега.
  • Masked — скрыто ли значение переменной. Если да, то оно не будет отображаться в логах о выполнении скрипта.
  • Scope — область видимости переменной. С помощью этого поля вы можете заводить разные значения одной и той же переменной для разных окружений.

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

  • APP_PATH — путь к приложению в системе. Папка для него была заранее подготовлена при настройке Nginx. Значение одинаковое для всех окружений: “/var/www/apps/APPLICATION_NAME”.
  • DEPLOY_USER — имя пользователя, под которым будет происходить развертывание приложения.
  • SERVER_ADDRESS — IP адрес сервера, на котором приложение должно быть развернуто.
  • SSH_PORT — порт SSH для подключения к серверу.
  • SSH_PRIVATE_KEY — приватный ключ SSH для подключения к серверу. Ниже в инструкции описано, каким образом получить его значение.

У интерфейса GitLab CI/CD нет возможности интерактивного ввода пароля для подключения по SSH, поэтому подключение будет происходить с помощью RSA ключа. Ключ необходимо создать на локальной машине, после чего приватную часть скопировать в переменную окружения на GitLab. Публичную часть нужно добавить на сервере в список разрешенных. Сделать это вы можете по следующей инструкции в разделе “Настройка авторизации по открытому ключу”:

В итоге вы должны получить похожую картину, только с вашими настоящими данными:

Создайте ветку staging из ветки master, опубликуйте изменения на GitLab и понаблюдайте за процессом выполнения скрипта CI/CD.

На этот раз в списке этапов их будет два:

После успешного выполнения вбейте в строку браузера ссылку на ваш сервер. Должно отобразиться React приложение.

Итог

Автоматическое разворачивание React приложения настроено.

При публикации изменений в ветку develop происходит сборка проекта. При публикации изменений в ветки staging и master происходит сборка проекта и его развертывание на staging и production серверах соответственно.

Источники

Создание нового React-приложения через “create-react-app”:

Развертывание Reac-приложения, созданного через “create-react-app”:

Формат файла “.gitlab-ci.yml”:

Работа с GitLab Runner:

Подключение по SSH из CI/CD скрипта:

Сборка проекта и копирование по SCP:

--

--