Deploy a Spring Boot app using the Fabric8 Maven Plugin

Fabric8 is an open-source solution that is built on Kubernetes, which helps developers create applications in Linux containers.

This tutorial walks you through using the Fabric8 plugin for Maven to develop to deploy an application to a Linux host in the Azure Container Service (AKS).

Prerequisites

In order to complete the steps in this tutorial, you need to have the following prerequisites:

Note

Due to the virtualization requirements of this tutorial, you cannot follow the steps in this article on a virtual machine; you must use a physical computer with virtualization features enabled.

Create the Spring Boot on Docker Getting Started web app

The following steps walk you through building a Spring Boot web application and testing it locally.

  1. Open a command-prompt and create a local directory to hold your application, and change to that directory; for example:

    md /home/GenaSoto/SpringBoot
    cd /home/GenaSoto/SpringBoot
    

    -- or --

    md C:\SpringBoot
    cd C:\SpringBoot
    
  2. Clone the Spring Boot on Docker Getting Started sample project into the directory.

    git clone https://github.com/spring-guides/gs-spring-boot-docker.git
    
  3. Change directory to the completed project; for example:

    cd gs-spring-boot-docker/complete
    

    -- or --

    cd gs-spring-boot-docker\complete
    
  4. Use Maven to build and run the sample app.

    mvn clean package spring-boot:run
    
  5. Test the web app by browsing to http://localhost:8080, or with the following curl command:

    curl http://localhost:8080
    

    You should see a Hello Docker World message displayed.

    Browse sample application locally

Install the Kubernetes command-line interface and create an Azure resource group using the Azure CLI

  1. Open a command prompt.

  2. Type the following command to log in to your Azure account:

    az login
    

    Follow the instructions to complete the login process

    The Azure CLI will display a list of your accounts; for example:

    [
      {
        "cloudName": "AzureCloud",
        "id": "00000000-0000-0000-0000-000000000000",
        "isDefault": false,
        "name": "Windows Azure MSDN - Visual Studio Ultimate",
        "state": "Enabled",
        "tenantId": "00000000-0000-0000-0000-000000000000",
        "user": {
          "name": "Gena.Soto@wingtiptoys.com",
          "type": "user"
        }
      }
    ]
    
  3. If you do not already have the Kubernetes command-line interface (kubectl) installed, you can install using the Azure CLI; for example:

    az acs kubernetes install-cli
    

    Note

    Linux users may have to prefix this command with sudo since it deploys the Kubernetes CLI to /usr/local/bin.

    If you already have kubectl) installed and your version of kubectl is too old, you may see an error message similar to the following example when you attempt to complete the steps listed later in this article:

    error: group map[autoscaling:0x0000000000 batch:0x0000000000 certificates.k8s.io
    :0x0000000000 extensions:0x0000000000 storage.k8s.io:0x0000000000 apps:0x0000000
    000 authentication.k8s.io:0x0000000000 policy:0x0000000000 rbac.authorization.k8
    s.io:0x0000000000 federation:0x0000000000 authorization.k8s.io:0x0000000000 comp
    onentconfig:0x0000000000] is already registered
    

    If this happens, you will need to reinstall kubectl to update your version.

  4. Create a resource group for the Azure resources that you will use in this tutorial; for example:

    az group create --name=wingtiptoys-kubernetes --location=westeurope
    

    Where:

    • wingtiptoys-kubernetes is a unique name for your resource group
    • westeurope is an appropriate geographic location for your application

    The Azure CLI will display the results of your resource group creation; for example:

    {
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/wingtiptoys-kubernetes",
      "location": "westeurope",
      "managedBy": null,
      "name": "wingtiptoys-kubernetes",
      "properties": {
        "provisioningState": "Succeeded"
      },
      "tags": null
    }
    

