Deploy a Spring Boot application JAR file with Nginx reverse proxy

Deploy a Spring Boot application JAR file with Nginx reverse proxy
Photo by Zachary Varga / Unsplash

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:

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.

The minimal configuration of a VPS server to host a Web Application
You just bought a fresh VPS to host your Web application but don’t know our the configure it in order to be ready to make your app accessible through Internet? We will cover how to configure it in this tutorial.

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.

Illustration of the reverse proxy of Spring Boot application with Nginx
Illustration of the reverse proxy of Spring Boot application with Nginx

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.

Verify JRE installation

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.

GitHub - tericcabrel/bmi: A Spring boot web application to calculate the body mass index
A Spring boot web application to calculate the body mass index - GitHub - tericcabrel/bmi: A Spring boot web application to calculate the body mass index

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.

Run the Spring Boot application locally

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".

The Spring Boot application is packaged as a JAR file
The Spring Boot application is packaged as a JAR file.

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
Copy the JAR file to the server using SCP
Copy the JAR file to the server using SCP

The file is now on your VPS

Verify the JAR file is present on the server
Verify the JAR file is present on the server

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.

Run the Spring Boot application on the server
Run the Spring Boot application on the server

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 "&".

Run the Spring Boot application on the server in the background
Run the Spring Boot application on the server in the background

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.

Create the DNS record for the subdomain
Create the DNS record for the subdomain

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:

Access the application through the subdomain 

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.

Access the secured application through the subdomain
Access the secured application through the subdomain 

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.