Deploying a Spring Boot & React App to Azure

Mohammed Abdul Mannan
7 min readJul 30, 2020

--

Microsoft Azure provides quite solid Java support.

In this tutorial, I’ll demonstrate how to make a Spring Boot application with React work on the Azure platform.

Creating a Spring Boot Application 🍃

We begin with creating the application using Spring Initializr.

Here we are given a choice on either to go Gradle (an advanced general-purpose build management tool) with Java 8 or Maven (a software project management system) with Java 11. Gradle is the newer tool and it is what I prefer over Maven, so let’s go with the Java 8 combination. You can add the group name of your own along with Artifact, Name, Description and the Package name.

For Packaging we go with Jar, which is package file format used to aggregate many Java class files and associated metadata and resources (images, text, etc.) into one file to distribute application software or libraries on the Java platform.

Lastly for the dependencies, it’s enough to only include “Spring Web” for the moment.

After downloading and opening up the project in IntelliJ, we can let Gradle fetch the dependencies.

Let’s add a simple controller so we see something when we fire up the application.

package com.mannan.demoapp;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import java.util.Date;
@RestController
public class DemoController {
@GetMapping(“/api/hello”)
public String hello() {
return “Hello mate, the time now is “ + new Date() + “\n”;
}
}

A simple controller with a REST (acronym for REpresentational State Transfer) api endpoint which will say hello and show what time it is.

Build the application using the build button and then run the Spring Application using the command gradlew bootrun on the terminal. Wait till the Tomcat server starts on port 8080.

http://localhost:8080/api/hello?name=Spring%20Boot

Add the following on the browser to check for the running application.

There you go a running Spring Boot application, responding to our query!

Now moving onto the front-end part.

Initializing React ⚛

Now, let’s set up the frontend. I mostly work with React, also for private projects.

We do so with the help of create-react-app which is a development environment that mirrors what you’d see working with React in a professional setting in a very simple manner!

Assuming we already have node/npm installed, we can jump right into installing create-react-app! We’ll want to run the following command in our terminal:

$ npm install -g create-react-app

Alternatively, if you’re big on using Yarn, you can use Yarn to install create-react-app globally instead!

$ yarn global add create-react-app

Then we create our react app in the main of our spring boot application using

npx create-react-app my-appcd my-appnpm start

This will open a web browser on your desktop, and it should display something like this:

Our default starter React project

Calling rest services in Spring from React 📞

Now we have a backend server in Spring Boot running at http://localhost:8080 and a frontend in React running at http://localhost:3000. We’d like to be able to call services in the backend and display the results in the frontend. In order to do this (and not get into trouble with any cross-origin requests (CORS)) we ask the frontend server to proxy any requests from :3000 to :8080.

According to the create-react-app documentation you have to add a proxy entry to my-app/package.json. This will ensure that the web server at :3000 proxies any requests to http://localhost:3000/api/* to http://localhost:8080/api, which will enable us to call the backend without running into any CORS issues. Note that this is only useful during development. In a test or production environment, we will solve this in a different way.

Make sure your package.json for the front end looks like this

Make sure you have the backend running, and restart the frontend. You should now be able to fetch the hello service through the frontend server at http://localhost:3000/api/hello

Next, let’s add a rest call to the frontend:

Open my-app/src/App.js and replace its contents with this:

Packaging React app with Spring Boot 🍃+⚛

The frontend is running on port 4000 and fetches data from the backend (which is running on port 8080).

We can now create a production build of the React app and copy it to build of spring boot application. Everything in static will be served as static files by Spring Boot.

Steps:

  1. Adding Node plugin

Add the following plugin to the build.gradle file so that it gets access to npm task

id “com.moowork.node” version “1.3.1”

Check whether spring boot application can access the npm task after syncing using gradlew tasks — all in the terminal.

2. Configuring the Plugin

We have to the configure the above plugin by using the node extension block, by adding this code:

node {
// Version of node to use.
version = '12.16.3'

// Version of npm to use.
npmVersion = '6.14.4'

// Base URL for fetching node distributions (change if you have a mirror).
// distBaseUrl = 'https://nodejs.org/dist'

// If true, it will download node using above parameters.
// If false, it will try to use globally installed node.
download = false

// Set the work directory for unpacking node
workDir = file("${project.buildDir}/src/main/my-app/nodejs")

// Set the work directory for NPM
npmWorkDir = file("${project.buildDir}/src/main/my-app/npm")

// Set the work directory where node_modules should be located
nodeModulesDir = file("${project.projectDir}/src/main/my-app")
}

3. Executing npm Tasks

When adding the node plugin, you will have a npmInstall task already added. This task will execute npm install and installs all dependencies in package.json. It will only run when changes are made to package.json or node_modules. Execute it like this:

task npmInstallDependencies(type: NpmTask) {
dependsOn 'npmSetup'
execOverrides {
it.ignoreExitValue = true
it.workingDir = 'src/main/my-app'
}
args = ['install']
}

task npmBuild(type: NpmTask) {
dependsOn 'npmInstallDependencies'
execOverrides {
it.workingDir = 'src/main/my-app'
}
args = ['run', 'build']
}

task copyMyapptoBuild(type: Copy) {
dependsOn 'npmBuild'
from "$projectDir/src/main/my-app/build/"
into "$buildDir/resources/main/static"
}

processResources {
dependsOn 'copyMyapptoBuild'
}

Once you add all of the above code build the application using gradlew build and then run the spring boot application using gradlew bootrun.

Now we can test if we correctly wired everything and run it, it should now look like the following:

Now moving onto the cloud 🌫

Setting up Azure ☁

Next up we try to setup Azure so we can push / deploy our jar. This requires the following steps:

· Create Azure account & setup a “Resource Group”

· Create a new “App Service”

We’ll first need to set up an account, by registering at portal.azure.com. On registering, you should get some free amount of compute time and / or budget.

Once logged in, you can create a Resource Group. This will serve as a container for your web app and other services which you might add later.

Next, add an instance of an App Service. We’ll just use Java SE with the version we used when generating the Spring Boot App. Lastly, make sure to change the tier to a lower one to get started.

Azure is now set up and waits for a first deployment. To do this, we need to install Azure CLI, following this guide. For Windows following are the commands.

1. Run the login command where you are using your spring application

az login

If the CLI can open your default browser, it will do so and load an Azure sign-in page.

2. Sign in with your account credentials in the browser.

Deployment with Gradle Plugin 🛠

Now we need to add a plugin to deploy our jar to Azure. We make use of this GitHub Repository. We can add it in the build.gradle file:

plugins {
id "lenala.azure.azurewebapp" version "1.0.1"
}

You also need some parameters set (which match your configuration) which will help decide the plugin where to push your app:

azureWebApp {
resourceGroup = 'demo_app'
appName = 'demoSpringReact'
pricingTier = 'S1'
region = 'central-us'
appService = {
type = 'linux'
javaVersion = 'jre8'
runtimeStack = 'jre8'
}
authentication = {
type = 'azurecli'
}
deployment = {
type = "jar"
}
}

After first running gradlew bootJar and then gradlew azureWebappDeploy, we see the how the webapp is getting deployed:

Let’s have a look online on our url provided by Azure:

We just deployed our first complete web app on Azure with frontend and backend working together — pretty awesome! 😍

You can have a look at the complete code in this Github repository.

Ping me on twitter for any queries. 🤗

— — Happy Hacking 😊

If you are a student you might be interested in knowing more about Microsoft Learn Student Ambassador program. 🧐

--

--

Mohammed Abdul Mannan

A Young Tech Enthusiast | Microsoft Learn Student Ambassador | Web Developer