Create a Kubernetes cluster using the Azure CLI

  1. Create a Kubernetes cluster in your new resource group; for example:

    az acs create --orchestrator-type kubernetes --resource-group wingtiptoys-kubernetes --name wingtiptoys-cluster --generate-ssh-keys --dns-prefix=wingtiptoys
    

    Where:

    • wingtiptoys-kubernetes is the name of your resource group from earlier in this article
    • wingtiptoys-cluster is a unique name for your Kubernetes cluster
    • wingtiptoys is a unique name DNS name for your application

    The Azure CLI will display the results of your cluster creation; for example:

    {
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/wingtiptoys-kubernetes/providers/Microsoft.Resources/deployments/azurecli0000000000.00000000000",
      "name": "azurecli0000000000.00000000000",
      "properties": {
        "correlationId": "00000000-0000-0000-0000-000000000000",
        "debugSetting": null,
        "dependencies": [],
        "mode": "Incremental",
        "outputs": {
          "masterFQDN": {
            "type": "String",
            "value": "wingtiptoysmgmt.westeurope.cloudapp.azure.com"
          },
          "sshMaster0": {
            "type": "String",
            "value": "ssh azureuser@wingtiptoysmgmt.westeurope.cloudapp.azure.com -A -p 22"
          }
        },
        "parameters": {
          "clientSecret": {
            "type": "SecureString"
          }
        },
        "parametersLink": null,
        "providers": [
          {
            "id": null,
            "namespace": "Microsoft.ContainerService",
            "registrationState": null,
            "resourceTypes": [
              {
                "aliases": null,
                "apiVersions": null,
                "locations": [
                  "westeurope"
                ],
                "properties": null,
                "resourceType": "containerServices"
              }
            ]
          }
        ],
        "provisioningState": "Succeeded",
        "template": null,
        "templateLink": null,
        "timestamp": "2017-09-15T01:00:00.000000+00:00"
      },
      "resourceGroup": "wingtiptoys-kubernetes"
    }
    
  2. Download your credentials for your new Kubernetes cluster; for example:

    az acs kubernetes get-credentials --resource-group=wingtiptoys-kubernetes --name wingtiptoys-cluster
    
  3. Verify your connection with the following command:

    kubectl get nodes
    

    You should see a list of nodes and statuses like the following example:

    NAME                    STATUS                     AGE       VERSION
    k8s-agent-00000000-0    Ready                      5h        v1.6.6
    k8s-agent-00000000-1    Ready                      5h        v1.6.6
    k8s-agent-00000000-2    Ready                      5h        v1.6.6
    k8s-master-00000000-0   Ready,SchedulingDisabled   5h        v1.6.6
    

Create a private Azure container registry using the Azure CLI

  1. Create a private Azure container registry in your resource group to host your Docker image; for example:

    az acr create --admin-enabled --resource-group wingtiptoys-kubernetes --location westeurope --name wingtiptoysregistry --sku Basic
    

    Where:

    Parameter Description
    wingtiptoys-kubernetes Specifies the name of your resource group from earlier in this article.
    wingtiptoysregistry Specifies a unique name for your private registry.
    westeurope Specifies an appropriate geographic location for your application.

    The Azure CLI will display the results of your registry creation; for example:

    {
      "adminUserEnabled": true,
      "creationDate": "2017-09-15T01:00:00.000000+00:00",
      "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/wingtiptoys-kubernetes/providers/Microsoft.ContainerRegistry/registries/wingtiptoysregistry",
      "location": "westeurope",
      "loginServer": "wingtiptoysregistry.azurecr.io",
      "name": "wingtiptoysregistry",
      "provisioningState": "Succeeded",
      "resourceGroup": "wingtiptoys-kubernetes",
      "sku": {
        "name": "Basic",
        "tier": "Basic"
      },
      "storageAccount": {
        "name": "wingtiptoysregistr000000"
      },
      "tags": {},
      "type": "Microsoft.ContainerRegistry/registries"
    }
    
  2. Retrieve the password for your container registry from the Azure CLI.

    az acr credential show --name wingtiptoysregistry --query passwords[0]
    

    The Azure CLI will display the password for your registry; for example:

    {
      "name": "password",
      "value": "AbCdEfGhIjKlMnOpQrStUvWxYz"
    }
    
  3. Navigate to the configuration directory for your Maven installation (default ~/.m2/ or C:\Users\username.m2) and open the settings.xml file with a text editor.

  4. Add your Azure Container Registry URL, username and password to a new <server> collection in the settings.xml file. The id and username are the name of the registry. Use the password value from the previous command (without quotes).

    <servers>
       <server>
          <id>wingtiptoysregistry.azurecr.io</id>
          <username>wingtiptoysregistry</username>
          <password>AbCdEfGhIjKlMnOpQrStUvWxYz</password>
       </server>
    </servers>
    
  5. Navigate to the completed project directory for your Spring Boot application (for example, "C:\SpringBoot\gs-spring-boot-docker\complete" or "/home/GenaSoto/SpringBoot/gs-spring-boot-docker/complete"), and open the pom.xml file with a text editor.

  6. Update the <properties> collection in the pom.xml file with the login server value for your Azure Container Registry.

    <properties>
       <docker.image.prefix>wingtiptoysregistry.azurecr.io</docker.image.prefix>
       <java.version>1.8</java.version>
    </properties>
    
  7. Update the <plugins> collection in the pom.xml file so that the <plugin> contains the login server address and registry name for your Azure Container Registry.

    <plugin>
      <groupId>com.spotify</groupId>
      <artifactId>dockerfile-maven-plugin</artifactId>
      <version>1.3.4</version>
      <configuration>
        <repository>${docker.image.prefix}/${project.artifactId}</repository>
        <serverId>${docker.image.prefix}</serverId>
        <registryUrl>https://${docker.image.prefix}</registryUrl>
      </configuration>
    </plugin>
    
  8. Navigate to the completed project directory for your Spring Boot application, and run the following Maven command to build the Docker container and push the image to your registry:

    mvn package dockerfile:build -DpushImage
    

    Maven will display the results of your build; for example:

    [INFO] ----------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ----------------------------------------------------
    [INFO] Total time: 38.113 s
    [INFO] Finished at: 2017-09-15T02:00:00-07:00
    [INFO] Final Memory: 47M/338M
    [INFO] ----------------------------------------------------
    

