Deploy a Spring Boot application JAR file with Nginx reverse proxy
Photo by Zachary Varga / Unsplash
Spring Boot provides two ways to package the application: JAR and WAR. Both processes generated a single file you can execute using the JRE. In production, this is not enough since you need to make the application accessible through the internet by typing a URL.
You should also make sure the requests between the client and the server are secured, and no one can spy on them. These are the topics I will cover in this post.
Prerequisites
Before following this tutorial, make sure you have the following tools installed on your computer; this is only required to run and package the project locally:
- Java Development Kit 11 or later - Download's link
- Apache Maven 3.5+ - Download's link
Prepare the Virtual Private Server
We will deploy the application on a server; you can go to the next step if you already have one.
If you don't have one, you can buy a VPS on DigitalOcean. Sign up with my referral link to get 100$ credits to use over 60 days.
Once you get the server, you will need to configure it so that it can make a web application accessible to the Internet. I wrote a post on a minimal configuration you need to do to host a Web application here.

I use a Virtual Private Server running Ubuntu 20.04, so the instructions might differ if you use another Linux distribution.
Install the required software
To run a JAR file, we need to install the Java Runtime Engine (JRE); the application will start the webserver on a specific port (8080 by default).
At this step, the application is running on the server but is not accessible to the Internet; Nginx comes to the rescue to allow us to set up a reverse proxy.

Install the Java Runtime Environment
Run the command below to install the JRE:
sudo apt install default-jre
java -version
We got the output below.

Install Nginx
Run the command below to install Nginx:
sudo apt update
sudo apt install nginx
Allow Nginx in the Firewall
sudo ufw allow 'Nginx Full'
Make sure Nginx is running:
systemctl status nginx
Setup the project locally
I prepared a Spring Boot project to use for this post. It is a web application to calculate the Body Mass Index. You can find de source code on my GitHub repository.
Let's clone it and run it locally.
git clone https://github.com/tericcabrel/bmi.git
cd bmi
mvn install
mvn spring-boot:run
Navigate to http://localhost:8000 on your browser.

The application is running locally; Let's make it work on the internet.
Generate the JAR file
Packaging a Spring Boot application is straightforward. Run the command below to generate the JAR file:
mvn clean package
The JAR file can be found in the "target" folder under the name "bmi-1.0.jar".

Copy the JAR file to the server
To copy the JAR file to the server in the $HOME folder, we will use SCP, which stands for Secure Copy. It allows copying files to a distant computer.
The syntax is:
scp -P $PORT $JAR_FILE $USER@$HOST:./
- $PORT: Replace this with the port of your VPS
- $JAR_FILE: The JAR file on the local computer we want to copy to the server.
- $USER: Replace the username created on your VPS
- $HOST: Replace this with the IP address of your VPS.
An example of the whole expression is:
scp -P 1234 bmi-1.0.jar user@192.186.11.12

The file is now on your VPS

Run the JAR file on the server
To run the JAR file with the JRE, run the command below:
java -jar bmi-1.0.jar
We get the following output.

But there is a problem; running the application like this locks the usage of the terminal, and we can do nothing on the server; even worse, if I log out of the server, the application stops running. We need to run the JAR file in the background to fix this.
Nohup is a Unix command allowing the launch of a process that will remain active even after the disconnection of the user having initiated it.
The command will be now:
nohup java -jar bmi-1.0.jar &
Don't forget the operator "&".

When we send a request to http://localhost:8000, we get a response with the HTML content. We cannot access it through the browser yet.
Create the DNS record
My domain's name is tericcabrel.com; I will create a subdomain bmi.tericcabrel.com that points to the VPS IP address. Log into the client space of your hosting platform and do that. My domain name is registered at OVH.

The change can take up to 24 hours to propagate. You can use this website to check if the DNS is ready.
Configure the reverse proxy with Nginx
On the VPS, Nginx is already installed. Create an Nginx configuration for the website with the command below:
sudo nano /etc/nginx/sites-available/bmi.tericcabrel.com
Note: The file's name is bmi.tericcabrel.com
I usually name it like that to quickly find the application I want to apply for a change. Feel free to call it as you wish.
Paste the code below inside the file, save and exit:
server {
server_name bmi.tericcabrel.com;
index index.html index.htm;
access_log /var/log/nginx/bmiapp.log;
error_log /var/log/nginx/bmiapp-error.log error;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:8000;
proxy_redirect off;
}
}
Don't forget to replace bmi.tericcabrel.com
by your domain or subdomain.
Enable the website with the command below:
sudo ln -s /etc/nginx/sites-available/bmi.tericcabrel.com /etc/nginx/sites-enabled/bmi.tericcabrel.com
We created a symbolic link of our config file inside the folder sites-enabled
; it is because Nginx only considers the websites present in this folder.
Let's verify if there is no Nginx error, then reload it to take the changes into account:
sudo nginx -t
sudo nginx -s reload
Navigate to http://bmi.tericcabrel.com
to see the result:

Youhou ?
Add SSL certificate with Letsencrypt
Install Certbot, which is the tool responsible for certificate generation:
sudo apt install snapd
sudo snap install --classic certbot
Generate and install an SSL certificate for our domain
sudo certbot --nginx -d bmi.tericcabrel.com
Reload Nginx configuration: sudo nginx -s reload
Navigate to https://bmi.tericcabrel.com.

Wrap up
To deploy a Spring Boot application packaged as a JAR file, make sure to run the application in the background process. Although this deployment method runs well, managing the running application is not easy. We can have a better deployment and monitoring process using Docker.
You can find the code source of the application deployed in this post on the GitHub repository.
Follow me on Twitter or subscribe to my newsletter to avoid missing the upcoming posts and the tips and tricks I occasionally share.