How to change server port in spring boot
Spring boot web application using embedded server by default runs on port 8080. Following are the ways to change default server port from 8080 to say 9090
Follow any of the given five ways to change server port:-
1. application.properties
server.port = 9090
2. application.yml
server:
port: 9090
3. command-line parameter
$ java -jar -Dserver.port=9090 spring-boot-app-1.0.jar
OR
$ java -jar spring-boot-app-1.0.jar --server.port=9090
4. SpringBootApplication main method
@SpringBootApplication
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(SpringBootDemoApplication.class);
app.setDefaultProperties(Collections.singletonMap("server.port", "9090"));
app.run(args);
}
}
5. implement WebServerFactoryCustomizer interface
@Component
public class ServerPortCustomizer
implements WebServerFactoryCustomizer<ConfigurableWebServerFactory> {
@Override
public void customize(ConfigurableWebServerFactory factory) {
factory.setPort(9090);
}
}
Which One Wins If You Use More Than One?
These five approaches don’t exist in isolation — Spring Boot merges all configured property sources into one Environment, and when the same property is set in more than one place, precedence decides which value applies. From highest to lowest among the options above:
- Command-line argument (
--server.port=9090) — always wins over file-based configuration. - JVM system property (
-Dserver.port=9090) — also wins over file-based configuration. application.properties/application.yml— read at startup; profile-specific files (e.g.application-prod.yml) override the base file for that profile.setDefaultProperties(...)— the lowest-precedence source of all, despite being set in code. It’s meant purely as a fallback used only when nothing else supplies the property.
The WebServerFactoryCustomizer approach in option 5 is different in kind — it’s not a property source at all, it’s imperative code that runs during server bean creation and calls factory.setPort(9090) directly. Because it executes as part of building the WebServerFactory bean, it effectively has the final say and will override a server.port value coming from any property source, which is worth knowing if you use it alongside application.yml and the port doesn’t seem to take effect the way you expect.
Picking a Random Free Port
A common need in integration tests is a server port that doesn’t collide with anything else running on the machine. Spring Boot supports this directly:
server.port = 0
Setting server.port to 0 tells the underlying servlet container (Tomcat, Jetty, or Undertow) to bind to any available ephemeral port assigned by the OS, rather than a fixed one. Since you don’t know the value ahead of time, you retrieve it at runtime — for example, in a Spring Boot test with @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT), by injecting it with @LocalServerPort (or @Value("${local.server.port}")).
Gotchas
- Port already in use. If another process already holds the configured port, the embedded server fails to start and Spring Boot throws a
PortInUseException— the whole application context fails to come up, it doesn’t just skip starting the web server. - Reactive apps use the same property. If you’re on Spring WebFlux with the embedded Netty server instead of Tomcat,
server.portis still the correct property — the property name doesn’t change with the underlying server implementation. - Actuator can live on a different port. If you separately expose Actuator endpoints and want them reachable on their own port (common for keeping management endpoints off the public-facing port), that’s a distinct property,
management.server.port, notserver.port. - Container port mapping isn’t the same thing. In Docker, mapping
-p 8080:9090on the host doesn’t change what port Spring Boot listens on inside the container — you still needserver.port=9090(or one of the methods above) set for the application; the Docker flag only maps the host-visible port to it.