Project 10: Containerization of Java Application using Docker

Semo
8 min readJun 18, 2024

--

Task : Containerize a 3 Tier Java application.

What did I use to build this environment?

  • Visual Studio Code
  • Docker
  • Github
  • Bash

What was built?

  • Docker Images
  • Docker Containers
  • Docker volume

First, Here is some explanations for what is used for this project.

What is container?

A container is a unit of software that packages code and its dependencies so the application runs quickly and reliably across computing environments.

What is docker ?

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.

What is containerization using Docker?

Docker is a containerization solution that allows containers to be quickly and easily created. It runs on Windows, Mac OS, and Linux, and is used at Enable in both development and production.

What is the difference between containerization and Docker?

Not Exactly, docker is container-based technology and containers are just user space of the operating system. At the low level, a container is just a set of processes that are isolated from the rest of the system, running from a distinct docker image that provides all files necessary to support the processes

What are the benefits of containerization using Docker?

The benefits of Docker in building and deploying applications are many:

  • Caching a cluster of containers.
  • Flexible resource sharing.
  • Scalability — many containers can be placed in a single host.
  • Running your service on hardware that is much cheaper than standard servers.

SCENARIO:

You have a Multi Tier Application Stack or many services in an application stack you manage as operations teams, DevOps team. These services are running on VM’s, on physicals machines on your own datacenter, on operating systems or on cloud environment. In agile, we need to do regular deployment with many changes: Continuous changes.

PROBLEM:

High CapEX&OpEx

Human errors in deployment

Not compatible with microservices architecture

Resource wastage

Not portable, Environment mot in syncs

SOLUTION:

Containers (to save a lot of money)

Consumes low resource (use less resource, no operating system)

Suits very well for microservice design

Deployment are done via images

Same container images across environment

Reusable & Repeatable

Flow Execution:

Phase 1: Clone the source code and prepare the directories

Phase 2: Create Dockerfiles for the images and build the artifact

Phase 3:Build the images

Phase 4: Create Docker compose file, run the containers and Validate

Phase 1: Clone the source code and prepare the directories

For the application I need five images for below services:

  • Tomcat
  • MySQL
  • Memcached
  • RabbitMQ
  • Nginx

To start I need to clone the project github repository to my VS code

https://github.com/hkhcoder/vprofile-project

Now that the repository is cloned, I will create a directory for my docker files

mkdir docker-files
cd docker-files

Now I need to make 3 directories for my images

mkdir web app db

Now time to build the images

Phase 2: Create Dockerfiles for the images and build the artifact

1: App Image:

First I will build an image for the app, For that I need to move to the app directory and create a Dockerfile

cd app
touch dockerfile
vim dockerfile #paste the below content

FROM tomcat:8-jre11
LABEL "Project"="Vprofile"
LABEL "Author"="semo"

