Manage your Java application

Introduction

This tutorial will guide you through the process of describing and deploying a Java-based workload using Score and the Humanitec Platform Orchestrator.

Prerequisites

To get started you’ll need:

  • The humctl Humanitec CLI
  • A Humanitec Organization. If you do not have one yet, sign up here for a free trial
  • A user account with the Administrator role in that Organization
  • A Kubernetes cluster connected to the Platform Orchestrator for Workload deployments. If you do not have one yet, these are your options:
Options to connect your Kubernetes cluster
Five-minute-IDP Bring your own cluster Reference architecture
Set up a local demo cluster following the Five-minute IDP

Duration: 5 min

No need to deploy the demo Workload, just perform the setup

Ephemeral (throw-away) setup for demo purposes
Connect an existing cluster by following the Quickstart up to “Connect your cluster” (guided), or using the instructions in Kubernetes (self-guided)

Duration: 15-30 min

One-time effort per cluster, can be re-used going forward
Set up the reference architecture

Duration: 15-30 min

Creates a new cluster plus supporting cloud infrastructure, and connects it to the Platform Orchestrator
  • kubectl with the current context set to your target cluster
  • (optional) Docker. Only required if you want to build the demo image yourself
  • (optional) A publicly reachable image registry to publish the demo image. You can otherwise simply use the pre-built public demo image from the ghcr.io registry

Prepare your environment

Set these environment variables:

export MY_REGISTRY=ghcr.io # Set to the name of your own registry if you are using one
export IMAGE=humanitec-tutorials/manage-your-java-app
export TAG=latest
export HUMANITEC_APP=manage-your-java-app
export HUMANITEC_ORG=<my-organization-id>

where:

Choose the Resource Definition of the target Kubernetes cluster. You can use humctl get resource-definition to get a list of available Resource Definitions, or go to the “Resource Management” section in the Platform Orchestrator UI.

export K8S_RESDEF=<my-k8s-cluster-resource-definition-id>

Clone the repository

To get started, clone the manage-your-java-app repository:

git clone https://github.com/humanitec-tutorials/manage-your-java-app.git
cd manage-your-java-app

Now that you’re in the manage-your-java-app directory, you can see the following file structure:

.github/workflows
src/main
Dockerfile
LICENSE
Makefile
README.md
pom.xml
score.yaml

Build the container image

Building and deploying a cloud-based application typically requires containerization, commonly done with Docker.

This tutorial works with a simple demo web application packaged as a .war file. It contains one servlet only and will be hosted by a Tomcat web server.

Inspect the Dockerfile

Inspect the Dockerfile provided with the cloned repository:

cat Dockerfile

The Dockerfile uses a multi-stage build so that you as a developer do not need to maintain build tooling (here: Maven) on your workstation.

The Dockerfile contains the following sections:

  • FROM maven:latest as build: Specifies a maven base image for the first stage
  • COPY . /build and WORKDIR /build: Copies the repo contents to the /build dir in the image and switches into it
  • RUN mvn clean install: Performs the Maven build of the project. It will create the .war file as /build/target/java-demo-docker-webapp-1.0.war
  • FROM tomcat:latest: Specifies a tomcat base image for the final stage. It provides a Tomcat server to serve our web application
  • COPY --from build ...: Copies the .war artefact from the previous stage and renames it. On startup, Tomcat will extract the file and serve its contents as a web application

Docker build

Execute the docker build command to build the Docker image:

docker build -t $MY_REGISTRY/$IMAGE:$TAG .

The flags represent:

  • -t $MY_REGISTRY/$IMAGE: Image name, prefixed by the registry URL if not using Docker Hub
  • :$TAG: Image tag, usually representing the release version
  • .: Directory containing the Dockerfile. “.” indicates the current directory

Docker push

Authentication via docker login is required before pushing to a registry:

echo $SECRET_PASSWORD | docker login $MY_REGISTRY -u $USERNAME --password-stdin

Push the image using the docker push command:

docker push $MY_REGISTRY/$IMAGE:$TAG

The variables represent:

  • $USERNAME: Username for the registry.
  • $SECRET_PASSWORD: Password for the registry.
  • $MY_REGISTRY/$IMAGE:$TAG: Image name and tag.

Now that your image is built and pushed to the registry, you can deploy it to your environment with Score.

Deploy with Score

Inspect the Score specification file

Inspect the score.yaml file provided with the cloned repository:

cat score.yaml

