Всем привет! Иногда бывает так, что учиться очень сложно и мотивацию надо поднять, а дженерики и лямбда выражения совсем высосали силы. Поэтому я, пару дней назад, залипая в мобильную игру, внезапно поймал себя на мысли, что могу упростить себе и еще нескольким сотням человек жизнь. Поэтому было принято решение сделать свое приложение
Предыстория. Пару месяцев назад я наткнулся на совершенно бессмысленную мобилку, в которой ты, как игрок, бьешь дерево, получаешь предметы, которые надеваешь на героя, поднимаешь уровень и тратишь на это персики (валюта). Но игра настолько же бессмысленная, насколько и занимательная (да и я сейчас описываю не все аспекты игры). Так, играя день за днем по часику в день, я ловил себя на мысли, что хочется спрогнозировать, сколько времени я потрачу на lvlup и как быстро «оденусь» в крутые доспехи.

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

Погуглив и покурив бамбук, я понял что надо подключать джавовую библиотеку Swing. Дальше часик-два в документации и я уже пишу следующее:

Дальше берем значения из полей, проверяем их на ошибки и делаем вычисления.

Не забываем обрабатывать ошибки, 1я проектная работа научила многому)

Запускаем все это и вуа-ля, у нас целое десктопное приложение, в котором можно считать и оно даже работает.

Но и этого мне стало мало, потому что большинство пользователей этой игры не буду запускать exe-шник на компе и считать персики. Нужно было удобное решение, удобное для всех пользователей мобилки. Поэтому было решено делать веб-приложение, используя весь накопленный опыт.
Опять гугл, опять бамбук и вот найдено решение. Spring. Да да, не удивляйтесь. Поэтому заходим на spring initializr, настраиваем то, что нам нужно(Spring web и шаблонизатор Thymeleaf) и жмем Generate.

Дальше ютуб, гугл, документация спринга и stackoverflow, чтобы разобраться как и что накрутить здесь. В итоге, получилась такая логика - на сервере мы делаем вычисления, работаем с двумя запросами: первый get, при загрузке главной страницы и post /calculate для расчетов, на фронте у нас html и css, с шаблонизатором, который может передавать данные из полей.
Добавляем в нашу модель атрибуты для get-запроса.

И считаем в post /calculate.

Дальше я настроил шаблон (и вспомнил html), чтобы все значения, который пользователь вводит передавались на бэк, проводились расчеты и отдавался результат.

В итоге имеем такой результат

Здорово, круто, я даже горжусь собой, но есть одно НО. Только я могу пользоваться этим, потому что это развернуто локально, у меня на компе. Для этого все это надо развернуть на сервере. А как развернуть jar-ник на сервере? Правильно, докер. И здесь я совсем профан, я не знал ни как, ни почему, ни зачем это все нужно. Так что дальше пол дня гугления, настройки, документации и видео, чтобы разобраться. Я опущу многие детали, пройдусь по основным. Я создал Dockerfile в своем проекте, установил Docker Desktop и запустил контейнер.

Dockerfile

Все работает, контейнер запускается, можно зайти в приложение. Теперь надо запустить это на сервере(благо у моего отца уже есть настроенный Ubuntu с nginx на борте) и настроить gitlab, чтобы при пуше в main ветку, происходила автоматическая сборка и деплой.
Предварительно, настроив nginx для моего проекта, указав все порты, хосты и прочие детали, я преступил к настройке CI/CD

Тут я тоже опущу много нюансов, как боролся с тем, чтобы jar предварительно собирался, обратным прокси и т.д. Покажу как реализован yaml файл в проекте.

В нем я указал что мы — деплоим все это дело, собираем jar файл, билдим докер, удаляя образ, если он уже есть и если у нас есть запущенный — останавливаем его. Ну и все это для ветки main.
Все работает как надо и при каждом пуше, я наблюдаю запуск job'ов

И веб приложение теперь доступно по адресу

Подытожу: с такой пустяковой идеи как сделать базовый, простенький калькулятор, я столкнулся с множеством фреймворков, нюансов, идей и вариантов их реализаций. Набрался немного опыта в Java, Spring, Docker, Gitlab CI/CD, поработал с гитом и еще куча всего. Хочу сказать - не бойтесь делать что то, даже если не получается и беритесь за такие микро-пэт проекты, чтобы набраться опыта :-)
И да, я не претендую на то, что я сделал все правильно и не допустил ошибок, я лишь учусь как и мы все.
Автор: monarchy_r