How to Deploy Spring Boot Application with Nginx on Ubuntu 18.04

Spring Boot is a free and open-source Java-based framework developed by Pivotal Team used to create a micro Service. Micro Service allows you to develop and deploy services independently.

Spring Boot provides a good platform for Java developers to develop a stand-alone and production-grade spring application easily. It has been specially designed to avoid complex XML configuration, reduce the development time and offer an easy way of getting started with the application. You don’t need to configure anything, everything is auto-configured.

In this tutorial, we will explain how to deploy Spring Boot with Nginx as a reverse proxy on Ubuntu 18.04.

Requirements

  • A server running Ubuntu 18.04.
  • A root password set up on your cloud server.
  • A Java version 8.

Getting Started

Before starting, make sure your server is up-to-date. Otherwise, you can update your server with the following command:

# apt-get update -y
# apt-get upgrade -y

Spring Boot is Java-based application, so you’ll need to install Java 8 on your server. You can install Java 8 with the following command:

# apt-get install openjdk-8-jdk -y

Once installed, you can check the Java version with the following command:

# java -version

You should see the following output:

java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)

Install Spring Boot CLI Tool

Next, you will need to install Spring Boot CLI and other build tools such as Gradle on your server. You can create a new project easily with Spring Boot CLI command-line tool.

First, you will need to install SDKMAN on your server. You can install it with the following script:

curl -s https://get.sdkman.io | bash

Once the installation has been completed, you should see the following output:

 All done!

Please open a new terminal, or run the following in the existing one:

source "/root/.sdkman/bin/sdkman-init.sh"

Then issue the following command:

# sdk help

You should see the following output:

 Enjoy!!!

Next, activate the SDKMAN with the following command:

# source "/root/.sdkman/bin/sdkman-init.sh"

You can check all the options available with sdk using the following command:

# sdk help

You should see the following output:

==== BROADCAST =================================================================
* 2019-09-13: Micronaut 1.2.2 released on SDKMAN! #micronautfw
* 2019-09-06: Springboot 2.1.8.RELEASE released on SDKMAN! #springboot
* 2019-09-05: Micronaut 1.2.1 released on SDKMAN! #micronautfw
================================================================================


Usage: sdk  [candidate] [version]
       sdk offline <enable|disable>

   commands:
       install   or i     [version]
       uninstall or rm    
       list      or ls   [candidate]
       use       or u     [version]
       default   or d     [version]
       current   or c    [candidate]
       upgrade   or ug   [candidate]
       version   or v
       broadcast or b
       help      or h
       offline           [enable|disable]
       selfupdate        [force]
       update
       flush             <broadcast|archives|temp>

   candidate  :  the SDK to install: groovy, scala, grails, gradle, kotlin, etc.
                 use list command for comprehensive list of candidates
                 eg: $ sdk list

   version    :  where optional, defaults to latest stable if not provided
                 eg: $ sdk install groovy

Next, you can install Spring Boot using sdk command as shown below:

# sdk install springboot

Once installed, you should get the following output:

###############################################################################
######################################################### 100.0%

Installing: springboot 2.1.8.RELEASE
Done installing!

Setting springboot 2.1.8.RELEASE as default.

You can also check the Spring Boot version with the following command:

# spring version

You should see the following output:

 Spring CLI v2.1.8.RELEASE

Next, install gradle by running the following command:

# sdk install gradle 4.5.1

Build a Jar File with Gradle

Next, create and build a new project named hello-world with Spring Boot CLI and gradle by running the following command:

# spring init --build=gradle --dependencies=web --name=hello hello-world

This command will create a new project directory named hello-world in your home directory as shown below:

Using service at https://start.spring.io
Project extracted to '/root/hello-world'

You can list all the parameters available with the Spring Boot CLI by running the following command:

# spring init --list

You should get the following output:

Project types (* denotes the default)

+-----------------+-----------------------------------------+-----------------------------+
| Id              | Description                             | Tags                        |
+-----------------+-----------------------------------------+-----------------------------+
| gradle-build    | Generate a Gradle build file            | build:gradle,format:build   |
| gradle-project  | Generate a Gradle based project archive | build:gradle,format:project |
| maven-build     | Generate a Maven pom.xml                | build:maven,format:build    |
| maven-project * | Generate a Maven based project archive  | build:maven,format:project  |
+-----------------+-----------------------------------------+-----------------------------+
Parameters
+-------------+------------------------------------------+------------------------------+
| Id          | Description                              | Default value                |
+-------------+------------------------------------------+------------------------------+
| artifactId  | project coordinates (infer archive name) | demo                         |
| bootVersion | spring boot version                      | 2.1.8.RELEASE                |
| description | project description                      | Demo project for Spring Boot |
| groupId     | project coordinates                      | com.example                  |
| javaVersion | language level                           | 1.8                          |
| language    | programming language                     | java                         |
| name        | project name (infer application name)    | demo                         |
| packageName | root package                             | com.example.demo             |
| packaging   | project packaging                        | jar                          |
| type        | project type                             | maven-project                |
| version     | project version                          | 0.0.1-SNAPSHOT               |
+-------------+------------------------------------------+------------------------------+

Next, change the directory to hello-world and open your Java hello-world file:

 cd hello-world 
nano src/main/java/com/example/helloworld/HelloApplication.java 

Make the following changes:

package com.example.helloworld;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

@SpringBootApplication
public class HelloApplication {


public static void main(String[] args) {
SpringApplication.run(HelloApplication.class, args);

      }
}

@RestController
class Hello {


@RequestMapping("/")
String index() {
return "Hello world";
       }
}

Save and close the file. Then, build the application with the following command:

# ./gradlew build

