Deploy and Running a Spring Boot App on Kubernetes in Windows

Deploy and Running a Spring Boot App on Kubernetes in Windows

Learn more about running Spring Boot applications on Kubernetes in Windows.

This is part one of the series "Running a Spring Boot Application on Kubernetes Minikube in Windows." This article assumes that the reader has previous experience with Spring Boot, containers, and Kubernetes. I will try and touch upon all of them in this post. After finishing this series, the reader will be able to:

1.    Create a Spring Boot application

2.   Create a Docker image for the application and store the image on Docker Hub

3.    Install minikube on your Windows Workstation and run the Spring Boot Docker image in it

In the first part of this series, we will be creating a Spring Boot application and dockerizing it. We are assuming that the workstation to be used has Windows 10 or higher, at least 8 GB RAM and 100 GB hard disk. Let's get started!

Creating a Spring Boot Application

The following sections provide steps to create a Spring Boot app with RESTful services. Check it out.

An Introduction to Spring Boot

Spring Boot is Spring's solution to the convention-over-configuration paradigm where we need rapid application development for production-grade, Spring-based applications. Spring Boot takes care of many configurations, thereby allowing the developer to focus mostly on the code.

Spring Boot provides an in-built Tomcat engine to run web applications inside the Spring Boot sandbox itself, instead of relying on third-party application server deployment for a developer workstation. It also provides the concept of parent dependency. If you add one parent dependency to your project build file, like build.gradle (Gradle projects) or pom.xml (Maven projects), Spring Boot takes care of adding the cache of dependant libraries for the parent.

Creating Your Spring Boot Application

To create a Spring Boot application, you must have Java 8+ installed and either the Maven or Gradle build tool. You must have one IDE installed as well.

For this project, I am using Java 8, Maven and IntelliJ IDEA: Community Edition for my IDE.

The easiest way to create a Spring Boot application from scratch is to use the Spring Boot Starter. If you visit the Spring Boot Starter project, you should be able to create the structure of your project with a basic folder structure — one Spring Boot Starter Main class and a required build file. Your build file will either be a build.gradle or a pom.xml based on the project type you chose.

In the artifact section and group section, enter the details as required. In the dependency section, choose the Spring dependency. And lastly, for the demo project, I choose Spring Web as it would be a RESTful web application

After adding dependencies, click on the "Generate -Ctrl +" button. Your project will be downloaded as a .zip file. Extract the .zip file in a workspace folder. You could extract it in C:\Users[username]\workspace folder.  Next, start IntelliJ IDEA. IntelliJ may ask you to open a project. Choose your project root folder to open the project in the IDE.

The project will have a, pom.xml, and mvnw.cmd file. The structure will look similar to the image below if you opened it in IntelliJ IDEA.

Now, we need to create a few more files to make it a web application.

POJO Class Kube

Create one file, as shown below, in the com.example.minikube.demo.kubedemo package.

package com.example.minikube.demo.kubedemo; import; import java.util.Objects; public class Kube implements Serializable { private String name; private float length; private float breadth; private float height; private long id; public Kube(String name, float length, float breadth, float height) { = name; this.length = length; this.breadth = breadth; this.height = height; } public Kube() { } @Override public String toString() { return "Kube{" + "name='" + name + '\'' + ", length=" + length + ", breadth=" + breadth + ", height=" + height + ", id=" + id + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Kube kube = (Kube) o; return, length) == 0 &&, breadth) == 0 &&, height) == 0 && id == && Objects.equals(name,; } @Override public int hashCode() { return Objects.hash(name, length, breadth, height, id); } public long getId() { return id; } public void setId(long id) { = id; } public String getName() { return name; } public void setName(String name) { = name; } public float getLength() { return length; } public void setLength(float length) { this.length = length; } public float getBreadth() { return breadth; } public void setBreadth(float breadth) { this.breadth = breadth; } public float getHeight() { return height; } public void setHeight(float height) { this.height = height; } }

