Spring Boot is the most widely used Java web framework, providing an opinionated, auto-configured platform for building standalone, production-ready applications. Spring Boot embeds an HTTP server (Tomcat, Jetty, or Undertow) directly in the application JAR, eliminating the need for a separate application server deployment. A Spring Boot application is packaged as an executable “fat JAR” (a JAR containing all dependencies) that starts with java -jar app.jar. This dramatically simplifies deployment: the application manages its own server lifecycle, making Spring Boot ideal for microservices, REST APIs, and cloud-native deployments. This guide covers building a Spring Boot 3.3 REST API with Spring Data JPA and PostgreSQL, packaging it as an executable JAR, and deploying it as a systemd service on RHEL 9.
Prerequisites
- OpenJDK 21 and Maven installed on RHEL 9
- PostgreSQL 16 running
Step 1 — Generate a Spring Boot Project
# Use Spring Initializr to generate the project
curl -X POST https://start.spring.io/starter.tgz
-d dependencies=web,data-jpa,postgresql,validation,actuator
-d type=maven-project
-d language=java
-d bootVersion=3.3.0
-d baseDir=myspringapp
-d groupId=com.example
-d artifactId=myspringapp
-d javaVersion=21
| tar -xzvf -
cd myspringapp
Step 2 — Configure Application Properties
# src/main/resources/application.properties
spring.application.name=myspringapp
server.port=8080
# PostgreSQL datasource
spring.datasource.url=jdbc:postgresql://localhost:5432/myspring_db
spring.datasource.username=myspring_user
spring.datasource.password=${DB_PASSWORD}
spring.datasource.driver-class-name=org.postgresql.Driver
# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
# Actuator health endpoint (for load balancer health checks)
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorized
Step 3 — Create a Simple REST Controller
# src/main/java/com/example/myspringapp/HealthController.java
package com.example.myspringapp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class HealthController {
@GetMapping("/api/status")
public Map status() {
return Map.of("status", "ok", "service", "myspringapp");
}
}
Step 4 — Build the Executable JAR
# Build and run tests
mvn clean package
# Skip tests for faster builds
mvn clean package -DskipTests
# The executable JAR is in target/
ls -lh target/myspringapp-0.0.1-SNAPSHOT.jar
# Test locally
DB_PASSWORD=MySpringPass123! java -jar target/myspringapp-0.0.1-SNAPSHOT.jar
Step 5 — Deploy as a systemd Service
useradd -r -s /bin/false springapp
mkdir -p /opt/myspringapp
cp target/myspringapp-0.0.1-SNAPSHOT.jar /opt/myspringapp/app.jar
chown springapp:springapp /opt/myspringapp/app.jar
# /etc/systemd/system/myspringapp.service
[Unit]
Description=My Spring Boot Application
After=network.target postgresql.service
[Service]
User=springapp
Group=springapp
WorkingDirectory=/opt/myspringapp
Environment=DB_PASSWORD=MySpringPass123!
Environment=JAVA_OPTS=-Xms256m -Xmx512m
ExecStart=/usr/bin/java ${JAVA_OPTS} -jar /opt/myspringapp/app.jar
SuccessExitStatus=143
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable --now myspringapp
curl http://localhost:8080/actuator/health
Conclusion
Spring Boot 3.3 on RHEL 9 with the embedded Tomcat server simplifies Java web application deployment to a single JAR file. The Spring Actuator health endpoint (/actuator/health) is essential for production deployments — load balancers and container orchestration platforms can poll this endpoint to detect unhealthy application instances and route traffic away before an outage impacts users. Set -Xms and -Xmx to the same value in production environments to prevent JVM heap resizing pauses under load.
Next steps: How to Install Java on RHEL 9, How to Install Maven and Gradle on RHEL 9, and How to Install Docker on RHEL 9.