On this page
Deployment
Spring Boot applications can be deployed as executable JARs, WAR files, or native images. The executable JAR is the most common approach.
Executable JAR
Spring Boot repackages your JAR with an embedded server:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Build and run:
mvn clean package -DskipTests
java -jar target/myapp-1.0.0.jar
# With JVM options
java -Xms512m -Xmx1g -jar target/myapp-1.0.0.jar
# With profile
java -jar target/myapp-1.0.0.jar --spring.profiles.active=prod
Externalized Configuration
java -jar myapp.jar \
--spring.datasource.url=jdbc:postgresql://db:5432/mydb \
--server.port=8080 \
--spring.profiles.active=prod
Environment variables (Spring relaxed binding):
export SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/mydb
export SERVER_PORT=8080
java -jar myapp.jar
Docker Deployment
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY target/myapp-1.0.0.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Multi-stage build:
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY . .
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:21-jre-alpine
COPY --from=build /app/target/myapp-1.0.0.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
Kubernetes
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: prod
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
WAR Deployment
For external Tomcat:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(Application.class);
}
}
<packaging>war</packaging>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
GraalVM Native Image
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
mvn -Pnative native:compile
./target/myapp # native binary, fast startup
Best Practices
- Use profiles (
dev,staging,prod) for environment-specific config - Externalize all secrets — never hardcode in JAR
- Configure health probes for Kubernetes deployments
- Set JVM heap limits appropriate for container memory
- Use multi-stage Docker builds for smaller images