Deploying Spring Boot

A reference of Spring Boot deployment strategies

Published: 6/25/2025

This section walks through deploying a simple Java Spring Boot app to Azure Web App. Firstly we create the Azure service, then we have the app deploy on push to the main repo branch. The GitHub actions build and test the app, then deploy it to Azure.

Note: Be sure to have something at the app root <yourapp>.azurewebsites.net/, which is important for app health checking. For example:

@RestController
public class HealthController {
    @GetMapping("/")
    public String index() {
        return "OK";
    }
}

https://portal.azure.com/ App Services -> Create -> Web App

  • Basics:
    • Resource Group: DefaultResourceGroupEAU
    • Name: yourapp
    • Publish: Code
    • Runtime stack: Java 21
    • Java web server stack: Java SE (Embedded Web Server)
    • Operating System: Linux
    • Region: Australia East
  • Deployment
    • Basic authentication: Enable

Navigate to the App in App Services

  • Configuration
    • Startup Command: java -jar /home/site/wwwroot/app.jar
# Run from the Azure Cloud shell
az ad sp create-for-rbac --name "github-deploy" --role contributor \
  --scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP_NAME> \
  --sdk-auth
// Example response format
{
  "clientId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "clientSecret": "your-secret",
  "subscriptionId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenantId": "xxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
  "resourceManagerEndpointUrl": "https://management.azure.com/",
  ...
}

Copy this response.

GitHub repo -> Settings -> Security -> Secrets and variables -> Actions

New respository secret:

  • Name: AZURE_CREDENTIALS
  • Secret: paste the response

At the root of the repo.

mkdir .github/workflows
touch .github/workflows/deploy-jar.yml
name: Build and deploy JAR app to Azure Web App

env:
  AZURE_WEBAPP_NAME: yourapp
  JAVA_VERSION: '21'
  WORKING_DIRECTORY: ./YourApp # or, ./

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Java version
        uses: actions/setup-java@v4
        with:
          java-version: ${{ env.JAVA_VERSION }}
          distribution: 'temurin'
          cache: 'gradle'

      - name: Build JAR
        working-directory: ${{ env.WORKING_DIRECTORY }}
        run: ./gradlew bootJar

      - name: Run tests
        working-directory: ${{ env.WORKING_DIRECTORY }}
        run: ./gradlew test

      - name: Upload artifact for deployment job
        uses: actions/upload-artifact@v4
        with:
          name: java-app
          path: ${{ env.WORKING_DIRECTORY }}/build/libs/*.jar 

  deploy:
    runs-on: ubuntu-latest
    needs: build
    
    # Show deployment URL in the Actions logs
    environment:
      name: 'production'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v4
        with:
          name: java-app
          path: java-app

      - name: List downloaded files
        run: ls -R

      # Login using Azure credentials
      - name: Log in to Azure
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy to Azure Web App
        id: deploy-to-webapp
        uses: azure/webapps-deploy@85270a1854658d167ab239bce43949edb336fa7c
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          package: java-app/*.jar
# Delete a resource group
az group delete --name my-resource-group --yes
# List subscriptions
az account list --all --output table
# Then switch a subscription
az account set --subscription "Azure subscription 1"