Deployment guide

Deploying a Spring Boot application on a VPS

Deploy on a VPS Cloud →

Development8 min read

Deploying a Spring Boot application on a VPS

Spring Boot remains the standard for enterprise Java APIs and microservices. Rather than paying for a PaaS billed by JVM memory, a VPS gives you full control over the heap, the connection pool and the monthly cost. Here is how to deploy your artifact cleanly in production.

Why self-host Spring Boot on a VPS

A Spring Boot application embeds its own server (Tomcat or Undertow) and ships as a standalone executable JAR. This is ideal for a VPS: a single app.jar file, one JVM, and you're running. PaaS platforms like Heroku or managed containers bill for every 512 MB slice of RAM, yet the JVM is greedy at startup. On a VPS, you set -Xmx yourself, you share the PostgreSQL database and the API on the same machine, and you control the cold warm-up without an imposed timeout. You also keep control over the exact JDK version (Temurin 21 LTS, GraalVM) and over the GC parameters, which is rarely possible in a managed environment.

Concrete benefits

  • Full control of the JVM heap (-Xmx, -Xms) and the garbage collector according to your real load
  • PostgreSQL database and API co-located: near-zero network latency between the app and the data
  • Fixed and predictable monthly cost, with no billing per RAM slice or compute time
  • JDK freedom: Temurin 21 LTS, GraalVM native-image or Azul Zulu according to your needs
  • No imposed cold start: your service stays warm 24/7 for stable response times
  • Actuator, Micrometer and Prometheus exposed freely for fine-grained monitoring at no extra cost

Hardware and software prerequisites

A Spring Boot API with a database runs comfortably on a VPS with 2 vCPU and 4 GB of RAM (count 1 to 1.5 GB for the JVM, the rest for PostgreSQL and the system). For a lightweight microservice without a heavy ORM, 2 GB is enough but stays tight at startup. Install Docker and Docker Compose, a JDK 21 if you compile on the server (otherwise build the JAR in CI and send only the artifact), and point a domain name such as api.mydomain.com at the VPS IP via an A record. Plan for 10 GB of disk minimum for the Docker images and logs.

Step-by-step deployment

01

Build the executable JAR

Run ./mvnw clean package -DskipTests (or ./gradlew bootJar). You get a file in target/app.jar that embeds Tomcat and all the dependencies. Check locally with java -jar target/app.jar before any upload.

02

Containerize with a multi-stage Dockerfile

Use eclipse-temurin:21-jre-alpine as the final image and copy only the JAR. A multi-stage build (maven:3.9-eclipse-temurin-21 to compile, JRE to run) reduces the image from 700 MB to about 250 MB. Expose port 8080.

03

Orchestrate app + PostgreSQL with Docker Compose

Declare two services in docker-compose.yml: app and db (image postgres:16). Pass the credentials via environment variables (SPRING_DATASOURCE_URL, SPRING_DATASOURCE_USERNAME) and link them through an internal network. Run docker compose up -d.

04

Configure Nginx as a reverse proxy

Install Nginx and create a vhost that does a proxy_pass http://127.0.0.1:8080;. Add the X-Forwarded-For and X-Forwarded-Proto headers so that Spring correctly detects HTTPS behind the proxy (server.forward-headers-strategy=framework).

05

Enable HTTPS with Certbot

Run certbot --nginx -d api.mydomain.com to obtain and install a Let's Encrypt certificate. Automatic renewal is handled by Certbot's systemd timer. Force the HTTP-to-HTTPS redirect in the vhost.

06

Make restart reliable

Add restart: unless-stopped to your Compose services and configure the Actuator healthcheck (/actuator/health) as the Docker probe. This way the app restarts on its own after a VPS reboot or a JVM crash.

Compile your application into a native image with GraalVM (./mvnw -Pnative native:compile via Spring Boot 3): the binary starts in under 100 ms and consumes 3 to 5 times less RAM than a classic JVM. This is decisive on a small VPS where every hundred MB counts. Also limit the heap explicitly with JAVA_OPTS=-Xmx512m in Compose to prevent the JVM from claiming all the available memory.

Deploy your Spring Boot API in minutes

The ServOrbit Cloud VPS provides a ready-to-use Docker environment, with dedicated resources and a fixed IP, to run your Spring Boot JAR in production without tedious system configuration.

Need help?

Browse our help center and FAQ, or write to our team — support in French, English and Arabic.