The score.yaml file contains the following sections:

  • metadata:
    • name: Defines the name of the application. We will override the value at deployment time
  • service: Defines the ports that the service exposes
  • containers: Defines the containers that make up the service
    • frontend: Defines the name of the container that will be deployed
      • image: Defines the image that will be deployed. We will override the value at deployment time

Now that your score.yaml file is ready, you can deploy your Application.

Login to the Platform Orchestrator

humctl login

Create an Application in the Platform Orchestrator

humctl create app $HUMANITEC_APP

Create matching criteria on the target Kubernetes cluster for your Application. This will make the Platform Orchestrator pick that cluster for the subsequent deployment.

export CRITERIA_ID=$(humctl api post /orgs/$HUMANITEC_ORG/resources/defs/$K8S_RESDEF/criteria \
  -d '{
  "app_id": "'${HUMANITEC_APP}'"
}' | jq --raw-output '.id' )
echo $CRITERIA_ID

We capture the CRITERIA_ID for cleaning up again later.

Deploy using Score

To deploy your application, run the following command:

humctl score deploy \
  --org $HUMANITEC_ORG \
  --app $HUMANITEC_APP \
  --env development \
  --file score.yaml \
  -p metadata.name=$HUMANITEC_APP \
  -p containers.frontend.image=$MY_REGISTRY/$IMAGE:$TAG

This command performs the following actions:

  • score deploy: Submits a Score file to the Platform Orchestrator for deployment
  • --org $HUMANITEC_ORG: Specifies your Humanitec Organization
  • --app $HUMANITEC_APP: Names the target Application in the Platform Orchestrator
  • --env development: Sets the target environment as development
  • --file score.yaml: Specifies the Score file
  • -p metadata.name: Overrides the Score file property metadata.name with your application ID
  • -p containers.frontend.image: Overrides the Score file property containers.frontend.image with the reference to your container image source

Inspect the deployment

Now that your application is deployed, inspect the result in the Platform Orchestrator.

  • Open the web UI and select Applications from the left hand navigation
  • Select the development environment of the manage-your-java-app Application.
  • Select the manage-your-java-app Workload
  • Select the frontend container

You should see the container logs showing the startup messages of the Tomcat server.

Access your application

To keep things simple, this tutorial did not have you set up any ingress for accessing the web application. You did, however, deploy a Kubernetes Service through the service spec in the Score file. We can use this service as a target for a kubectl port forwarding from your local workstation.

First obtain the namespace of the service:

export APP_NAMESPACE=$(kubectl get service -A \
  -l app.kubernetes.io/name=$HUMANITEC_APP \
  -o custom-columns=NAME:metadata.namespace \
  --no-headers)

echo $APP_NAMESPACE

Create a port forwarding to the service:

kubectl port-forward service/manage-your-java-app 8080:8080 \
  -n $APP_NAMESPACE

Open this URL in your browser: http://localhost:8080/java-demo-docker-webapp/hello?greets=deployer

You should see the message “Hello deployer!” served to you by your Java web application.

Quit the port forwarding via Cmd-C or Ctrl-C.

As you make code changes, simply rebuild the Docker image with the new tag, push it to the image registry, and run humctl score deploy again to deploy the latest version. This will require you to use your own registry.

The Platform Orchestrator will automatically roll out the new image and restart containers. This allows for fully automated, continuous deployment of your application.

Deploy with your CI pipeline (optional)

If you already have a CI pipeline producing a container image for your Java application, you can easily extend it to perform an automated deployment via Score and the Platform Orchestator just like you now performed it.

  • Add a Score file to your repository
  • Make the humctl CLI available to the pipeline runner
  • Add a pipeline step performing a humctl score deploy command as seen in the Deploy using Score step above, providing the required parameters on the target Application and Environment as well as the newly generated image tag and version.

For more information, refer to CI/CD integration.

Cleaning up

Delete the Application from the Platform Orchestrator. This will make the Orchestrator un-deploy the Workload from the cluster.

humctl delete app $HUMANITEC_APP

Delete the matching criteria on the cluster Resource Definition:

humctl api delete /orgs/${HUMANITEC_ORG}/resources/defs/${K8S_RESDEF}/criteria/${CRITERIA_ID}

Recap

In this tutorial, you learned how to:

  • Build a container image from a Java application
  • Create a Score file describing your containerized Workload
  • Deploy the Workload using Score, the Humanitec Platform Orchestrator, and the humctl CLI
  • Automate deployments using a CI pipeline

Next steps

Now that you have deployed a standalone Workload, explore how to work with dependent Resources in Score:

Top