Goal
The goal of this project is to create Docker Compose Stack to deploy a simple Java application running in Containers 3-Tier Architecture.
Pre-Requisites
- Create AWS EC2 (Amazon Linux) Instance in Public Subnet with any desired Instance Type
- Allow Port 80 in Security Group
- Apache Maven Build Artifact (.war)
- Install docker and run docker service
- Install docker-compose
- Application Source Code Java
Step 1: Set Up the Environment:
1. Create an Amazon Linux EC2 Instance:
- Launch an EC2 instance in a public subnet.
- Choose any instance type, such as t2.micro for testing.
- Allow port 80 (HTTP) in the security group.
2. Install Docker and Docker Compose on the EC2 Instance:
– Docker:
sudo yum update -ysudo yum install -y dockersudo service docker startsudo usermod -a -G docker ec2-usersudo yum update -y sudo yum install -y docker sudo service docker start sudo usermod -a -G docker ec2-usersudo yum update -y sudo yum install -y docker sudo service docker start sudo usermod -a -G docker ec2-user
Enter fullscreen mode Exit fullscreen mode
– docker-compose:
sudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-composesudo chmod +x /usr/local/bin/docker-composedocker-compose versionsudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose versionsudo curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod +x /usr/local/bin/docker-compose docker-compose version
Enter fullscreen mode Exit fullscreen mode
3. Install Java and Apache Maven (for building the Java application):
curl -LO https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.tar.gzsudo tar -xvzf amazon-corretto-11-x64-linux-jdk.tar.gz -C /usr/java/cd /usr/java/amazon-corretto-*-linux-x64/binfor i in java javac jfr; do path=$(find `pwd`/$i -type f); echo $path; sudo alternatives --install /usr/bin/$i $i $path 20000 ; sudo update-alternatives --config $i ; donejava -versioncurl -LO https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.tar.gz sudo tar -xvzf amazon-corretto-11-x64-linux-jdk.tar.gz -C /usr/java/ cd /usr/java/amazon-corretto-*-linux-x64/bin for i in java javac jfr; do path=$(find `pwd`/$i -type f); echo $path; sudo alternatives --install /usr/bin/$i $i $path 20000 ; sudo update-alternatives --config $i ; done java -versioncurl -LO https://corretto.aws/downloads/latest/amazon-corretto-11-x64-linux-jdk.tar.gz sudo tar -xvzf amazon-corretto-11-x64-linux-jdk.tar.gz -C /usr/java/ cd /usr/java/amazon-corretto-*-linux-x64/bin for i in java javac jfr; do path=$(find `pwd`/$i -type f); echo $path; sudo alternatives --install /usr/bin/$i $i $path 20000 ; sudo update-alternatives --config $i ; done java -version
Enter fullscreen mode Exit fullscreen mode
Step 2: Clone the Java Source Code:
- To deploy this application, clone the source code into the Amazon Linux instance created using
git clone
command.
git clone https://github.com/Divine4212/java-login-appgit clone https://github.com/Divine4212/java-login-appgit clone https://github.com/Divine4212/java-login-app
Enter fullscreen mode Exit fullscreen mode
Step 3: Write Dockerfiles:
Dockerfiles are the blueprints for creating Docker images. In a Docker Compose project, they define the environment for each service. Docker Compose uses these Dockerfiles to build the images and then run them as containers.
– Dockerfile-sql:
The Dockerfile-sql will create custom MySQL
container image by taking docker.io/mysql:8.0
as reference image from Docker Hub registry.
FROM mysql:8.0ENV MYSQL_ROOT_PASSWORD=rootpasswordENV MYSQL_DATABASE=UserDBENV MYSQL_USER=adminENV MYSQL_PASSWORD=Admin123COPY init.sql /docker-entrypoint-initdb.d/FROM mysql:8.0 ENV MYSQL_ROOT_PASSWORD=rootpassword ENV MYSQL_DATABASE=UserDB ENV MYSQL_USER=admin ENV MYSQL_PASSWORD=Admin123 COPY init.sql /docker-entrypoint-initdb.d/FROM mysql:8.0 ENV MYSQL_ROOT_PASSWORD=rootpassword ENV MYSQL_DATABASE=UserDB ENV MYSQL_USER=admin ENV MYSQL_PASSWORD=Admin123 COPY init.sql /docker-entrypoint-initdb.d/
Enter fullscreen mode Exit fullscreen mode
– init.sql:
init.sql:CREATE TABLE Employee (id int unsigned auto_increment not null,first_name varchar(250),last_name varchar(250),email varchar(250),username varchar(250),password varchar(250),regdate timestamp,primary key (id));init.sql: CREATE TABLE Employee ( id int unsigned auto_increment not null, first_name varchar(250), last_name varchar(250), email varchar(250), username varchar(250), password varchar(250), regdate timestamp, primary key (id) );init.sql: CREATE TABLE Employee ( id int unsigned auto_increment not null, first_name varchar(250), last_name varchar(250), email varchar(250), username varchar(250), password varchar(250), regdate timestamp, primary key (id) );
Enter fullscreen mode Exit fullscreen mode
– Dockerfile-app:
The Dockerfile-app is a simplified and optimized version for your Java Login App that takes docker.io/openjdk:11-jre-slim
as base image from Docker Hub registry.. It installs unzip
, vim
, telnet
and mysql-client
and copy .war
artifact to /app.war
and start the application.
# Use OpenJDK 11 as the base imageFROM openjdk:11-jre-slim# Install necessary packages (unzip, vim, telnet, mysql-client)RUN apt-get update && \apt-get install -y unzip vim telnet mysql-client && \rm -rf /var/lib/apt/lists/*# Set volume for temporary filesVOLUME /tmp# Copy the WAR file to the containerCOPY target/dptweb-1.0.war /app.war# Expose the port Tomcat will run onEXPOSE 8080# Run the application using the JAR commandENTRYPOINT ["java", "-jar", "/app.war"]# Use OpenJDK 11 as the base image FROM openjdk:11-jre-slim # Install necessary packages (unzip, vim, telnet, mysql-client) RUN apt-get update && \ apt-get install -y unzip vim telnet mysql-client && \ rm -rf /var/lib/apt/lists/* # Set volume for temporary files VOLUME /tmp # Copy the WAR file to the container COPY target/dptweb-1.0.war /app.war # Expose the port Tomcat will run on EXPOSE 8080 # Run the application using the JAR command ENTRYPOINT ["java", "-jar", "/app.war"]# Use OpenJDK 11 as the base image FROM openjdk:11-jre-slim # Install necessary packages (unzip, vim, telnet, mysql-client) RUN apt-get update && \ apt-get install -y unzip vim telnet mysql-client && \ rm -rf /var/lib/apt/lists/* # Set volume for temporary files VOLUME /tmp # Copy the WAR file to the container COPY target/dptweb-1.0.war /app.war # Expose the port Tomcat will run on EXPOSE 8080 # Run the application using the JAR command ENTRYPOINT ["java", "-jar", "/app.war"]
Enter fullscreen mode Exit fullscreen mode
– Dockerfile-nginx:
The Dockerfile creates a custom Nginx container image by taking docker.io/amazonlinux
as reference image from Docker Hub registry. Will installs Nginx server
, telnet
and also copy the custom nginx.conf
file with proxy_pass rule to forward the traffic to the app container.
FROM amazonlinux:2RUN yum update -y && \amazon-linux-extras install nginx1 -y && \yum install -y telnetCOPY nginx.conf /etc/nginx/nginx.confEXPOSE 80CMD ["nginx", "-g", "daemon off;"]FROM amazonlinux:2 RUN yum update -y && \ amazon-linux-extras install nginx1 -y && \ yum install -y telnet COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]FROM amazonlinux:2 RUN yum update -y && \ amazon-linux-extras install nginx1 -y && \ yum install -y telnet COPY nginx.conf /etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
Enter fullscreen mode Exit fullscreen mode
– nginx.conf:
events {worker_connections 1024;}http {upstream app {server app:8080;}server {listen 80;location / {proxy_pass http://app;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}}}events { worker_connections 1024; } http { upstream app { server app:8080; } server { listen 80; location / { proxy_pass http://app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }events { worker_connections 1024; } http { upstream app { server app:8080; } server { listen 80; location / { proxy_pass http://app; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
Enter fullscreen mode Exit fullscreen mode
Step 4: Write the Docker Compose File (docker-compose.yml
):
– docker-compose.yml:
Docker Compose Stack Builds and Runs the Nginx, MySQL, App containers.
services:db:build:context: .dockerfile: Dockerfile-mysqlenvironment:MYSQL_ROOT_PASSWORD: rootpasswordMYSQL_DATABASE: UserDBMYSQL_USER: adminMYSQL_PASSWORD: Admin123networks:- app-networkapp:build:context: .dockerfile: Dockerfile-appdepends_on:- dbnetworks:- app-networkports:- "8080:8080" # Expose port 8080nginx:build:context: .dockerfile: Dockerfile-nginxports:- "80:80"depends_on:- appnetworks:- app-networknetworks:app-network:driver: bridgeservices: db: build: context: . dockerfile: Dockerfile-mysql environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: UserDB MYSQL_USER: admin MYSQL_PASSWORD: Admin123 networks: - app-network app: build: context: . dockerfile: Dockerfile-app depends_on: - db networks: - app-network ports: - "8080:8080" # Expose port 8080 nginx: build: context: . dockerfile: Dockerfile-nginx ports: - "80:80" depends_on: - app networks: - app-network networks: app-network: driver: bridgeservices: db: build: context: . dockerfile: Dockerfile-mysql environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: UserDB MYSQL_USER: admin MYSQL_PASSWORD: Admin123 networks: - app-network app: build: context: . dockerfile: Dockerfile-app depends_on: - db networks: - app-network ports: - "8080:8080" # Expose port 8080 nginx: build: context: . dockerfile: Dockerfile-nginx ports: - "80:80" depends_on: - app networks: - app-network networks: app-network: driver: bridge
Enter fullscreen mode Exit fullscreen mode
After creating these files in your cloned application folder, run mvn clean package
command to build your application with Maven, run docker-compose build
command to verify if container images are getting created and the run Run docker-compose up -d
command to verify if all containers are running.
Validation
- Login to Nginx container shell and check App port is reachable.
docker exec -it 'container-id-nginx' /bin/shcurl http://app:8080docker exec -it 'container-id-nginx' /bin/sh curl http://app:8080docker exec -it 'container-id-nginx' /bin/sh curl http://app:8080
Enter fullscreen mode Exit fullscreen mode
- Login to App container shell and check MySQL port is reachable.
docker exec -it 'container-id-app' /bin/shtelnet db 3306docker exec -it 'container-id-app' /bin/sh telnet db 3306docker exec -it 'container-id-app' /bin/sh telnet db 3306
Enter fullscreen mode Exit fullscreen mode
or
docker exec -it 'container-id-app' /bin/shmysql -h db -u admin -pdocker exec -it 'container-id-app' /bin/sh mysql -h db -u admin -pdocker exec -it 'container-id-app' /bin/sh mysql -h db -u admin -p
Enter fullscreen mode Exit fullscreen mode
- Browse the application from public internet browser to verify the application is accessible.
Conclusion
Once the project setup has been completed, do not forget to clean up resources to avoid the billing for your test environment. Run docker-compose down
command to stop and remove the containers and finally, terminate the instance from AWS Console.
暂无评论内容