How to Run Multiple Tomcat Instances in Spring Boot 3 – A Step‑by‑Step Guide
This tutorial shows how to configure Spring Boot 3 to start multiple Tomcat servers, isolate services into separate modules with shared parent configuration, and test the endpoints, providing full code snippets and screenshots for each step.
Environment: Spring Boot 3.2.5.
1. Introduction
By default a Spring Boot project embeds a Tomcat server, which simplifies development and deployment. Adding Actuator and configuring management.server.port moves the Actuator endpoints to a separate Tomcat instance.
<code>management:
server:
port: 7000</code>After changing the Actuator port, the console shows two Tomcat instances; all Actuator endpoints run on the Tomcat listening on port 7000 (the /ac prefix was also changed).
Developers can use SpringApplicationBuilder to start multiple Tomcat instances, isolating resources while sharing the main application configuration.
2. Practical Example
The project is organized into two modules ( com.pack.m1.* and com.pack.m2.* ) that share a parent module ( com.pack.parent.* ). Each module has its own configuration file ( m1.properties , m2.properties ) analogous to the default application.yml / application.properties .
2.1 Define Modules
Module 1 configuration class:
<code>@Configuration
@ComponentScan(basePackages = {"com.pack.m1"})
@PropertySource({"classpath:m1.properties"})
@EnableAutoConfiguration
public class M1Config {
}</code>Module 1 test controller:
<code>@RestController
@RequestMapping("/m")
public class M1Controller {
private final ParentService parentService;
public M1Controller(ParentService parentService) {
this.parentService = parentService;
}
@GetMapping("/index")
public Object m1() {
return "module 01 -" + this.parentService.query();
}
}</code>Configuration file m1.properties :
<code># m1.properties
server.port=8075
server.servlet.context-path=/m1</code>Module 2 mirrors Module 1 with its own package and properties:
<code>@Configuration
@ComponentScan(basePackages = {"com.pack.m2"})
@PropertySource({"classpath:m2.properties"})
@EnableAutoConfiguration
public class M2Config {
}
@RestController
@RequestMapping("/m")
public class M2Controller {
private final ParentService parentService;
public M2Controller(ParentService parentService) {
this.parentService = parentService;
}
@GetMapping("/index")
public Object m2() {
return "module 02 - " + this.parentService.query();
}
}
# m2.properties
server.port=8076
server.servlet.context-path=/m2</code>2.2 Parent Module Definition
Shared service:
<code>@Service
public class ParentService {
public String query() {
return "I am parent module content";
}
}</code>Parent configuration class:
<code>@Configuration
@ComponentScan(basePackages = {"com.pack.parent"})
public class ParentConfig {
}</code>Note: No Web MVC is enabled, so a controller in the parent module would not be active without additional container configuration.
2.3 Global Configuration File
The default application.yml is still applied unless spring.config.name is changed:
<code>spring:
application:
name: springboot-parent-child
---
logging:
include-application-name: false
pattern:
dateformat: HH:mm:ss</code>Put shared settings here if child modules need to inherit them.
2.4 Startup Class
<code>public class SpringbootParentChildApplication {
public static void main(String[] args) {
SpringApplicationBuilder builder = new SpringApplicationBuilder();
// Configure parent container (non‑web)
builder.parent(ParentConfig.class)
// Configure first child as a web container
.child(M1Config.class).web(WebApplicationType.SERVLET)
// Configure sibling child container sharing the same parent
.sibling(M2Config.class).web(WebApplicationType.SERVLET)
.run(args);
}
}</code>No @SpringBootApplication annotation is added; the builder manually creates the parent and child contexts.
2.5 Test
After starting the application, the console shows two Tomcat instances on ports 8075 and 8076. Accessing the endpoints returns the expected responses from each module and the shared parent service.
Module 1 response:
Module 2 response:
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.