Back to Blog
Tutorial

How to Deploy a Spring Boot Application in 1 Minute

Daniel Brooks6 min read
How to Deploy a Spring Boot Application in 1 Minute

Spring Boot is Java's most popular framework for building production-grade applications. It powers everything from microservices at Fortune 500 companies to startup MVPs. The embedded Tomcat server, auto-configuration, and opinionated defaults make it the go-to choice for enterprise Java development.

Deploying a Spring Boot application to production typically requires configuring a JVM, tuning memory settings, setting up reverse proxies, and managing SSL certificates. With Out Plane, you can deploy your Spring Boot application in under a minute. This guide shows you exactly how.

What You'll Need

Before starting, make sure you have:

  • Java 17+ installed on your machine
  • Maven or Gradle as your build tool
  • A GitHub account
  • A Spring Boot application in a GitHub repository

Don't have Java installed? Download it from Adoptium:

  • Windows: Download the MSI installer from adoptium.net. Verify installation with java -version in PowerShell.
  • macOS: Use brew install --cask temurin or download the PKG installer from adoptium.net
  • Linux: Run sudo apt install openjdk-17-jdk (Ubuntu/Debian) or sudo dnf install java-17-openjdk-devel (Fedora)

For Maven, install with:

  • Windows: Download from maven.apache.org and add to PATH
  • macOS: Use brew install maven
  • Linux: Run sudo apt install maven (Ubuntu/Debian)

Once Java and Maven are installed, create a project folder:

bash
mkdir my-spring-app && cd my-spring-app

If you don't have a Spring Boot application yet, use our example below.

Quick Start: Sample Spring Boot Application

You can generate a new project with Spring Initializr or create the files manually. Here's a minimal Spring Boot application you can use.

Create pom.xml:

xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.4.2</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>my-spring-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-spring-app</name>
    <description>Spring Boot application deployed on Out Plane</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Create the main application class at src/main/java/com/example/myspringapp/MySpringAppApplication.java:

java
package com.example.myspringapp;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MySpringAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringAppApplication.class, args);
    }
}

Create a REST controller at src/main/java/com/example/myspringapp/controller/AppController.java:

java
package com.example.myspringapp.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class AppController {

    @GetMapping("/")
    public Map<String, String> home() {
        return Map.of(
            "message", "Hello from Spring Boot!",
            "status", "running"
        );
    }

    @GetMapping("/health")
    public Map<String, String> health() {
        return Map.of("status", "healthy");
    }

    @GetMapping("/api/items")
    public List<Map<String, Object>> getItems() {
        return List.of(
            Map.of("id", 1, "name", "Item One", "active", true),
            Map.of("id", 2, "name", "Item Two", "active", true),
            Map.of("id", 3, "name", "Item Three", "active", false)
        );
    }
}

Create src/main/resources/application.properties:

properties
server.port=8080
spring.application.name=my-spring-app
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorized

Test your application locally:

bash
mvn spring-boot:run

Visit http://localhost:8080 in your browser. You should see the JSON response.

Now create a Dockerfile in the project root. A multi-stage build keeps the final image small by separating the build environment from the runtime:

dockerfile
# Build stage
FROM maven:3.9-eclipse-temurin-17 AS builder

WORKDIR /app

COPY pom.xml .
RUN mvn dependency:go-offline

COPY src ./src
RUN mvn package -DskipTests

# Runtime stage
FROM eclipse-temurin:17-jre-alpine

WORKDIR /app

