Деплой приложения на Java. Хостим проект через push в Git

В статье мы рассмотрим, как развернуть в облаке приложение на Java, на примере Spring Boot приложения с встраиваемой базой данных H2. А именно, мы попробуем развернуть приложение с простым REST API, сборкой Maven и тремя эндпоинтами, позволяющими добавить продукт, получить список всех продуктов и узнать общую стоимость всех продуктов. 

Код приложения из примера можно скачать по ссылке.

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

Будут использоваться:

— Git

— Intellij Idea Ultimate Edition (подойдет любая другая IDE);

— Spring Boot 2.7.17 (так как крайняя поддерживаемая версия Java 11)

— Postman для тестирования работы приложения

— Flyway

— Tests Containers

Чтобы создать проект, воспользуемся сервисом https://start.spring.io (можно воспользоваться, встроенной в Itellij Idea Ultimate Edition, Spring Initializr), нам потребуются:

— Spring Web

— H2 Database

— Spring Data JPA 

8cf050ed9adbf92eda110cb0a69291b9.png

Нажимаем GENERATE и скачиваем архив нашего проекта. Разархивируем приложение и откроем его в IDE.

Spring initializr с недавнего времени не дает возможности выбрать Spring Boot 2.7 и Java 11,   поэтому нужно определить версии вручную в pom.xml.

5150faa73dbdb5af86d595fd6c33d7b0.png

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

Для этого предварительно зарегистрируемся по ссылке. Стартового баланса хватит на эксперименты и первые недели работы проекта. При наличии иностранной карты, вы можете воспользоваться любым другим сервисом, поддерживающим развертывание через push в Git (например, Heroku).

Находясь на главной странице, нажимаем «Создать».

Вводим название проекта, например, amvera-java, и выбираем тариф «Начальный».

bc966291e7833d7d935164735aa93d70.png

Нажимаем «Далее» и переходим к загрузке данных проекта.

Существует два варианта загрузить проект: непосредственно командами git или через интерфейс сервиса. Мы воспользуемся Git, так-как это упрощает доставку обновлений. Но можно использовать и загрузку/удаление файлов через личный кабинет, тем более, можно комбинировать способы.

12c31368c4e6561e1080c0ce1a553a0b.png

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

1. Вызовем терминал в IDE, где открыто приложение, или откроем папку проекта в терминале

2. Инициализируем локальный гит репозиторий командой

git init

3. Добавим удаленный репозиторий нашего проекта (url вашего репозитория будет отличаться. Во избежание синтаксических ошибок скопируйте ссылку на втором шаге создания проекта)

git remote add amvera https://git.amvera.ru/имя_пользователя/имя_проекта

4. Добавим файлы и сделаем первый коммит

git add .

git commit -m ‘init’

5. Запушим наш код в репозиторий проекта

git push amvera master
  1. Сервис начнет сборку проекта, но она закончится ошибкой, потому что отсутствует конфигурационный файл amvera.yml (или Dockerfile), который мы создадим на следующем этапе.

Нажимаем «Далее» и наблюдаем интерфейс создания конфигурационного файла.

Для нашего проекта на данном этапе потребуется такая настройка.

0c1211c5433e8cf53af483e693596ce3.png

jarName можно найти следующим способом

Нужно собрать проект:

./mvnw package

Будет создана папка /target, в корне которой будет лежать нужный jar файл, его имя и нужно вставить.

Нажимаем «Завершить». В удаленном репозитории проекта создастся файл amvera.yml. Можем наблюдать это во вкладке «Репозиторий» нашего проекта.

c7da28c1120319d1694472653604275a.png

Важно: Файл amvera.yml появился в удаленном репозитории, но локально его у нас пока нет. Давайте добавим, чтобы при будущих обновлениях нашего приложения Git не выдавал ошибку.

Перейдите в терминал IDE

Введите:

git pull amvera master

У вас загрузятся и закоммитятся файлы с удаленного репозитория (никаких конфликтов на данном этапе возникнуть не должно), а именно, amvera.yml

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

Альтернативный способ добавления конфигурационного файла: воспользуйтесь генератором по ссылке. Скачайте файл и добавьте его в корень репозитория перед первым коммитом в Git.

Интерфейс создания файла

Интерфейс создания файла

В данном случае воспроизведите шаги:

1. Вызовем терминал в IDE, где открыто приложение, или откроем папку проекта в терминале

2. Инициализируем локальный гит репозиторий командой

git init

3. Добавим удаленный репозиторий нашего проекта (url вашего репозитория будет отличаться. Во избежание синтаксических ошибок скопируйте ссылку на втором шаге создания проекта).

git remote add amvera https://git.amvera.ru/имя пользователя/название проекта

4. Добавим файлы и сделаем первый коммит

git add .

git commit -m ‘init’

5. Сделаем push в репозиторий проекта

git push amvera master

6. Должна начаться сборка проекта. Если появится надпись «Сборка завершилась ошибкой», нажмите на иконку «Инструменты», чтобы запустить процесс сборки заново.

