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 !!!