В статье мы рассмотрим, как развернуть в облаке приложение на 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 

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

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

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

Для этого предварительно зарегистрируемся по ссылке. Стартового баланса хватит на эксперименты и первые недели работы проекта.

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

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

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

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

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

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

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

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

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

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

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

./mvnw package

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

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

Важно: Файл 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.

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

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

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

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

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

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

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

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

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

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

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

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

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

В терминале:

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

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

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

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

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

Подключаем 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.

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

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

  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. Добавляем удаленный репозиторий проекта 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 работает.

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

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

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

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

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

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

  • Нажимаем Save.

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

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

В проекте нашего приложения сохраняем переменные, которые определили в 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. Отправим те же запросы, что мы отправляли ранее и проверим изменения в БД.

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

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

Подключим Flyway

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

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

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

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

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

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

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

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

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

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

git add .
git commit -m "flyway"
git push amvera master

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

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

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

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

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

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

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

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

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

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

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

git add .
git commit -m "test containers"
git push amvera master

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

Итог

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

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

Комментарии (8)


  1. Data4
    06.12.2023 10:47
    +1

    В статье описано, как задеплоить, используя GitOps. Не увидел, что делать, если нужно залить просто на VPS хостинг?


    1. kirillkosolapov
      06.12.2023 10:47

      Там совсем другая механика. Надо nginx настраивать и т.д.. Хотя и свободы действий больше. Как вариант, если есть ВМ, можно воспользоваться одним из инструментов для CI/CD для реализации похожей механики доставки кода.


    1. saboteur_kiev
      06.12.2023 10:47
      +2

      тут просто реклама облака Amvera, а про гит они пошутили и вообще недосказали что это их функционал.


  1. Anzorik_228
    06.12.2023 10:47

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


    1. saboteur_kiev
      06.12.2023 10:47
      +2

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


      1. Anzorik_228
        06.12.2023 10:47
        +1

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

        • Автор исправил ошибку

        • Автор понял как писать лучше в будущем, чтобы аудитории статьи заходили лучше

        • И чтобы другие пользователи могли посмотреть на комментарий голосующего, вдруг он не прав и сам ошибся по незнанию материала и его неверного восприятия


        1. saboteur_kiev
          06.12.2023 10:47

          Вы автор? Или что за вопросы?

          Если бы я ставил оценку, я бы сразу сказал, что название статьи совершенно не соответствует смыслу, ибо никакого отношения к деплою приложения через пуш в гит тут нет. Тут есть пуш в CI/CD систему на базе облачного сервиса.
          Через гит это через гит-хуки.

          Вон в первом комментарии тоже самое пишут


      1. Anzorik_228
        06.12.2023 10:47
        +1

        Или есть ещё "другое". Так что другое?) Не понравилось из-за самодурства? Так лучше уже так и написать. Степень ответственности автора может быть высока и он будет ходить и думать, в чём же и в каком месте я мог ошибиться