Деплой приложения на 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
Нажимаем 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: для него также потребуется создать отдельный проект, но его можно запускать только во время использования в целях экономии.
Создаем amvera.yml
meta:
environment: db
toolchain:
name: postgresql
version: 13
run:
args: listen_addresses=0.0.0.0
Создаем новый проект postgres.
Для небольшой нагрузки будет достаточно пробного тарифа
Важно: на данном этапе пропустите шаги загрузки файлов и конфигурации!
Добавим переменную POSTGRES_USER и секрет POSTGRES_PASSWORD. Значения переменных понадобятся для подключения к БД.
Добавляем удаленный репозиторий проекта 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 мб.).
Добавим переменную PGADMIN_DEFAUL_EMAIL и секрет PGADMIN_DEFAUL_PASSWORD для входа в pgAdmin
Добавляем удаленный репозиторий проекта postgres и пушим в него amvera.yml (ссылка удаленного репозитория вашего проекта будет отличаться).
Добавляем удаленный репозиторий проекта 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 и выполнили миграции. Код из примеров собран в репозитории по ссылке.
Автор инструкции: Тимур Ким