За процессом сборки и запуска приложения можно наблюдать во вкладках «Лог сборки» и «Лог приложения» соответственно. Чтобы загрузить логи, нужно нажать кнопку в виде часов. Логи могут приходить с задержкой, время логов в UTC.

После успешной сборки должна появиться надпись «Приложение запущено».

Проверим работу приложения

Откроем Postman

Ссылка приложения находится во вкладке «Инфо» страницы проекта.

3b90b4b1599b68fa2d3f6a4eb443fac2.pngПоздравляем, приложение работает!

Поздравляем, приложение работает!

Сборка с помощью Dockerfile

Dockerfile является альтернативным способом задания конфигурации для сборки приложения и позволяет запустить код с произвольным окружением (на любых языках и с использованием любых фреймворков).

Создаем Dockerfile для нашего приложения (пример с комментариями в репозитории).

Наше Spring Boot приложение слушает порт 8080, но в Amvera по дефолту контейнер должен слушать порт 80. Изменим это поведение, добавив amvera.yml в корень нашего приложения (пример и комментарии в репозитории).

Альтернативный вариант:

Чтобы не добавлять конфигурационный файл amvera.yml, нам потребуется изменить порт приложения в application.yml на 80.

b9509b5b47fbf497c25e296d23776f3e.png

Сохраняем H2 в /data

Сейчас наше приложение использует H2 Database, и при каждом новом пуше изменений приложения или перезапуска контейнера наши данные будут теряться. Чтобы этого избежать, нужно сообщить H2 сохранять файл с данными в папке /data

 Для этого требуется изменить одну строчку в application.yml.

74d1e9740d22a57216c0e21cb6dbe1b2.png

Так как мы добавили путь бд до папки, которой не существует локально, наши тесты не будут выполняться и сборка проекта будет завершаться ошибкой. Поэтому в папке /test добавим новую папку /resources и создадим в ней application.yml.

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

f6a55b2355655d4b251ea060a09d5fc9.png

В терминале:

git add .
git commit -m ‘Data saved in /data’
git push amvera master

Наш проект начнет пересобираться автоматически (возможно не сразу). Ждем.

После сборки в разделе «Репозиторий» папка Data мы увидим файл spring-boot-h2-db.mv.db.

35437c1b910b8e1763603d66c8678850.png

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

Ссылка на репозиторий примера.

Подключаем PostgreSQL

Использование H2 для небольших pet проектов допустимо. Но для более серьезных проектов его использование нежелательно (и функционала может не хватить), поэтому подключим PostgreSQL.

Для подключения PostgreSQL потребуется создать отдельный проект с СУБД. Развертывание подробно описано в документации. Там же описан процесс развертывания pgAdmin: для него также потребуется создать отдельный проект, но его можно запускать только во время использования в целях экономии. 

  1. Создаем amvera.yml

meta:
  environment: db
  toolchain:
    name: postgresql
    version: 13
run:
  args: listen_addresses=0.0.0.0
  1. Создаем новый проект postgres.

    Для небольшой нагрузки будет достаточно пробного тарифа

    9c87193776adc3dc6f3b9137dc6cbdc3.png

    Важно: на данном этапе пропустите шаги загрузки файлов и конфигурации!

  2. Добавим переменную POSTGRES_USER и секрет POSTGRES_PASSWORD. Значения переменных понадобятся для подключения к БД.

  3. Добавляем удаленный репозиторий проекта postgres и пушим в него amvera.yml (ссылка удаленного репозитория вашего проекта будет отличаться).

git remote add amvera https://git.amvera.ru/kimutir/postgres
git push amvera master

Либо вы можете загрузить yaml файл с шага 1 через интерфейс и нажать «собрать».

Разворачиваем pgAdmin

  1. Создадим amvera.yml

meta:
  environment: db
  toolchain:
    name: pgadmin
    version: 7.1

2. Создадим новый проект pgadmin. Тариф нужно выбрать не менее «Начального», иначе проект не запустится из-за недостатка ОЗУ (потребляет около 200 мб.).

  1. Добавим переменную PGADMIN_DEFAUL_EMAIL и секрет PGADMIN_DEFAUL_PASSWORD для входа в pgAdmin

  2.  Добавляем удаленный репозиторий проекта postgres и пушим в него amvera.yml (ссылка удаленного репозитория вашего проекта будет отличаться).

  3. Добавим переменную PGADMIN_DEFAUL_EMAIL и секрет PGADMIN_DEFAUL_PASSWORD для входа в pgAdmin.

  4. Добавляем удаленный репозиторий проекта postgres и пушим в него amvera.yml (ссылка удаленного репозитория вашего проекта будет отличаться).

git remote add amvera https://git.amvera.ru/имя пользователя/название проекта
git push amvera master

Либо вы можете загрузить yaml файл с шага 1 через интерфейс и нажать «собрать».

* если вы захотите изменить значение переменной, то после изменения перезапустите проект (иконка обновления, справа от иконки инструментов).

Подробнее про развертывание БД.

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

