Deploy Spring Boot to the Cloud with Docker
Spring Boot is the dominant Java framework for building production-grade REST APIs and microservices. It comes with an embedded Tomcat server, production-ready health endpoints via Spring Actuator, and seamless integration with PostgreSQL, MySQL, Redis, and MongoDB.
PandaStack runs Docker containers and supports all the databases Spring Boot typically needs. This guide covers a complete deployment from a fresh Spring Boot project to a live production URL.
Prerequisites
- Java 21+ (JDK) installed locally
- Maven or Gradle installed locally
- Docker installed locally
- A GitHub account
- PandaStack CLI:
npm install -g @pandastack/cli
Step 1 — Create a Spring Boot Application
Use Spring Initializr via the CLI:
curl https://start.spring.io/starter.tgz -d dependencies=web,actuator,data-jpa,postgresql -d javaVersion=21 -d bootVersion=3.3.0 -d artifactId=my-spring-app -d name=MySpringApp | tar -xzvf -
cd my-spring-appOr generate from [start.spring.io](https://start.spring.io) with Spring Web, Spring Boot Actuator, Spring Data JPA, and PostgreSQL Driver.
Add a health and hello endpoint in src/main/java/com/example/MySpringApp/HelloController.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 HelloController {
@GetMapping("/api/hello")
public Map<String, String> hello() {
return Map.of("message", "Hello from PandaStack!");
}
}Spring Actuator already exposes /actuator/health — use that as the health check endpoint.
Step 2 — Build the Application
./mvnw package -DskipTests
ls target/*.jar
# target/my-spring-app-0.0.1-SNAPSHOT.jarStep 3 — Write a Multi-Stage Dockerfile
A multi-stage build keeps the final image small by separating the build environment from the runtime:
# Stage 1: Build
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app
COPY .mvn/ .mvn/
COPY mvnw pom.xml ./
RUN ./mvnw dependency:go-offline -q
COPY src ./src
RUN ./mvnw package -DskipTests -q
# Stage 2: Runtime
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]The runtime image uses the JRE (not JDK) and a non-root user — both production best practices.
Build and test locally:
docker build -t my-spring-app .
docker run -p 8080:8080 -e SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/mydb my-spring-app
curl http://localhost:8080/actuator/health
# {"status":"UP"}Step 4 — Configure pandastack.json
{
"type": "container",
"healthCheckPath": "/actuator/health"
}Spring Actuator's /actuator/health returns {"status":"UP"} with HTTP 200 when the application is ready — perfect for PandaStack's health check.
Step 5 — Configure Application Properties
Create src/main/resources/application-production.properties:
spring.datasource.url=${DATABASE_URL}
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
management.endpoints.web.exposure.include=health,infoActivate the profile via environment variable in the PandaStack dashboard:
SPRING_PROFILES_ACTIVE=production
DATABASE_URL=jdbc:postgresql://your-pandastack-db-host:5432/mydb
DB_USERNAME=spring_user
DB_PASSWORD=your-secure-passwordStep 6 — Provision a PostgreSQL Database
panda db create --type postgres --name spring-dbPandaStack adds connection details to your project's environment automatically.
Step 7 — Push to GitHub and Deploy
git init
git add .
git commit -m "Spring Boot app with Docker and PandaStack config"
gh repo create my-spring-app --private --source=. --pushDeploy:
panda deployOr connect at [dashboard.pandastack.io](https://dashboard.pandastack.io) → New Project → select your GitHub repository.
Verify the Deployment
curl https://my-spring-app.pandastack.io/actuator/health
# {"status":"UP"}
curl https://my-spring-app.pandastack.io/api/hello
# {"message":"Hello from PandaStack!"}
panda logs --followStep 9 — Understand Spring Actuator Endpoints
Spring Actuator exposes several useful endpoints in production. The /actuator/health endpoint is used by PandaStack for health checks, but you can also expose /actuator/info and /actuator/metrics for observability. Control which endpoints are exposed in application-production.properties:
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=when-authorizedThe health endpoint returns component-level status including database connectivity:
{
"status": "UP",
"components": {
"db": { "status": "UP" },
"diskSpace": { "status": "UP" }
}
}If the database is unreachable, the health check returns DOWN with HTTP 503 — PandaStack will not route traffic to an unhealthy instance.
Summary
Spring Boot on PandaStack uses a multi-stage Docker build to produce a lean, secure runtime image. Spring Actuator provides the health check endpoint out of the box. Set database credentials in the PandaStack dashboard and push to GitHub — deploys happen automatically. Full docs at [docs.pandastack.io](https://docs.pandastack.io).