You should get the following output:

Downloading https://services.gradle.org/distributions/gradle-5.6.2-bin.zip

.........................................................................................


Welcome to Gradle 5.6.2!

Here are the highlights of this release:

- Incremental Groovy compilation
- Groovy compile avoidance
- Test fixtures for Java projects
- Manage plugin versions via settings script

For more details see https://docs.gradle.org/5.6.2/release-notes.html

Starting a Gradle Daemon (subsequent builds will be faster)

> Task :test
2019-09-14 06:40:09.170  INFO 6852 --- [       Thread-4] o.s.s.concurrent.ThreadPoolTaskExecutor  
: Shutting down ExecutorService 'applicationTaskExecutor'

BUILD SUCCESSFUL in 38s
5 actionable tasks: 5 executed

Next, run this application with the following command:

# java -jar build/libs/hello-world-0.0.1-SNAPSHOT.jar

You application is now running on a Tomcat servlet on port 8080 as shown below:

.   ____          _            __ _ _

/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

\\/  ___)| |_)| | | | | || (_| |  ) ) ) )

'  |____| .__|_| |_|_| |_\__, | / / / /

=========|_|==============|___/=/_/_/_/
:: Spring Boot ::        (v2.1.8.RELEASE)

2019-09-14 07:02:50.820  INFO 14121 --- [           main] com.example.helloworld.HelloApplication  : Starting HelloApplication on ubuntu with PID 14121 (/root/hello-world/build/libs/hello-world-0.0.1-SNAPSHOT.jar started by root in /root/hello-world)
2019-09-14 07:02:50.823  INFO 14121 --- [           main] com.example.helloworld.HelloApplication  : No active profile set, falling back to default profiles: default
2019-09-14 07:02:51.607  INFO 14121 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

Next, Press CTRL+C to stop the application and run the application again with gradle:

 gradle bootRun 

You should see the following output:

Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details
>Task :bootRun

.   ____          _            __ _ _

/\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

\\/  ___)| |_)| | | | | || (_| |  ) ) ) )

'  |____| .__|_| |_|_| |_\__, | / / / /

=========|_|==============|___/=/_/_/_/

:: Spring Boot ::        (v2.1.8.RELEASE)

2019-09-14 07:32:00.883  INFO 15562 --- [           main] com.example.helloworld.HelloApplication  : Starting HelloApplication on ubuntu with PID 15562 (/root/hello-world/build/classes/java/main started by root in /root/hello-world)
2019-09-14 07:32:00.886  INFO 15562 --- [           main] com.example.helloworld.HelloApplication  : No active profile set, falling back to default profiles: default
2019-09-14 07:32:05.724  INFO 15562 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)

Create a Systemd Service File for Spring Boot

Next, you will need to create a systemd service file to manage your application. You can do it with the following command:

# nano /etc/systemd/system/helloworld.service

Add the following lines:

[Unit]
Description=Spring Boot HelloWorld
After=syslog.target
After=network.target[Service]
User=root
Type=simple

[Service]
ExecStart=/usr/bin/java -jar /root/hello-world/build/libs/hello-world-0.0.1-SNAPSHOT.jar
Restart=always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=helloworld

[Install]
WantedBy=multi-user.target

Save and close the file. Then, reload the systemd daemon with the following command:

# systemctl daemon-reload

Next, start the helloworld service and enable it to start on boot using the following command:

# systemctl start helloworld
# systemctl enable helloworld

You can now check the status of your service with the following command:

# systemctl status helloworld

You should get the following output:

  • helloworld.service – Spring Boot HelloWorld

Loaded: loaded (/etc/systemd/system/helloworld.service; disabled; vendor preset: enabled) Active: active (running) since Sat 2019-09-14 07:48:45 UTC; 14s ago Main PID: 15696 (java) Tasks: 36 (limit: 4915) CGroup: /system.slice/helloworld.service └─15696 /usr/bin/java -jar /root/hello-world/build/libs/hello-world-0.0.1-SNAPSHOT.jar Sep 14 07:48:46 ubuntu helloworld[15696]: 2019-09-14 07:48:46.264  INFO 15696 — [           main] com.example.helloworld.HelloApplication  : Sep 14 07:48:46 ubuntu helloworld[15696]: 2019-09-14 07:48:46.268  INFO 15696 — [           main] com.example.helloworld.HelloApplication  : Sep 14 07:48:47 ubuntu helloworld[15696]: 2019-09-14 07:48:47.195  INFO 15696 — [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Sep 14 07:48:47 ubuntu helloworld[15696]: 2019-09-14 07:48:47.221  INFO 15696 — [           main] o.apache.catalina.core.StandardService   :

Configure Nginx as a Reverse Proxy

Next, you will need to configure Nginx as a reverse proxy to proxy request coming on port 80 to 8080. First, install Nginx server by running the following command:

# apt-get install nginx -y

Once installed, create a new virtual host configuration file for your application with the following command:

# nano /etc/nginx/conf.d/helloworld.conf

Add the following lines:

server {
listen 80;
listen [::]:80;

server_name example.com;

location / {
proxy_pass http://localhost:8080/;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
     }
}

Save and close the file. Then, restart Nginx service to apply all the configuration changes with the following command:

# systemctl restart nginx

Test Your Application

Spring Boot application is now installed and configured with Nginx. You can access it by visiting the URL http://example.com on your web browser. You should see your application on the following page:

Conclusion

Congratulations! you have successfully installed Spring Boot Application on your server with Nginx as a reverse proxy. For more information, you can visit the Spring Boot documentation at Spring Boot.

To write a comment on this article, fill out the form below. Fields marked with an asterisk (*) are required.