Deploying a Java Web App
Deploying a Java web app means taking your built application and running it somewhere users can reach it — a server, a container platform, or a cloud service. With modern Spring Boot this is far simpler than the old days of configuring a standalone Tomcat: Boot packages your app and an embedded web server into a single executable JAR that runs with one command. This guide covers building that JAR, running it on a server, containerising it with Docker, and the production checks that separate a demo from a real deployment.
Step 1: Build an executable JAR
Spring Boot's build plugin produces a "fat JAR" — your code plus all dependencies plus an embedded server, bundled together. With Maven:
# Build the project; the JAR lands in the target/ folder
./mvnw clean package
# Run it — the embedded server starts on port 8080 by default
java -jar target/myapp-1.0.0.jar
That single JAR is fully self-contained. Anywhere a compatible Java runtime is installed, this command starts your app. No external server install, no WAR deployment.
Step 2: Configure for the environment
Never hard-code production settings. Pass them at runtime so the same JAR works in dev, staging, and production:
# Override properties without rebuilding — values come from the environment
java -jar target/myapp-1.0.0.jar \
--server.port=8080 \
--spring.datasource.url="jdbc:postgresql://db-host:5432/prod" \
--spring.profiles.active=prod
Using Spring profiles (--spring.profiles.active=prod) lets you keep separate application-prod.properties and application-dev.properties files, so each environment loads its own config cleanly.
Step 3: Run it as a managed service
On a Linux server you do not want the app to die when you log out. Run it under a process manager so it restarts on crash and on reboot. A minimal systemd unit:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot App
After=network.target
[Service]
# Run as a non-root user for security
User=appuser
ExecStart=/usr/bin/java -jar /opt/myapp/myapp-1.0.0.jar
SuccessExitStatus=143
Restart=always
[Install]
WantedBy=multi-user.target
Then systemctl enable --now myapp keeps it running and restarts it automatically.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesStep 4: Containerise with Docker (optional but common)
Packaging your app as a Docker image makes deployment portable and reproducible:
# Use an official Java runtime base image
FROM eclipse-temurin:21-jre
# Copy the built JAR into the image
COPY target/myapp-1.0.0.jar /app/app.jar
# Document the port the app listens on
EXPOSE 8080
# Start the app when the container runs
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
Build with docker build -t myapp . and run with docker run -p 8080:8080 myapp. The container runs identically on your laptop, a server, or a cloud platform.
Production essentials checklist
Before calling a deployment "done," verify:
- Externalised secrets — database passwords and API keys come from environment variables or a secrets store, never the JAR.
- A reverse proxy — put Nginx or a load balancer in front to handle HTTPS/TLS termination.
- Health checks — expose a health endpoint (Spring Boot Actuator provides
/actuator/health) so monitoring can detect failures. - Logging — write logs somewhere durable, not just the console, so you can diagnose issues.
- Resource limits — set JVM memory options appropriate to the server so the app does not get killed under load.
Common mistakes
- Baking secrets into the JAR or image. Anyone with the artifact can read them. Inject secrets at runtime.
- Running as root. Run the app under a dedicated unprivileged user to limit damage if it is compromised.
- No process manager. Launching with a bare
java -jarin a terminal means the app dies on logout. Use systemd, Docker, or a platform. - Skipping HTTPS. Serving plain HTTP in production exposes user data. Terminate TLS at a reverse proxy.
- Forgetting environment-specific config. Shipping dev settings (debug logging, a test database URL) to production causes outages. Use profiles.
FAQ
Do I still need a separate Tomcat? No. Spring Boot embeds the server in the JAR, so you typically run the JAR directly. Deploying a WAR to an external server is still possible but no longer the default.
Which Java version should production use? Run a current Long-Term Support release (such as Java 21) for stability and security updates.
Keep learning
Deployment is the last mile after understanding your app structure and building with Spring Boot. See where it fits in the Advanced Java roadmap, or browse the Advanced Java hub.
Want to take a Java app all the way to production? Join the waitlist for the Advanced Java course at Infoplanet, Jalgaon.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Advanced Java / Backend Roadmap
A clear, ordered roadmap for learning Advanced Java and backend development — from core Java through servlets, Spring Boot, REST APIs, and deployment.
Hibernate & JPA Basics
Hibernate is the leading JPA implementation that maps Java objects to database tables. This guide explains ORM, entities, and the Jakarta Persistence annotations.
Anatomy of a Java Web App
A tour of how a modern Java web application is structured: the standard directory layout, layered packages, and how a request flows through them.
