Client Area

Deploying Java and Spring Boot Applications on DomainIndia VPS

ByDomain India Team·DomainIndia Engineering
5 min read24 Apr 20264 views
# Deploying Java and Spring Boot Applications on DomainIndia VPS
TL;DR
Java/Spring Boot runs on any DomainIndia VPS. Package your app as an executable JAR, run it under systemd with a dedicated Java user, front with nginx + Let's Encrypt SSL. This guide covers JDK choice, memory tuning, database config, and going live.
## Why VPS, not shared Java apps are long-running JVM processes consuming 256 MB–2 GB+ RAM. Shared cPanel/DirectAdmin optimises for PHP per-request workloads — the JVM doesn't fit. A DomainIndia VPS gives you the root access, persistent process control, and RAM you need. Minimum VPS for Spring Boot production:
App sizeVPS planJVM heapConcurrency
Small API / MVPVPS Starter (2 GB)-Xmx512m~50 req/sec
Production APIVPS Business (4 GB)-Xmx2g~200 req/sec
Enterprise / microservicesVPS Enterprise (8+ GB)-Xmx4g per service1000+ req/sec
## Step 1 — Install JDK Java 21 LTS is the current long-term-support release (2026).
1
SSH into VPS as root
2
Install OpenJDK 21:
3
Verify: java -version → should show openjdk version "21..."
4
Create app user:
Info

Use LTS versions only. Java 21 is LTS (support until 2031). Java 22/23 are non-LTS — fine for experiments, risky for production. Our OpenJDK packages include security updates via standard OS updates.

## Step 2 — Build your Spring Boot JAR On your laptop: ```bash ./mvnw clean package -DskipTests # Produces target/your-app-0.0.1-SNAPSHOT.jar ``` Upload: ```bash scp target/your-app-0.0.1-SNAPSHOT.jar root@your-vps:/opt/spring-app/app.jar sudo chown spring:spring /opt/spring-app/app.jar ``` ## Step 3 — systemd service Create `/etc/systemd/system/spring-app.service`: ```ini [Unit] Description=Spring Boot Application After=network.target postgresql.service [Service] Type=simple User=spring Group=spring WorkingDirectory=/opt/spring-app ExecStart=/usr/bin/java -Xms256m -Xmx1024m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/spring-app/heapdumps -Dspring.profiles.active=production -Dserver.port=8080 -jar /opt/spring-app/app.jar SuccessExitStatus=143 TimeoutStopSec=20 Restart=on-failure RestartSec=10 # Security NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ReadWritePaths=/opt/spring-app ProtectHome=true # Environment EnvironmentFile=-/opt/spring-app/.env StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target ``` Create `/opt/spring-app/.env`: ``` DB_URL=jdbc:postgresql://localhost/myapp DB_USER=spring DB_PASSWORD=changeme JWT_SECRET=some-random-256-bit-string ``` Start: ```bash sudo systemctl daemon-reload sudo systemctl enable --now spring-app sudo journalctl -u spring-app -f ``` ## Step 4 — nginx reverse proxy `/etc/nginx/conf.d/spring.conf`: ```nginx upstream spring { server 127.0.0.1:8080; keepalive 32; } server { listen 80; server_name api.yourcompany.com; client_max_body_size 20M; location / { proxy_pass http://spring; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; proxy_read_timeout 60s; } } ``` Test + reload + Let's Encrypt: ```bash sudo nginx -t && sudo systemctl reload nginx sudo certbot --nginx -d api.yourcompany.com ``` ## Step 5 — Database (PostgreSQL) ```bash sudo dnf install -y postgresql-server postgresql-contrib sudo postgresql-setup --initdb sudo systemctl enable --now postgresql sudo -u postgres psql -c "CREATE DATABASE myapp;" sudo -u postgres psql -c "CREATE USER spring WITH ENCRYPTED PASSWORD 'changeme';" sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE myapp TO spring;" ``` `application-production.yml` in your Spring app: ```yaml spring: datasource: url: ${DB_URL} username: ${DB_USER} password: ${DB_PASSWORD} jpa: hibernate: ddl-auto: validate # or update for dev; never create in prod show-sql: false properties: hibernate: dialect: org.hibernate.dialect.PostgreSQLDialect ``` ## Memory tuning Wrong heap sizing is the #1 cause of Spring Boot crashes on small VPS.
VPS RAM-Xms-XmxOS overhead buffer
2 GB256m1024m~1 GB
4 GB512m2048m~2 GB
8 GB1024m4096m~4 GB
Rule: **JVM max heap ≤ (total RAM / 2)**. The JVM uses non-heap memory (metaspace, native code, threads) that's not counted in `-Xmx`. Over-sized heap + OOM killer = service restart loop. Enable `XX:+HeapDumpOnOutOfMemoryError` so when it does crash, you have a dump to debug with Eclipse MAT. ## Build optimisation **Multi-module projects with Maven:** ```bash ./mvnw -T 4 clean package -DskipTests -Dspring-boot.build-image.skip=true ``` `-T 4` uses 4 parallel threads. **Spring Boot layered JAR (faster Docker rebuilds):** ```xml org.springframework.boot spring-boot-maven-plugin true ``` Unpack the JAR into layers, containerise each layer separately → dependency layers cached, app layer small and fast. ## Common pitfalls ## FAQ
Q Which JVM — OpenJDK, Oracle JDK, or GraalVM?

OpenJDK for production stability. Oracle JDK requires a commercial licence for business use. GraalVM Community Edition is interesting for low-RAM workloads (native-image reduces to ~30 MB + <100 ms startup), but builds are complex — worth exploring for microservices, overkill for monoliths.

Q Native image (GraalVM) vs traditional JVM?

Native: faster cold start, 5–10× less RAM, harder to build (reflection issues, long compile). JVM: slower start (3–10s), higher RAM, easier build. Start with JVM, move to native only if cold-start or RAM is critical.

Q Tomcat (embedded) vs Netty vs Undertow?

Spring Boot defaults to Tomcat — fine for 95% of apps. Netty is reactive/non-blocking (WebFlux). Undertow is lighter than Tomcat if you're on a 2 GB VPS and need to squeeze RAM.

Q How do I enable HTTPS directly in Spring?

Don't — let nginx handle SSL. Simpler to renew, simpler to tune, standard ops practice.

Q Can I run multiple Spring services on one VPS?

Yes — different ports + different systemd services + nginx server blocks per domain. Plan RAM carefully.

Java/Spring needs a proper VPS with 4+ GB RAM for production workloads. See VPS plans

Was this article helpful?

Your feedback helps us improve our documentation

Still need help? Submit a support ticket

Still need help?

Our support team can assist you directly.

Submit Ticket