Переходим по ссылке приложения pgAdmin, она находится в разделе «Инфо» проекта pgAdmin

В нашем случае https://pgadmin-kimutir.amvera.io (у вас ссылка будет отличаться).

Вводим почту и пароль, которые вы использовали при создании переменных (PGADMIN_DEFAUL_EMAIL и PGADMIN_DEFAUL_PASSWORD), если зашли, то pgAdmin работает.

Подключимся с бд:

6f26f202bb0a1f2bce13cb0252f534e6.png

— введем любое имя сервера

— переходим на вкладку Connections

467213e4ceabf946b6d27ba6b9e8c083.png

  • Вводим доменное имя приложения с Postgres (находится в вкладке «Инфо» на странице проекта postgres)

  • Порт по умолчанию 5432 (мы его не меняли)

  • Username и Password, как в переменных POSTGRES_USER и POSTGRES_PASSWORD

  • Нажимаем Save.

Для подключения нашего приложения к БД потребуется изменить application.yml и добавить зависимость postgres в pom.xml. Для тестирования пока оставим H2, только изменим sope на test.

3e6b819b0826c9d478d8ffe887431d66.png

Хранить url, username и password в репозитории небезопасно, поэтому будем поместим эти данные в переменных окружения. Также изменим диалект и драйвер для работы с PostgreSQL.

b0e8645a1cbcc24149314d6f3ab83028.png

В проекте нашего приложения сохраняем переменные, которые определили в application.yml

DB_USER — такое же значение, как и в POSTGRES_USER

DB_PASSWORD — такое же значение, как и в POSTGRES_PASSWORD

DB_URL — jdbc: postgresql://amvera-kimutir-run-postgres:5432/postgres

Сохраняем и пушим изменения в удаленный репозиторий нашего проекта amvera-java

git add .
git commit -m ‘postgresql’
git push amvera master

Ждем, когда закончится сборка и проверяем в Postman. Отправим те же запросы, что мы отправляли ранее и проверим изменения в БД.

6f7179257cb9f6a8eeec69a31ab251e8.png

Продукт Apple успешно сохранился в БД.

Код из примера в репозитории.

Подключим Flyway

Ни одно современное приложение не обходится без миграции баз данных, наше не будет исключением. Подключим Flyway.

Добавим зависимость в pom.xml

4ae0a143b17f9535fe67c4d5565918e4.png

Активируем Flyway в application.yml и поставим ddl-auto: none

1acfa89032c82130e4449fc6e22dfbcc.png

Добавим файл миграции. Для этого в папке /resources создадим /db/migration/V1__create_cart_table.sql

9152135a5a82a0a156ad1b38351a418f.png

Удалим ранее сгенерированную таблицу в БД через pgAdmin

2d129bc7a249a897573489ab3c61a599.png

Для того, чтобы Flyway знал с какой БД работать, ему нужно указать url, username и password. Но переменные DB_URL, BD_USER и DB_PASSWORD не подойдут, хотя и содержат правильные значения.

Flyway нужно предоставить определенные переменные — FLYWAY_PASSWORD, FLYWAY_URL, FLYWAY_USER.

Запишем переменные в проекте amvera-java.

6817ea91e473f1f1ad7a26eb12f40e2f.png

На данный момент наши тесты будут падать, потому что Flyway ждет значения переменных. Чтобы это исправить, изменим /test/resoursec/application.yml

75e2d5d28f7bdf1689eff0b40993b2d7.png

Сохраняем и пушим изменения

git add .
git commit -m ‘flyway’
git push amvera master

В логах приложения мы увидим, что миграция успешно выполнена.

b72f4ad8a7ce143dab1d5d7c2251fb96.png

А в pgAdmin, что таблица создалась.

Проверим, как и в прошлые разы, через Postman работоспособность приложения.

Код из примера по ссылке.

Для тестирования все еще используется H2, хотя приложение использует Postgres. Исправим это.

Будем использовать тест контейнеры. Удалим H2 из pom.xml и добавим зависимости для test containers.

b9696b9e4213ca4435ae46de0a4a6a56.png

Удалим application.yml в /test/resources

Особенностью тест контейнеров является скачивание образа и развертывания контейнера, в нашем случае Postgres, поэтому для локального тестирования мы должны открыть Docker Desktop. А при деплое запретить тесты, потому что Amvera не позволяет скачивать образы.

Отключаем тесты в amvera.yml.

59a61c2c2dff67ff3f681f617dee0af6.png

Добавим еще одну миграцию для проверки

a769c7b1692a0bf794765542a61b2baf.png

Сохраняем и пушим изменения

git add .
git commit -m ‘test containers’
git push amvera master

Код из примера по ссылке.

Итог:

Мы осуществили деплой Spring Boot приложения с встраиваемой базой данных H2 как с использованием конфигурационного YAML-файла, так и с использованием Dockerfile. Подключили PostgreSQL и выполнили миграции. Код из примеров собран в репозитории по ссылке.

Автор инструкции: Тимур Ким

© Habrahabr.ru