REST Controller

Now, we would like to add one Spring REST Controller to support our CRUD RESTful operations. The filename will be

package com.example.minikube.demo.kubedemo; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.HashMap; @RestController public class KubeController { private HashMap<Long,Kube> repository = new HashMap<Long,Kube>(); private long localId = 0l; @GetMapping public ResponseEntity index(){ return new ResponseEntity(repository.values(), HttpStatus.OK); } @GetMapping("{id}") public ResponseEntity get(@PathVariable Long id){ return new ResponseEntity(repository.get(id),HttpStatus.OK); } @PostMapping public String create(@RequestBody Kube kube){ kube.setId(++localId); repository.put(kube.getId(),kube); return "Kube "+kube+" Created"; } @PutMapping("{id}") public ResponseEntity update(@RequestBody Kube kube, @PathVariable Long id){ if(repository.containsKey(id)){ kube.setId(id); repository.replace(id,kube); } return new ResponseEntity(kube,HttpStatus.OK); } @DeleteMapping("{id}") public String remove(@PathVariable Long id){ repository.remove(id); return "Kube having ID = "+id+ " is removed"; } }

Validation for the RESTful Application

Since we are done creating the REST service, we need to validate whether or not the service is working correctly. It involves starting the application and making a call to the RESTful services using the cURL or postman tool. cURL is a command-line tool that makes HTTP calls, whereas postman is a desktop tool used to test RESTful services. I will be using cURL for my tests.

Starting the Application

To start the application, open a command prompt and make your project root folder as your current directory. Type the command mvnw spring-boot:run. This would start the application at port 8080. You could see the successful start-up message in the command prompt in a few seconds.

Validating RESTful Services

The REST API has five endpoints: 2 GET(1 for a list and 1 for by ID) and 1 POST, PUT, and DELETE each.


Give the following command in the command prompt. It would create one Kube object. If you repeat the command by changing the values in the JSON input section, it would create multiple Kube Objects.

