Spring Boot-приложение запускается одной кнопкой в IDE: класс с @SpringBootApplication, встроенный Tomcat и строка «Started AppApplication in 2.4 seconds» в логе. Показать его кому-то по ссылке — уже другая задача: нужен сервер с JDK нужной версии, собранный jar, процесс, который не умирает после закрытия терминала, прокси и сертификат. Обычно именно на этом шаге пет-проект и замирает. Рассказываем, как выложить Spring Boot без VPS и на что смотреть именно в Java-проекте: порт, память JVM и health-check.
Почему деплой Spring Boot упирается в сервер
Локально всё выглядит бесплатным, потому что IDE берёт четыре вещи на себя. При выносе в интернет каждая превращается в отдельную задачу:
JDK нужной версии. Проект написан на Java 21 — и на сервере должна оказаться ровно 21. Поставить «какую-нибудь» не выйдет: Maven упадёт с жалобой на неподдерживаемый release.
Сборка. jar нужно где-то собрать, а зависимости Maven тянет из сети — иногда пачками и небыстро.
Запуск в фоне. java -jar app.jar из терминала умирает вместе с сессией. Нужен systemd-юнит, логи, автозапуск после падения и перезагрузки.
Прокси и HTTPS. Tomcat отдаёт HTTP на порт 8080, а браузер хочет https:// на 443. Значит, nginx, сертификат Let's Encrypt и напоминание о его обновлении.
Каждый пункт по отдельности не страшен. Но берутся они вместе, и вечер на них уходит раньше, чем на сам код.
Что платформа берёт на себя
На Dockbox вы загружаете исходники — не jar, а проект с pom.xml или build.gradle. Дальше платформа:
- определяет Java по файлу сборки и ставит нужную версию;
- собирает проект в Docker-контейнер: тот же Maven или Gradle, те же зависимости;
- выдаёт публичный HTTPS-адрес — сертификат и прокси не ваша забота;
- перезапускает контейнер при сбое и хранит логи в панели.
Ни JDK, ни nginx, ни systemd, ни certbot настраивать не нужно — и VPS арендовать тоже. Контейнеры работают постоянно: нет ни лимита часов, ни засыпания по неактивности, ссылка отвечает в момент открытия, а не после «прогрева».
Сборка: pom.xml или build.gradle в корне
Файл сборки — в корне проекта. Именно по нему определяется, что это Java и какой инструмент использовать. Maven или Gradle — поддерживаются оба, обёртки mvnw и gradlew можно оставить, они не мешают.
Версию Java укажите явно. В pom.xml это свойство java.version, в build.gradle — sourceCompatibility. Тогда сборка идёт на нужной версии, а не на той, что оказалась ближайшей, и не падает с ошибкой про unsupported release.
Каталоги сборки — не в архив. target/, build/ и локальный кэш зависимостей только раздувают загрузку: платформа соберёт их заново. Локально происходит то же самое командой:
./mvnw clean package -DskipTests
Порт: только из переменной PORT
Самая частая причина ситуации «сборка прошла, а ссылка пустая» — жёстко прописанный порт. Платформа сообщает приложению порт через переменную окружения PORT, и слушать нужно именно её, а не 8080 из кода. В Spring Boot это одна строка в application.properties:
server.port=${PORT:8080}
server.address=0.0.0.0
Если порт зашит в код или прописан константой server.port=8080, контейнер стучится не туда, и снаружи сайт не открывается. То же с адресом: приложение должно слушать все интерфейсы, а не только localhost, иначе запрос до него просто не доходит.
Память JVM: главное отличие Java от скриптов
У Python-скрипта память растёт по мере надобности, а JVM забирает её на старте и держит резерв. На маленьком тарифе это заметно: попросите слишком много — получите OutOfMemoryError или убитый контейнер.
Задайте потолок кучи. Флаг -XX:MaxRAMPercentage=75 заставляет JVM взять не больше 75% доступной памяти, и размер тарифа можно менять без правки команд:
JAVA_TOOL_OPTIONS=-XX:MaxRAMPercentage=75
Или явно, в команде запуска:
java -Xms128m -Xmx512m -jar app.jar
Подберите тариф под приложение. На Starter — 990 ₽/мес, первый месяц бесплатно: 1 vCPU, 2 ГБ RAM и 20 ГБ SSD. Этого хватает типичному Spring Boot-сервису с базой. Если приложение тяжёлое или проектов несколько — Pro (2 490 ₽/мес): 2 vCPU, 4 ГБ RAM, до 5 проектов. Дальше — Team (4 990 ₽/мес). Цены в рублях, отдельных счетов за сборки или трафик нет.
Health-check и свой Dockerfile
Платформа поднимает упавший процесс сама, но полезно дать ей признак «приложение живое». Для этого в проект добавляют Spring Boot Actuator — эндпоинт /actuator/health. Если хочется совсем просто, годится обычный контроллер:
@RestController
public class HealthController {
@GetMapping("/health")
public String health() {
return "ok";
}
}
Аккуратный health-check нужен не для красоты: пока приложение поднимается, JVM греет классы, и внешний монитор не должен принимать это за падение.
Свой Dockerfile тоже можно принести — например, когда нужен конкретный образ. EXPOSE в нём ничего не фиксирует, порт всё равно берётся из PORT:
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
ENTRYPOINT ["java","-XX:MaxRAMPercentage=75","-jar","app.jar"]
Загрузите код и дождитесь первой сборки
Подключите Git-репозиторий или загрузите архив — терминал не нужен. Первая сборка Java заметно длиннее, чем у скриптовых языков: Maven или Gradle скачивают все зависимости с нуля, а в Spring Boot их много. Это разовая плата, статус и логи видны в панели в реальном времени.
Когда сборка закончится, откроется публичный HTTPS-адрес — его можно отправлять кому угодно. Если страница не отвечает, начните с логов: там написано, стартовал ли Spring Boot и на каком порту слушает. Обновление кода — загрузка новой версии или push в Git, ссылка при этом не меняется. Попробовать можно на Dockbox.
Частые вопросы
Нужно ли собирать jar перед загрузкой?
Нет. Загружайте исходники вместе с pom.xml или build.gradle — проект соберётся на платформе. Готовый jar, каталоги target/ и build/ и локальный кэш зависимостей в архиве не нужны.
Почему первая сборка Java-проекта идёт так долго?
Maven или Gradle качают все зависимости заново, а у Spring Boot их много. Это разовая трата: следующие деплои того же проекта проходят быстрее, потому что кэш уже прогрет.
Сборка прошла, а ссылка не открывается. С чего начать?
С логов: часто приложение падает на старте — например, не видит базу данных. Вторая причина по частоте — порт: если он зашит в коде или приложение слушает только localhost, снаружи до него не достучаться. Берите порт из PORT и слушайте все интерфейсы.
Как подключить PostgreSQL к Spring Boot на платформе?
Либо подключите внешнюю базу и передайте строку подключения через секреты — Spring Boot читает её из переменных окружения. Либо поднимайте базу рядом с приложением в docker-compose с именованным томом, чтобы данные пережили обновление кода.
Сколько памяти дать JVM на тарифе Starter?
При 2 ГБ RAM разумный потолок — около 1.5 ГБ: ставьте -XX:MaxRAMPercentage=75 или -Xmx1536m, иначе JVM зарезервирует лишнее и контейнер упрётся в лимит. Начните с меньшего значения и увеличивайте, если в логах появятся OutOfMemoryError.