Deploying a Java based application using Docker and kubernetes using Minikube.
- Nishant Nath
- Oct 21, 2023
- 5 min read
1. Installing Docker & Kubernetes on an Ubuntu AWS EC2 Machine:
Minikube is local Kubernetes, focusing on making it easy to learn and develop for Kubernetes. Launch an EC2 instance (t2-medium) with SSH and Inbound port for the application and make sure to have:
2GB of free memory
2 CPUs or more
20GB of free disk space
git installed

Make sure you have Docker installed on your Ubuntu machine. If not, you can install it using the following command:
sudo apt-get update
sudo apt-get install docker.ioInstall kubectl: You need to have kubectl installed to interact with the Kubernetes cluster created by Minikube. You can install kubectl using the following command:
sudo snap install kubectl --classicInstall Minikube: You can install Minikube on Ubuntu using a package manager like curl or by downloading the binary. Here's how to install it using curl:
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 && chmod +x minikube && sudo mv minikube /usr/local/bin/ Run the following command to add your user to the "docker" group:
sudo usermod -aG docker $USERThis command appends your user to the "docker" group, where $USER is your username.After adding your user to the "docker" group, you need to apply the group changes to your current session.
newgrp docker Now, you should be able to start Minikube with the Docker driver:
minikube start --driver=dockerThis command will download and run a Docker container with the Minikube Kubernetes cluster inside.
Verify Minikube: After the Minikube cluster is up and running, you can verify its status with status command. It should display that the cluster is running.
minikube statusTo see the kubectl configuration use the command:
kubectl config viewapiVersion: v1
clusters:
- cluster:
certificate-authority: /home/ubuntu/.minikube/ca.crt
extensions:
- extension:
last-update: Sat, 21 Oct 2023 07:01:05 UTC
provider: minikube.sigs.k8s.io
version: v1.31.2
name: cluster_info
server: https://192.168.49.2:8443
name: minikube
contexts:
- context:
cluster: minikube
extensions:
- extension:
last-update: Sat, 21 Oct 2023 07:01:05 UTC
provider: minikube.sigs.k8s.io
version: v1.31.2
name: context_info
namespace: default
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: /home/ubuntu/.minikube/profiles/minikube/client.crt
client-key: /home/ubuntu/.minikube/profiles/minikube/client.key
To show the cluster information:
kubectl cluster-infoKubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyTo check running nodes use the following command:
kubectl get nodesubuntu@ip-172-31-81-209:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 25m v1.27.4To ssh into the Minikube VM:
minikube sshubuntu@ip-172-31-81-209:~$ minikube ssh
docker@minikube:~$ 2. Our Java Application:
Repository: https://github.com/shazforiot/docker-Java-kubernetes-project
Microservice Application tree:
├── README.md
├── kubernetes
│ ├── productcatalogue-service.yaml
│ ├── shopfront-service.yaml
│ └── stockmanager-service.yaml
├── productcatalogue
│ ├── Dockerfile
│ ├── pom.xml
│ ├── product-catalogue.yml
│ └── src
├── shopfront
│ ├── Dockerfile
│ ├── pom.xml
│ └── src
└── stockmanager
| ├── Dockerfile
| ├── pom.xml
| └── src3. Let's Install the dependencies:
a. Install maven
apt-get install maven -yb. Set the maven home as a variable
export MAVEN_HOME=/usr/share/mavenubuntu@ip-172-31-81-209:~ echo $MAVEN_HOME
/usr/share/mavenc. Build the image for micro-service shopfront
cd shopfrontubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ ls
Dockerfile pom.xml src4. Let's Build and Push the images to DockerHub for each services
a. Now run mvn clean install from inside that folder so it can build part of our microservice
mvn clean install mvn clean install
[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/springframework/boot/spring-boot-starter-parent/1.5.22.RELEASE/spring-boot-starter-parent-1.5.22.RELEASE.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 29.019 s
[INFO] Finished at: 2023-10-21T10:26:50Z
[INFO] ------------------------------------------------------------------------Now if we do ls we will see <target> directory where we have shopfront-0.0.1-SNAPSHOT.jar
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ ls
Dockerfile pom.xml src target
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ cd target/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront/target$ ls
classes generated-test-sources maven-status shopfront-0.0.1-SNAPSHOT.jar.original test-classes
generated-sources maven-archiver shopfront-0.0.1-SNAPSHOT.jar surefire-reportsb. Create the docker image
docker build -t <dockerhub-username>/<image-name>:tag .docker build -t nishant277/shopfront:latest .ubuntu@ip-172-31-81-209:~/java-docker-k8s/shopfront$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nishant277/shopfront latest e71412eef061 3 minutes ago 320MBc. Let's do the same build process for productcatalogue micro-service now
ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd productcatalogue/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ ls
Dockerfile pom.xml product-catalogue.yml src
ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$mvn clean installubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ ls
Dockerfile pom.xml product-catalogue.yml src targetdocker build -t nishant277/productcatalogue:latest .ubuntu@ip-172-31-81-209:~/java-docker-k8s/productcatalogue$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nishant277/productcatalogue latest ce435c338475 6 seconds ago 291MB
nishant277/shopfront latest e71412eef061 9 minutes ago 320MBd. Let's do the same build process for last micro-service stockmanager now
ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd stockmanager/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ ls
Dockerfile pom.xml srcmvn clean installubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ ls
Dockerfile build pom.xml src targetdocker build -t nishant277/stockmanager:latest .Now if we check we have 3 images for each services
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nishant277/stockmanager latest 1b88249cb428 4 seconds ago 317MB
nishant277/productcatalogue latest ce435c338475 3 minutes ago 291MB
nishant277/shopfront latest e71412eef061 12 minutes ago 320MBe. Let's push the images to the dockerhub
ubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: nishant277
Password:
WARNING! Your password will be stored unencrypted in /home/ubuntu/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeededubuntu@ip-172-31-81-209:~/java-docker-k8s/stockmanager$ docker push nishant277/stockmanager
Using default tag: latest
The push refers to repository [docker.io/nishant277/stockmanager]
d88146d4d2f1: Pushed
1aaddf64804f: Mounted from library/openjdk f. Push all the respective images to the DockerHub.

5. Let's deploy the services to our K8s cluster
ubuntu@ip-172-31-81-209:~/java-docker-k8s$ cd kubernetes/
ubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$Our manifest files for each services
ubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$ ls
productcatalogue-service.yaml shopfront-service.yaml stockmanager-service.yamlubuntu@ip-172-31-81-209:~/java-docker-k8s/kubernetes$ kubectl apply -f shopfront-service.yaml
service/shopfront created
deployment.apps/shopfront createdubuntu@ip-172-31-89-196:~/java-docker-k8s/kubernetes$ kubectl apply -f productcatalogue-service.yaml
service/productcatalogue unchanged
deployment.apps/productcatalogue createdLet's test the application inside the cluster by doing ssh
minikube sshminikube ssh
docker@minikube:ubuntu@ip-172-31-89-196:~ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h18m
shopfront NodePort 10.105.228.45 <none> 8010:32683/TCP 151mNow we will test the application inside the container
docker@minikube:~$ curl http://192.168.49.2:32683
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Welcome to the Docker Java Shopfront!</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous" />
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container-fluid" style="background-color: #ff203b">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Docker Java Shopfront</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="#">Help</a></li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<div class="col-sm-3 col-md-2 sidebar">
<ul class="nav nav-sidebar">
<li class="active"><a href="#">Overview <span class="sr-only">(current)</span></a></li>
</ul>
</div>
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<h1 class="page-header">Welcome to the Docker Java Shopfront!</h1>
<h2 class="sub-header">Please select a product!</h2>
<div class="table-responsive">
<table class="table table-striped" id="product-table">
<thead>
<tr>
<th>Product Num</th>
<th>SKU</th>
<th>Name</th>
<th>Description</th>
<th>Price £</th>
<th>Qty Available</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>default</td>
<td>Widget</td>
<td>Premium ACME Widgets</td>
<td>1.20</td>
<td>999</td>
</tr>
<tr>
<td>2</td>
<td>default</td>
<td>Sprocket</td>
<td>Grade B sprockets</td>
<td>4.10</td>
<td>999</td>
</tr>
<tr>
<td>3</td>
<td>default</td>
<td>Anvil</td>
<td>Large Anvils</td>
<td>45.50</td>
<td>999</td>
</tr>
<tr>
<td>4</td>
<td>default</td>
<td>Cogs</td>
<td>Grade Y cogs</td>
<td>1.80</td>
<td>999</td>
</tr>
<tr>
<td>5</td>
<td>default</td>
<td>Multitool</td>
<td>Multitools</td>
<td>154.10</td>
<td>999</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>docker@minikube:~$
Test the application (local minikube)
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4h8m
productcatalogue NodePort 10.105.98.100 <none> 8020:30139/TCP 35m
shopfront NodePort 10.105.228.45 <none> 8010:32683/TCP 3h21mminikube service productcatalogue




Comments