curl -H "Content-Type: application/json" -X POST -d {\"name\":\"triangle\",\"length\":8.5,\"breadth\":2.5,\"height\":4.5} http://localhost:8080/


The GET command for a list and GET for ID will be as follows:

GET all - curl http://localhost:8080 GET By ID - curl http://localhost:8080/1


the PUT command is used to update one object.

curl -H "Content-Type: application/json" -X PUT -d {\"name\":\"triangle\",\"length\":6.5,\"breadth\":3.5,\"height\":1.5} http://localhost:8080/1


The DELETE command is used to delete a Kube object by id:

curl -H "Content-Type: application/json" -X DELETE http://localhost:8080/1

We need to make a GET call after the UPDATE and DELETE calls to validate whether both the commands worked fine.


Once we have validated that the application is working fine, we need to create a Docker image and publish it to Docker hub. Check out the following steps:

  1. Create a Docker account if you have not already

  2. Install Docker Toolbox for Windows

  3. Create a Dockerfile

  4. Create a Docker image of the Spring Boot application

  5. Push the image to the Docker hub


Docker is a Platform as a Service product that enables OS-level virtualization to run applications in isolated self-dependant sandboxes called containers. Now, the container is synonymous with Docker.

Creating a Docker Account

A Docker account could be created in Docker Hub. After an account is created, create one repository under the Docker Hub. Name the repository: kube.

Install Docker Toolbox

Docker toolbox could be downloaded from the GitHub repository. Once the .exe is downloaded, it could be installed like any other .exe file. Once it is installed, start the Docker service. If the Docker service is not running, the following steps will not work.


A Dockerfile is an input to Docker on how to create an image. We need to create a file inside our Spring Boot application root project and name it Dockerfile without any extension.

FROM openjdk:8-jdk-alpine VOLUME C:\\Users\adity\\workspace COPY target/kube-demo-0.0.1-SNAPSHOT.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"]

In the above file, the volume component must be changed according to the folder structure in your work station.

Creating a Docker Image

Now, it is time to create a Docker image. First, open the command prompt and make the Spring Boot project your current directory. Give the command "mvnw package" to create the minikube-demo-0.0.1-SNAPSHOT.jar under the target folder.

After that use the docker login command to log in to Docker Hub from the command prompt. Once the Docker login is successful, we need to create the image by giving the following command:

docker build --build-arg=target\kube-demo-0.0.1-SNAPSHOT.jar -t /:kubedemo1

You need to put your correct docker user name and docker hub repository name. You could validate the image creation by using the docker images command. It will list all local Docker images present in your workstation. The output of the command is shown in the image in the section below.

Running the Docker Image

Once the Docker image is available, you can start the Spring Boot application in a Docker container using the following command.

docker run -p 8080:8080 adityapratapbhuyan/aditya-test:kubedemo1

The output for the Docker image and Docker run is shown below:

Once it is running, we can test it by giving the docker-machine IP and port. To know the docker-machine IP, type the command docker-machine ip. It will give you the IP address of the Docker container. Now, we can test the application by hitting http://docker-machine-ip:8080 instead of http://localhost:8080.

Pushing the Docker Image

The Docker image can be pushed to the Docker Hub repository with the following command:

docker push adityapratapbhuyan/aditya-test:kubedemo1

Once it is pushed to the Docker Hub, you can verify it by logging into Docker Hub. Once it is available in Docker Hub, we can pull the image in any machine and run it.

Thank you for reading !

What is the difference between Docker, Kubernetes and Docker Swarm ?

What is the difference between Docker, Kubernetes and Docker Swarm ?

What is the difference between Docker and Kubernetes? And Kubernetes or Docker Swarm? In my video "Docker vs Kubernetes vs Docker Swarm" I compare both Docker and Kubernetes and Kubernetes vs Docker Swarm.

What is the difference between Docker and Kubernetes? And Kubernetes or Docker Swarm?
In my video "Docker vs Kubernetes vs Docker Swarm" I compare both Docker and Kubernetes and Kubernetes vs Docker Swarm.

Kubernetes and Docker are not competing technologies. In fact, they actually complement one another to get the best out of both. In contrast, Docker Swarm is the comparable technology to Kubernetes.

  • 0:38 - Comparison Docker and Kubernetes
  • 1:40 - Docker and Kubernetes in the software development process
  • 2:42 - Kubernetes in Detail
  • 3:21 - Differences of Kubernetes and Docker Swarm

WordPress in Docker. Part 1: Dockerization

WordPress in Docker. Part 1: Dockerization

This entry-level guide will tell you why and how to Dockerize your WordPress projects.

This entry-level guide will tell you why and how to Dockerize your WordPress projects.

Dockerize Java App

Dockerize Java App

In this article, we'll provide a brief introduction to Docker and go over what it takes to containerize a Java application.

Dockerize your Java Application

A Dockerfile is a fundamental building block used when dockerizing your Java applications, and it is how you can create a Docker image that can be used to create the containers you need for automatic builds.

Introduction to Dockerfiles

Docker builds images by reading instructions from a Dockerfile. A Dockerfile is a simple text file that contains instructions that can be executed on the command line. Using docker build, you can start a build that executes all of the command-line instructions contained in the Dockerfile.

Common Dockerfile instructions start with RUNENVFROMMAINTAINERADD, and CMD, among others.

  • FROM - Specifies the base image that the Dockerfile will use to build a new image. For this post, we are using phusion/baseimage as our base image because it is a minimal Ubuntu-based image modified for Docker friendliness.

  • MAINTAINER - Specifies the Dockerfile Author Name and his/her email.

  • RUN - Runs any UNIX command to build the image.

  • ENV - Sets the environment variables. For this post, JAVA_HOME is the variable that is set.

  • CMD - Provides the facility to run commands at the start of container. This can be overridden upon executing the docker run command.

  • ADD - This instruction copies the new files, directories into the Docker container file system at specified destination.

  • EXPOSE - This instruction exposes specified port to the host machine.
Writing a Dockerfile for a simple Java application

It is not necessary to write a Dockerfile for OpenJDK in order to run a simple Java application, because you can obtain the official image of OpenJDK from the Docker Hub repository.

Let’s create a Dockerfile for the Oracle JDK, which is not available on Docker Hub.

To begin this process, create a new folder and then create a file in it named “Dockerfile” with the following content.

# Dockerfile

FROM phusion/baseimage:0.9.17

MAINTAINER Author Name <[email protected]>

1. Update the package repository

RUN echo "deb trusty main universe" > /etc/apt/sources.list

RUN apt-get -y update

2. Install python-software-properties

This enables add-apt-repository for use later in the process.

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q python-software-properties software-properties-common

3. Install Oracle Java 8

ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

RUN echo 'deb trusty main' >> /etc/apt/sources.list &&
    echo 'deb-src trusty main' >> /etc/apt/sources.list &&
  apt-key adv --keyserver --recv-keys C2518248EEA14886 &&
  apt-get update &&
  echo oracle-java${JAVA_VER}-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections &&
  apt-get install -y --force-yes --no-install-recommends oracle-java${JAVA_VER}-installer oracle-java${JAVA_VER}-set-default &&
  apt-get clean &&
  rm -rf /var/cache/oracle-jdk${JAVA_VER}-installer

4. Set Oracle Java as the default Java

RUN update-java-alternatives -s java-8-oracle

RUN echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc

5. Clean Up APT when finished

RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

6. Use baseimage-docker’s init system

CMD ["/sbin/my_init"]

View the complete Dockerfile

# Dockerfile

FROM phusion/baseimage:0.9.17

MAINTAINER Author Name <[email protected]>

RUN echo "deb trusty main universe" > /etc/apt/sources.list

RUN apt-get -y update

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y -q python-software-properties software-properties-common

ENV JAVA_HOME /usr/lib/jvm/java-8-oracle

RUN echo 'deb trusty main' >> /etc/apt/sources.list &&
    echo 'deb-src trusty main' >> /etc/apt/sources.list &&
  apt-key adv --keyserver --recv-keys C2518248EEA14886 &&
  apt-get update &&
  echo oracle-java${JAVA_VER}-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections &&
  apt-get install -y --force-yes --no-install-recommends oracle-java${JAVA_VER}-installer oracle-java${JAVA_VER}-set-default &&
  apt-get clean &&
  rm -rf /var/cache/oracle-jdk${JAVA_VER}-installer

RUN update-java-alternatives -s java-8-oracle

RUN echo "export JAVA_HOME=/usr/lib/jvm/java-8-oracle" >> ~/.bashrc

RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

CMD ["/sbin/my_init"]

Building the image from the Dockerfile

Now that we have written a Dockerfile, we can build the corresponding Docker image.

To build the image, start with the following command:

$ docker build -f Dockerfile -t demo/oracle-java:8 .
  • -f specifies the Dockerfile. This can be skipped if the filename used at the beginning of this process is Dockerfile.

  • -t specifies the name of the image. The name demo/oracle-java, and the 8 after the colon, specify the image tag. The tag 8 is used because we are using Java 8. This can be changed to any tag name that makes sense.

NOTE: Do not forget the .(dot) at the end of command; it specifies the context of the build. The .(dot) at the end of the command specifies the current directory. The files and directories of current directory will be sent to Docker daemon as a build artifact.

We have built our Java 8 image successfully, now we need to test it using sample Java application.

Testing the Image

Create a project folder and then create a file called inside this folder with following content:

public class Main
   public static void main(String[] args) {
    System.out.println("Hello, World");

Now execute the following commands from the current project directory.

  • To compile your file.
$ docker run --rm -v $PWD:/app -w /app demo/oracle-java:8 javac
  • To run your compiled Main.class file.
$ docker run --rm -v $PWD:/app -w /app demo/oracle-java:8 java Main

output should be displayed.

Hello, World 

You have seen in the above example that we used the Oracle Java image to successfully run a sample Java application.

If you need to use the OpenJDK for your application, you don’t always need to write a Dockerfile and build an image. You can use the official Docker Hub repository version of Java.

Run the following commands to run your application using OpenJDK.

$ docker run --rm -v $PWD:/app -w /app java:8 javac

$ docker run --rm -v $PWD:/app -w /app java:8 java Main

Writing a Dockerfile for a Maven-based Java application

If you’re using the OpenJDK with Maven, you don’t necessarily need to write a Dockerfile because you can use the official Docker Hub repository’s version of Maven. However, if you’re using the Oracle JDK with Maven, then you’ll need to write your own Dockerfile.

We will use the demo/oracle-jdk:8 image as our base image because we have built this image in our previous example.

1. Create the Dockerfile

# Dockerfile
FROM demo/oracle-java:8


RUN mkdir -p /usr/share/maven
  && curl -fsSL$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz
  | tar -xzC /usr/share/maven --strip-components=1
 && ln -s /usr/share/maven/bin/mvn /usr/bin/mvn

ENV MAVEN_HOME /usr/share/maven

VOLUME /root/.m2

CMD ["mvn"] 

In this Dockerfile we have used the command VOLUME. This command is used to expose to the host machine the volume from the container. We can map this volume to any host directory.

2. Build the Docker image

Build the docker image from the above Dockerfile using this command:

$ docker build -f Dockerfile -t demo/maven:3.3-jdk-8 .

This will build an image with the name of demo/maven and tag of 3.3-jdk-8. Name and tag your images clearly so that you can easily identify each image.

3. Run a test application

Run a test Maven application using this image that we created.

If you don’t have a Maven project, create one using this command:

$ docker run -it --rm -v "$PWD":/app -w /app demo/maven:3.3-jdk-8 mvn archetype:generate -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -Dinte

This will create a Maven project in the current directory under the my-app directory.

4. Build the project and test the JAR file

Go to the project directory.

$ cd my-app

Build the project.

$ docker run -it --rm -v "$PWD":/app -w /app demo/maven:3.3-jdk-8 mvn package

Test the newly compiled and packaged JAR with the following command.

$ docker run -it --rm -v "$PWD":/app -w /app demo/maven:3.3-jdk-8 java -cp target/my-app-1.0-SNAPSHOT.jar

This should print the following output:

Hello World!

Write a Dockerfile for Spring MVC web application

There are two approaches we can take for Spring-based applications.

  1. Use the existing Maven-based image as the base image and install Tomcat on it to run the web application.

  2. Use the existing Maven-based image to only compile and package the application. And then use a different Tomcat-based Docker container to deploy the application.

We’ll cover both approaches next.

Install Tomcat on the existing Maven-based image

Create an empty directory and add a Dockerfile inside it with the following content.

# Dockerfile
FROM demo/maven:3.3-jdk-8
MAINTAINER Author <[email protected]>
RUN apt-get update &&
  apt-get install -yq --no-install-recommends wget pwgen ca-certificates &&
  apt-get clean &&
  rm -rf /var/lib/apt/lists/*

1. Install Tomcat

wget -qO-${TOMCAT_MAJOR_VERSION}/v${TOMCAT_MINOR_VERSION}/bin/apache-tomcat-${TOMCAT_MINOR_VERSION}.tar.gz.md5 | md5sum -c - &&
tar zxf apache-tomcat-.tar.gz &&
  rm apache-tomcat-
.tar.gz &&
  mv apache-tomcat* tomcat

RUN mkdir /etc/service/tomcat
ADD /etc/service/tomcat/run
RUN chmod +x /*.sh
RUN chmod +x /etc/service/tomcat/run


2. Use baseimage-docker’s init system

CMD ["/sbin/my_init"]

3. Create the Tomcat admin user

Create a file called in the same directory with following content:


if [ -f /.tomcat_admin_created ]; then
  echo "Tomcat 'admin' user already created"
  exit 0

4. Generate Password

Continue to add the following script to generate a password.

PASS=${TOMCAT_PASS:-$(pwgen -s 12 1)}
_word=$( [ ${TOMCAT_PASS} ] && echo "preset" || echo "random" )

echo "=> Creating an admin user with a ${_word} password in Tomcat"
sed -i -r 's/</tomcat-users>//' ${CATALINA_HOME}/conf/tomcat-users.xml
echo '<role rolename="manager-gui"/>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '<role rolename="manager-script"/>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '<role rolename="manager-jmx"/>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '<role rolename="admin-gui"/>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '<role rolename="admin-script"/>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo "<user username="admin" password="${PASS}" roles="manager-gui,manager-script,manager-jmx,admin-gui, admin-script"/>" >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo '</tomcat-users>' >> ${CATALINA_HOME}/conf/tomcat-users.xml
echo "=> Done!"
touch /.tomcat_admin_created

echo "========================================================================"
echo "You can now configure to this Tomcat server using:"
echo ""
echo "  admin:${PASS}"
echo ""
echo "========================================================================"

This file creates the Tomcat admin user. Add one more file in the same directory named as with following content. This will call the create users file and then reload the Tomcat server.


if [ ! -f /.tomcat_admin_created ]; then

exec ${CATALINA_HOME}/bin/ run

5. Build and Test the Docker Image

Build the docker image using following command.

$ docker build -f Dockerfile -t demo/spring:maven-3.3-jdk-8 .

Test the image.

Here is the sample Spring Maven-based project that you can use for testing. You can download the zip or clone it by using the following command:

$ git clone

Go to the project directory:

$ cd spring-maven-sample

Run the following command to build and package the project:

$ docker run -it --rm -v "$PWD":/app -w /app demo/spring:maven-3.3-jdk-8 mvn clean install

The above command will create a war file at target/springwebapp.war.

Copy this war file into the Tomcat webapps directory:

$ docker run -it -d --name spring -p 8080:8080 -v "$PWD":/app demo/spring:maven-3.3-jdk-8 bash -c "cp /app/target/springwebapp.war /tomcat/webapps/ & /tomcat/bin/ run"

The above command runs a container named spring in detached mode. It also provides mapping from the Docker container port 8080 to host machine port 8080.

You can access your web application at the following url in the browser.http://localhost:8080/springwebapp/car/add.

This will show a sample form to add a car.

Since the Docker container is run in detached mode, it will keep running in the background. You can check the running container using following command:

$ docker ps

To check all running and non-running containers use this command:

$ docker ps -a

So to stop our Spring application container, we need to execute following command:

$ docker rm -vf spring
Run Spring app with a different Tomcat Docker image

Clone the same sample project:

$ git clone

Go to the project directory:

$ cd spring-maven-sample

Create a Dockerfile with following content:

# Dockerfile
FROM tomcat:8

ADD target/*.war /usr/local/tomcat/webapps/

Build and package and the project:

$ docker run -it --rm -v "$PWD":/app -w /app demo/maven:3.3-jdk-8 mvn clean install

Build the Dockerfile:

$ docker build -f Dockerfile -t demo/tomcat:8 .

Run the application by executing this command:

$ docker run --rm -p 8080:8080 demo/tomcat:8

Now you can access your web application at the following url in the browser.http://localhost:8080/springwebapp/car/add.

This will show a sample form to add a car.

To stop the application, press Ctrl + C.


In this article, we’ve covered the fundamentals of how to go about dockerizing your Java application. We went over the basics of what a Dockerfile is, and how to create a Dockerfile for a simple Java application, a Maven-based Java application, and a Spring MVC web application. We’ve also learned how to build the Dockerfiles into an image, and to run the image to launch a container.

Thanks For Visiting, Keep Visiting.

This post was originally published here