COPY --from=builder /app/target/*.jar app.jar

EXPOSE 8080

ENTRYPOINT ["java", "-jar", "app.jar"]

This produces a production-ready image with only the JRE and your application JAR. The build stage downloads dependencies first for better Docker layer caching.

Push this code to a GitHub repository, and you're ready to deploy.

Deploy in 3 Steps

Step 1: Connect Your Repository

  1. Go to console.outplane.com
  2. Sign in with your GitHub account
  3. Select your Spring Boot repository from the list

Out Plane detects your application and prepares the build process.

Step 2: Configure Your Application

Configure the following settings in the create application form:

Build Method

Select how Out Plane should build your application:

  • Dockerfile (Recommended): Uses the multi-stage Dockerfile above for optimal image size and full control over JVM settings.
  • Buildpacks: Automatically detects Java and builds from pom.xml or build.gradle.

For Spring Boot applications, Dockerfile is the recommended approach. It gives you control over JVM memory settings and produces smaller, more predictable images.

Basic Settings

  • Port: Set to 8080
  • Branch: Select main or your preferred branch
  • Region: Choose the region closest to your users (default: Nuremberg)

Environment Variables (Optional)

If your application uses environment-specific configuration, add them here. For our simple example, no environment variables are required.

For more complex applications, add variables using the Add button or Raw Edit for bulk entry:

text
SPRING_PROFILES_ACTIVE=prod
JAVA_OPTS=-Xms256m -Xmx512m

Step 3: Deploy

Click Deploy Application and watch the build process:

  1. Queued → Waiting for resources
  2. Building → Compiling your Spring Boot application, downloading dependencies
  3. Deploying → Starting your application with embedded Tomcat
  4. Ready → Your app is live

Once the status shows Ready, your application is live. You can find your application URL at the top of the deployment page. Click the URL to open your Spring Boot app in a new tab. SSL is automatically configured.

Production Best Practices

JVM Memory Settings

Java applications need proper memory configuration. Set JVM heap size based on your container's available memory:

text
JAVA_OPTS=-Xms256m -Xmx512m -XX:+UseG1GC

A common rule: set the max heap (-Xmx) to roughly 75% of your container's memory limit. The remaining 25% covers metaspace, thread stacks, and native memory.

Update your Dockerfile entrypoint to respect JAVA_OPTS:

dockerfile
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

Spring Profiles

Use Spring profiles to manage environment-specific configuration. Create src/main/resources/application-prod.properties:

properties
server.port=8080
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
logging.level.root=WARN
logging.level.com.example=INFO
management.endpoints.web.exposure.include=health,info,metrics

Activate the production profile via environment variable:

text
SPRING_PROFILES_ACTIVE=prod

This keeps development and production settings separated without code changes.

Actuator Health Checks

Spring Boot Actuator provides built-in health check endpoints. With spring-boot-starter-actuator in your dependencies, the /actuator/health endpoint is available automatically:

json
{
  "status": "UP"
}

Out Plane uses health endpoints to verify your application is ready to receive traffic. Actuator also exposes metrics at /actuator/metrics for monitoring JVM performance, HTTP request counts, and database connection pool status.

Graceful Shutdown

Enable graceful shutdown so in-flight requests complete before the application stops:

properties
server.shutdown=graceful
spring.lifecycle.timeout-per-shutdown-phase=30s

This gives active requests 30 seconds to finish before forcing shutdown. This prevents data loss during deployments and scaling events.

Externalized Configuration

Keep sensitive data out of your codebase. Spring Boot reads environment variables automatically:

java
// application.properties
// spring.datasource.url=${DATABASE_URL}
// spring.datasource.username=${DB_USERNAME}
// spring.datasource.password=${DB_PASSWORD}

// Or use @Value in your code
@Value("${app.api-key:default-value}")
private String apiKey;

Spring Boot maps environment variables to properties automatically. DATABASE_URL maps to database.url, and SPRING_DATASOURCE_URL maps to spring.datasource.url.

Connecting a Database

Most Spring Boot applications need a database. Out Plane provides managed PostgreSQL:

  1. Go to Databases in the sidebar
  2. Click Create Database
  3. Select PostgreSQL version and region
  4. Copy the connection URL

Add the connection URL as an environment variable:

text
DATABASE_URL=postgres://user:password@host:5432/database

Add Spring Data JPA and PostgreSQL dependencies to your pom.xml:

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <scope>runtime</scope>
</dependency>

Configure the datasource in application-prod.properties:

properties
spring.datasource.url=${DATABASE_URL}
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5

Create an entity and repository:

java
@Entity
@Table(name = "items")
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private boolean active;

    // Getters and setters
}
java
@Repository
public interface ItemRepository extends JpaRepository<Item, Long> {
    List<Item> findByActiveTrue();
}

Spring Data JPA handles connection pooling via HikariCP automatically. No additional configuration is needed for production-grade database connections.

Custom Domain Setup

Replace the default .outplane.app URL with your own domain:

  1. Navigate to Domains
  2. Click Map Domain
  3. Enter your domain (e.g., api.yourdomain.com)
  4. Add the DNS records shown to your domain registrar

SSL certificates are automatically provisioned once DNS propagates.

Monitoring Your Application

After deployment, monitor your Spring Boot application:

  • Logs: View real-time application logs including Spring Boot startup logs and request traces
  • Metrics: Track CPU, memory, and network usage
  • HTTP Logs: Analyze incoming requests, response times, and status codes

Access these from the sidebar in your application dashboard.

Spring Boot Actuator provides additional insight into your application. With the Actuator dependency included, these endpoints are available:

  • /actuator/health — Application health status and dependency checks
  • /actuator/metrics — JVM memory, garbage collection, HTTP request statistics
  • /actuator/info — Application metadata and build information

Troubleshooting

Out of Memory / Java Heap Errors

Configure JVM heap size. Java applications default to using a percentage of the host's total memory, which may exceed container limits. Set explicit limits:

text
JAVA_OPTS=-Xms256m -Xmx512m

Check your application logs for java.lang.OutOfMemoryError messages.

Port Mismatch

Check the port configuration. Make sure you set the port to 8080 in the application settings. Verify your application.properties contains server.port=8080 and your Dockerfile has EXPOSE 8080.

Build Failures

Verify your pom.xml or build.gradle is in the repository root. Maven and Gradle builds require the build file at the project root. Run mvn clean package locally to confirm the build succeeds before deploying.

Common causes:

  • Missing spring-boot-maven-plugin in pom.xml
  • Incompatible Java version between local and Docker image
  • Test failures (use -DskipTests in the Dockerfile build stage)

Slow Startup

Optimize your Spring Boot startup time. Spring Boot 3.x applications with many auto-configurations can take 10-30 seconds to start. Reduce startup time by:

  • Excluding unused auto-configurations: @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
  • Using lazy initialization: spring.main.lazy-initialization=true
  • Minimizing classpath scanning

Database Connection Errors

Verify DATABASE_URL format. Ensure the connection string follows this format:

text
postgres://username:password@hostname:port/database

For Spring Boot, you may also use the JDBC format:

text
spring.datasource.url=jdbc:postgresql://hostname:port/database
spring.datasource.username=username
spring.datasource.password=password

Check that your database is in the same region as your application for lowest latency.

Next Steps

Your Spring Boot application is now deployed and running in production. Here's what to explore next:

  • Scale your application: Adjust instance types and auto-scaling settings for higher traffic
  • Set up CI/CD: Enable automatic deployments on every git push
  • Add monitoring: Integrate with external monitoring tools via Out Plane's metrics export
  • Configure caching: Add Redis with Spring Data Redis for session storage and response caching

Summary

Deploying a Spring Boot application to Out Plane takes three steps:

  1. Connect your GitHub repository
  2. Configure port (8080), build method (Dockerfile), and environment variables
  3. Deploy and get your live URL with automatic HTTPS

No server configuration, no manual SSL setup, no infrastructure management. Your embedded Tomcat server runs inside a containerized environment with automatic scaling.

Ready to deploy your Spring Boot application? Get started with Out Plane and receive $20 in free credit. Pay only for what you use with per-second billing.


Tags

spring-boot
java
deployment
tutorial
api
enterprise

Start deploying in minutes

Connect your GitHub repository and deploy your first application today. $20 free credit. No credit card required.