Почему ваш Spring Boot «не хочет» слушать на 8080?
Вы запускаете своё первое Spring Boot приложение, видите заветный баннер в консоли, открываете браузер — а там «Connection refused». Знакомая ситуация? Чаще всего проблема в том, что порт 8080 уже занят другим процессом (например, Skype, Docker или второй экземпляр вашего же приложения). Или, наоборот, вам нужно запустить три микросервиса на одной машине, и все они хотят захватить один и тот же порт.
В этой статье мы разберём все основные способы настройки порта в Spring Boot — от самых простых до «боевых» для продакшена. Вы узнаете, как переопределить порт через файлы конфигурации, переменные окружения, аргументы командной строки и даже программно. А в конце я дам чек-лист, какой способ выбрать в зависимости от ситуации.
Способ 1: application.properties — классика
Самый распространённый и интуитивно понятный метод. В файле src/main/resources/application.properties достаточно добавить одну строку:
server.port=9090
Всё. После перезапуска приложение будет слушать на порту 9090. Если нужно вернуть 8080 — просто удалите или закомментируйте строку.
Плюсы: простота, понятность, работает «из коробки».
Минусы: жёстко зашито в код — для каждого окружения (dev, test, prod) придётся менять файл вручную или использовать профили.
Способ 2: application.yml (YAML) — для любителей структуры
Если вы предпочитаете YAML-формат, конфигурация будет выглядеть так:
server:
port: 9090
Обратите внимание на отступы: два пробела перед port. YAML чувствителен к пробелам, но зато позволяет группировать настройки. Например, можно сразу задать и контекстный путь:
server:
port: 9090
servlet:
context-path: /myapp
Когда использовать: если ваш проект уже использует YAML для всех конфигураций (например, для Spring Cloud Config).
Способ 3: Аргументы командной строки — гибкость для DevOps
Самый гибкий способ, который часто используется в контейнерах и CI/CD. При запуске JAR-файла просто передайте параметр:
java -jar myapp.jar --server.port=9090
Или, если используете Maven/Gradle плагин:
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=9090
Аргументы командной строки имеют самый высокий приоритет среди всех способов конфигурации в Spring Boot. Это значит, что они переопределят даже то, что написано в application.properties.
Идеально для: Docker-контейнеров, Kubernetes, автоматизированных деплоев.
Способ 4: Переменные окружения — стандарт двенадцатифакторных приложений
Spring Boot автоматически читает переменные окружения и преобразует их в свойства. Правило простое: SERVER_PORT (в верхнем регистре, подчёркивание вместо точки) станет server.port.
В Linux/macOS:
export SERVER_PORT=9090
java -jar myapp.jar
В Windows (cmd):
set SERVER_PORT=9090
java -jar myapp.jar
В Docker Compose это выглядит ещё элегантнее:
services:
myapp:
image: myapp:latest
ports:
- "9090:9090"
environment:
- SERVER_PORT=9090
Почему это круто: переменные окружения не попадают в репозиторий, их легко менять для разных сред, и они следуют методологии 12-factor app.
Способ 5: Программная настройка — для микроменеджмента
Иногда нужно вычислить порт динамически (например, найти свободный порт или получить из внешнего сервиса). Тогда на помощь приходит Java-код.
Самый простой вариант — переопределить метод setServerPort в классе, аннотированном @SpringBootApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.addListeners((ApplicationListener<ApplicationEnvironmentPreparedEvent>) event -> {
int dynamicPort = findFreePort(); // ваш метод
System.setProperty("server.port", String.valueOf(dynamicPort));
});
app.run(args);
}
private static int findFreePort() {
// логика поиска свободного порта
return 9090; // упрощённо
}
}
Или, если используете внешний конфигурационный сервер:
@Value("${custom.port:8080}")
private int port;
@Bean
public TomcatServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.setPort(port);
return factory;
}
Когда это нужно: когда порт берётся из базы данных, внешнего API или генерируется на лету для изоляции тестов.
Сравнение подходов: что выбрать?
Давайте сведём все способы в одну таблицу для наглядности:
- application.properties — для прототипов и личных проектов. Просто, но негибко.
- application.yml — для структурированных конфигов с множеством вложенных свойств.
- Аргументы командной строки — для Docker и CI/CD. Максимальный приоритет.
- Переменные окружения — для продакшена и 12-factor apps. Безопасно и стандартизировано.
- Программная настройка — для динамических сценариев (тесты, облачные среды).
Важно помнить порядок приоритета (от высшего к низшему):
- Аргументы командной строки (
--server.port=...) - Переменные окружения (
SERVER_PORT) - application.properties / application.yml (внешние, если указан
spring.config.location) - application.properties / application.yml (внутренние, в classpath)
- Значения по умолчанию (8080)
Это значит, что если вы задали порт в application.properties как 9090, но при запуске передали --server.port=7070, то приложение запустится на порту 7070.
Как узнать текущий порт программно?