Configure your Spring Boot app to use the Fabric8 Maven plugin

  1. Navigate to the completed project directory for your Spring Boot application, (for example: "C:\SpringBoot\gs-spring-boot-docker\complete" or "/home/GenaSoto/SpringBoot/gs-spring-boot-docker/complete"), and open the pom.xml file with a text editor.

  2. Update the <plugins> collection in the pom.xml file to add the Fabric8 Maven plugin:

    <plugin>
      <groupId>io.fabric8</groupId>
      <artifactId>fabric8-maven-plugin</artifactId>
      <version>3.5.30</version>
      <configuration>
        <ignoreServices>false</ignoreServices>
        <registry>${docker.image.prefix}</registry>
      </configuration>
    </plugin>
    
  3. Navigate to the main source directory for your Spring Boot application, (for example: "C:\SpringBoot\gs-spring-boot-docker\complete\src\main" or "/home/GenaSoto/SpringBoot/gs-spring-boot-docker/complete/src/main"), and create a new folder named "fabric8".

  4. Create three YAML fragment files in the new fabric8 folder:

    a. Create a file named deployment.yml with the following contents:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: ${project.artifactId}
      labels:
        run: gs-spring-boot-docker
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: gs-spring-boot-docker
      strategy:
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 1
        type: RollingUpdate
      template:
        metadata:
          labels:
            run: gs-spring-boot-docker
        spec:
          containers:
          - image: ${docker.image.prefix}/${project.artifactId}:latest
            name: gs-spring-boot-docker
            imagePullPolicy: Always
            ports:
            - containerPort: 8080
          imagePullSecrets:
            - name: mysecrets
    

    b. Create a file named secrets.yml with the following contents:

    apiVersion: v1
    kind: Secret
    metadata:
      name: mysecrets
      namespace: default
      annotations:
        maven.fabric8.io/dockerServerId:  ${docker.image.prefix}
    type: kubernetes.io/dockercfg
    

    c. Create a file named service.yml with the following contents:

    apiVersion: v1
    kind: Service
    metadata:
      name: ${project.artifactId}
      labels:
        expose: "true"
    spec:
      ports:
      - port: 80
        targetPort: 8080
      type: LoadBalancer
    
  5. Run the following Maven command to build the Kubernetes resource list file:

    mvn fabric8:resource
    

    This command merges all Kubernetes resource yaml files under the src/main/fabric8 folder to a YAML file that contains a Kubernetes resource list, which can be applied to Kubernetes cluster directly or export to a helm chart.

    Maven will display the results of your build; for example:

    [INFO] ----------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ----------------------------------------------------
    [INFO] Total time: 16.744 s
    [INFO] Finished at: 2017-09-15T02:35:00-07:00
    [INFO] Final Memory: 30M/290M
    [INFO] ----------------------------------------------------
    
  6. Run the following Maven command to apply the resource list file to your Kubernetes cluster:

    mvn fabric8:apply
    

    Maven will display the results of your build; for example:

    [INFO] ----------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ----------------------------------------------------
    [INFO] Total time: 14.814 s
    [INFO] Finished at: 2017-09-15T02:41:00-07:00
    [INFO] Final Memory: 35M/288M
    [INFO] ----------------------------------------------------
    
  7. Once the app is deployed to the cluster, query the external IP address using the kubectl application; for example:

    kubectl get svc -w
    

    kubectl will display your internal and external IP addresses; for example:

    NAME                    CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    kubernetes              10.0.0.1     <none>        443/TCP        19h
    gs-spring-boot-docker   10.0.242.8   13.65.196.3   80:31215/TCP   3m
    

    You can use the external IP address to open your application in a web browser.

    Browse sample application externally

Delete your Kubernetes cluster

When your Kubernetes cluster is no longer needed, you can use the az group delete command to remove the resource group, which will remove all of its related resources; for example:

az group delete --name wingtiptoys-kubernetes --yes --no-wait

Next steps

To learn more about Spring and Azure, continue to the Spring on Azure documentation center.

Additional Resources

For more information about using Spring Boot applications on Azure, see the following articles:

For more information about using Azure with Java, see the Azure for Java Developers and the Working with Azure DevOps and Java.

For further details about the Spring Boot on Docker sample project, see Spring Boot on Docker Getting Started.

For help with getting started with your own Spring Boot applications, see the Spring Initializr at https://start.spring.io/.

For more information about getting started with creating a simple Spring Boot application, see the Spring Initializr at https://start.spring.io/.

For additional examples for how to use custom Docker images with Azure, see Using a custom Docker image for Azure Web App on Linux.