Why Self-Host Spring Boot on a VPS?
Managed Java platforms bill per RAM slice and lock you into their JDK version, which complicates JVM tuning and PostgreSQL connection management. On a VPS, you control the full stack: OpenJDK 21 LTS with Virtual Threads, Maven for builds, Nginx at the front, and PostgreSQL 16 for data. You decide on JVM flags, connection pool size, and deployment strategy. For a production Spring Boot application, this transparency is decisive: you can profile a slow endpoint, adjust -Xmx per service, and deploy a new version with no hidden extra cost.
Concrete Benefits of a Self-Hosted Spring Boot
- Full control over PostgreSQL: indexes, VACUUM, connection pools, and scheduled pg_dump backups.
- Virtual Threads (OpenJDK 21 Loom) for Spring WebMVC: hundreds of concurrent requests without reactive rewrites.
- Fixed, predictable cost regardless of traffic or API request volume.
- Data and logs under your jurisdiction, useful for compliance and auditing.
- Freedom of JDK version and system dependencies without buildpack constraints.
- Reproducible deployments: one fat JAR, one
java -jar, and the application is live.
Hardware and Software Requirements
For a Spring Boot application with PostgreSQL, plan at least 2 vCPU and 2 GB RAM; target 4 GB if you run multiple services or a loaded connection pool. The recommended OS is Ubuntu 24.04 LTS — OpenJDK 21 is in the official repositories, no PPA required. A domain name is optional: without one, an SSH tunnel to port 8080 suffices for development and testing. Allocate at least 10 GB of disk for the JVM, application, database, and logs.
Deploy Spring Boot Step by Step
Install OpenJDK 21 and PostgreSQL
SSH into your VPS and run
apt-get install -y openjdk-21-jdk maven nginx postgresql postgresql-contrib— no extra repository setup on Ubuntu 24.04. ⚠️ Nameopenjdk-21-jdkexplicitly: themavenpackage only depends ondefault-jre-headless, that isopenjdk-21-jre-headless, a runtime with nojavac. This is whyjava -versiondoes print 21.x and makes everything look ready, while the first build on the server fails withNo compiler is provided in this environment. Verify:javac -version,mvn -versionandpsql --version(16.x).Create the PostgreSQL Database and User
Connect as
sudo -u postgres psqland runCREATE USER myapp WITH PASSWORD 'StrongPassword'; CREATE DATABASE myappdb OWNER myapp;. Setspring.datasource.url=jdbc:postgresql://localhost/myappdbin yourapplication.properties.Build and Upload the JAR
Run
mvn clean package -DskipTestslocally, then transfer the fat JAR to/var/www/your-app/app.jarviascp. Create anapplication.propertieswith your PostgreSQL credentials andserver.port=8080.Create a systemd Service
Create
/etc/systemd/system/your-app.servicewithExecStart=/usr/bin/java -jar /var/www/your-app/app.jar,Restart=always,User=www-data. Runsystemctl daemon-reload && systemctl enable --now your-app. Check withsystemctl status your-appandjournalctl -u your-app -f.Configure Nginx and Enable HTTPS
Create an Nginx server block with
proxy_pass http://127.0.0.1:8080;andX-Forwarded-Protoheaders. Runcertbot --nginx -d your-domain.comfor a free Let's Encrypt certificate. Spring Boot listens on the internal port only; Nginx handles TLS.
Use Java 21 Virtual Threads with Spring MVC to multiply throughput without switching to WebFlux: add spring.threads.virtual.enabled=true to your application.properties. Each HTTP request runs in a lightweight virtual thread — thousands can be active simultaneously without saturating the system thread pool. ⚠️ The gain stays conditional on OpenJDK 21: a virtual thread that blocks inside a synchronized block pins its carrier thread instead of releasing it, and that limit is only lifted by JEP 491, in JDK 24. So before expecting a gain on I/O-bound workloads (SQL calls, REST) on a 2 GB VPS, check that your JDBC driver has moved to ReentrantLock — the PostgreSQL one did so starting with 42.6.0 — and measure pinning with the jdk.VirtualThreadPinned JFR event instead of assuming it.
Deploy Spring Boot in One Click from the ServOrbit Marketplace
The ServOrbit Marketplace offers a preconfigured Spring Boot Stack template: OpenJDK 21 LTS, Maven, Nginx, and PostgreSQL 16 are installed automatically on your VPS at order time. No SSH session for the base setup — you arrive directly at the step of uploading your JAR. The marketplace listing contains exact specifications, use cases, and a first-configuration guide.