RUN rm -rf /usr/local/tomcat/webapps/*
COPY target/vprofile-v2.war /usr/local/tomcat/webapps/ROOT.war

EXPOSE 8080
CMD ["catalina.sh", "run"]
WORKDIR /usr/local/tomcat/
VOLUME /usr/local/tomcat/webapps

2: Mysql Image:

Same steps as the app image

cd ..
cd db
touch dockerfile
vim dockerfile #paste the below content

FROM mysql:5.7.25
LABEL "Project"="Vprofile"
LABEL "Author"="semo"
ENV MYSQL_ROOT_PASSWORD="vprodbpass"
ENV MYSQL_DATABASE="accounts"
ADD db_backup.sql /docker-entrypoint-initdb.d/db_backup.sql

I need to add another file for the Mysql backup

touch db_backup.sql
vim db_backup.sql #paste the below content

-- MySQL dump 10.13 Distrib 5.7.18, for Linux (x86_64)
--
-- Host: localhost Database: accounts
-- ------------------------------------------------------
-- Server version 5.7.18-0ubuntu0.16.10.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `role`
--

DROP TABLE IF EXISTS `role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `role` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `role`
--

LOCK TABLES `role` WRITE;
/*!40000 ALTER TABLE `role` DISABLE KEYS */;
INSERT INTO `role` VALUES (1,'ROLE_USER');
/*!40000 ALTER TABLE `role` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `user`
--

DROP TABLE IF EXISTS `user`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) DEFAULT NULL,
`userEmail` varchar(255) DEFAULT NULL,
`profileImg` varchar(255) DEFAULT NULL,
`profileImgPath` varchar(255) DEFAULT NULL,
`dateOfBirth` varchar(255) DEFAULT NULL,
`fatherName` varchar(255) DEFAULT NULL,
`motherName` varchar(255) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL,
`maritalStatus` varchar(255) DEFAULT NULL,
`permanentAddress` varchar(255) DEFAULT NULL,
`tempAddress` varchar(255) DEFAULT NULL,
`primaryOccupation` varchar(255) DEFAULT NULL,
`secondaryOccupation` varchar(255) DEFAULT NULL,
`skills` varchar(255) DEFAULT NULL,
`phoneNumber` varchar(255) DEFAULT NULL,
`secondaryPhoneNumber` varchar(255) DEFAULT NULL,
`nationality` varchar(255) DEFAULT NULL,
`language` varchar(255) DEFAULT NULL,
`workingExperience` varchar(255) DEFAULT NULL,
`password` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `user`
--

LOCK TABLES `user` WRITE;
/*!40000 ALTER TABLE `user` DISABLE KEYS */;
INSERT INTO `user` VALUES (7,'admin_vp','admin@visualpathit.com',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'$2a$11$0a7VdTr4rfCQqtsvpng6GuJnzUmQ7gZiHXgzGPgm5hkRa3avXgBLK'),(8,'WahidKhan','wahid.khan74@gmail.com',NULL,NULL,'28/03/1994','M Khan','R Khan','male','unMarried','Ameerpet,Hyderabad','Ameerpet,Hyderabad','Software Engineer','Software Engineer','Java HTML CSS ','8888888888','8888888888','Indian','english','2 ','$2a$11$UgG9TkHcgl02LxlqxRHYhOf7Xv4CxFmFEgS0FpUdk42OeslI.6JAW'),(9,'Gayatri','gayatri@gmail.com',NULL,NULL,'20/06/1993','K','L','male','unMarried','Ameerpet,Hyderabad','Ameerpet,Hyderabad','Software Engineer','Software Engineer','Java HTML CSS ','9999999999','9999999999','India','english','5','$2a$11$gwvsvUrFU.YirMM1Yb7NweFudLUM91AzH5BDFnhkNzfzpjG.FplYO'),(10,'WahidKhan2','wahid.khan741@gmail.com',NULL,NULL,'28/03/1994','M Khan','R Khan','male','unMarried','Ameerpet,Hyderabad','Ameerpet,Hyderabad','Software Engineer','Software Engineer','Java HTML CSS ','7777777777','777777777','India','english','7','$2a$11$6oZEgfGGQAH23EaXLVZ2WOSKxcEJFnBSw2N2aghab0s2kcxSQwjhC'),(11,'KiranKumar','kiran@gmail.com',NULL,NULL,'8/12/1993','K K','RK','male','unMarried','California','James Street','Software Engineer','Software Engineer','Java HTML CSS ','1010101010','1010101010','India','english','10','$2a$11$EXwpna1MlFFlKW5ut1iVi.AoeIulkPPmcOHFO8pOoQt1IYU9COU0m'),(12,'Saikumar','sai@gmail.com',NULL,NULL,'20/06/1993','Sai RK','Sai AK','male','unMarried','California','US','Software Engineer','Software Engineer','Java HTML CSS AWS','8888888111','8888888111','India','english','8','$2a$11$pzWNzzR.HUkHzz2zhAgqOeCl0WaTgY33NxxJ7n0l.rnEqjB9JO7vy'),(13,'RamSai','ram@gmail.com',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'$2a$11$6BSmYPrT8I8b9yHmx.uTRu/QxnQM2vhZYQa8mR33aReWA4WFihyGK');
/*!40000 ALTER TABLE `user` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `user_role`
--

DROP TABLE IF EXISTS `user_role`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `user_role` (
`user_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`role_id`),
KEY `fk_user_role_roleid_idx` (`role_id`),
CONSTRAINT `fk_user_role_roleid` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_user_role_userid` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `user_role`
--

LOCK TABLES `user_role` WRITE;
/*!40000 ALTER TABLE `user_role` DISABLE KEYS */;
INSERT INTO `user_role` VALUES (4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1);
/*!40000 ALTER TABLE `user_role` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

3: Web Image:

First step is to create the Dockerfile for the web Image

cd ..
cd web
touch dockerfile
vim dockerfile #paste the below content

FROM nginx
LABEL "Project"="Vprofile"
LABEL "Author"="semo"
RUN rm -rf /etc/nginx/conf.d/default.conf
COPY nginxvproapp.conf /etc/nginx/conf.d/vproapp.conf

Then create the nginxvproapp.conf file

touch nginxvproapp.conf
vim nginxvproapp.conf #paste the below content

upstream vproapp{
server vproapp:8080;
}
server{
listen 80;
location / {
proxy_pass http://vproapp;
}
}

Now the images are almost ready to be built, Just one step needed

4: Build the application artifact:

To build the artifact I will need Openjdk and maven to be installed on my machine

So I checked first if it’s the case

java -version
mvn -version

Now it’s time build the atrifact:

mvn install

After the build was completed I copied the artifact to the docker-files/app directory

Another thing, I need to make sure the containers that will be created with Docker images will comply with the settings in application.properties file as below. Otherwise application cannot run properly.

Phase 3:Build the images

1: Building app image

Time to build my images now. I will go to/docker-files/app directory and run below command:

docker build -t <docker_hub_username>/vprofileapp:V1 . 

In My case: docker build -t semo90/vprofileapp:V1 .

2: Building db image

Move to/docker-files/db directory and run below command:

docker build -t <docker_hub_username>/vprofiledb:V1 .

In My case: docker build -t semo90/vprofiledb:V1 .

3:Building web image

Move to/docker-files/web directory.Run below command:

docker build -t <docker_hub_username>/vprofileweb:V1 .

In My case: docker build -t semo90/vprofileweb:V1 .

4: Building RabbitMQ&Memcached image

I don’t need any customization for RabbitMq & Memcached images. I can directly pull from DockerHub.

docker pull memcached
docker pull rabbitmq
docker pull ngnix

All the Docker images are ready. Next I will build the containers with Docker compose.

Phase 4: Create Docker compose file, run the containers and validate

1: Docker Compose file

To run docker-compose commands, First we need to check i it’s installed

for my case it’s already installed

Now I will move to my main directory and create a file for Docker compose

touch docker-compose.yml
vim docker-compose.yml #paste the below content

version: '3.8'
services:
vprodb:
image: semo90/vprofiledb:V1
container_name: vprodb
ports:
- "3306:3306"
volumes:
- vprodbdata:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=vprodbpass
vprocache01:
image: memcached
container_name: vprocache01
ports:
- "11211:11211"
vpromq01:
image: rabbitmq
container_name: vpromq01
ports:
- "15672:157672"
environment:
- RABBITMQ_DEFAULT_USER=guest
- RABBITMQ_DEFAULT_PASS=guest
vproapp:
image: semo90/vprofileapp:V1
container_name: vproapp
ports:
- "8081:8080"
volumes:
- vproappdata:/usr/local/tomcat/webapps
vproweb:
image: semo90/vprofileweb:V1
container_name: vproweb
ports:
- "80:80"
volumes:
vprodbdata: {}
vproappdata: {}

2: Run Containers & Test

I will stay in the same directory where I created docker-compose.yml file and run below command:

docker-compose up

I will just use my localhost on port 8081 to check the application

After login

It’s working !!!

--

--

Semo
Semo

Written by Semo

0 Followers

UK based Junior Cloud Engineer with 3 AWS certifications, Azure Fundamentals www.linkedin.com/in/mohammed-zitouni-234b34240

No responses yet