<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: divine kenechukwu</title>
    <description>The latest articles on Forem by divine kenechukwu (@divine_kenechukwu_fc921c4).</description>
    <link>https://forem.com/divine_kenechukwu_fc921c4</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1760910%2F2cbb19db-d80e-40bc-ad32-5cd4eebb7edd.png</url>
      <title>Forem: divine kenechukwu</title>
      <link>https://forem.com/divine_kenechukwu_fc921c4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/divine_kenechukwu_fc921c4"/>
    <language>en</language>
    <item>
      <title>Deploy Simple Java Application using Docker Compose.</title>
      <dc:creator>divine kenechukwu</dc:creator>
      <pubDate>Sat, 14 Sep 2024 21:28:37 +0000</pubDate>
      <link>https://forem.com/divine_kenechukwu_fc921c4/deploy-simple-java-application-using-docker-compose-41mp</link>
      <guid>https://forem.com/divine_kenechukwu_fc921c4/deploy-simple-java-application-using-docker-compose-41mp</guid>
      <description>&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;&lt;br&gt;
The goal of this project is to create Docker Compose Stack to deploy a simple Java application running in Containers 3-Tier Architecture.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pre-Requisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create AWS EC2 (Amazon Linux) Instance in Public Subnet with any desired Instance Type&lt;/li&gt;
&lt;li&gt;Allow Port 80 in Security Group&lt;/li&gt;
&lt;li&gt;Apache Maven Build Artifact (.war)&lt;/li&gt;
&lt;li&gt;Install docker and run docker service&lt;/li&gt;
&lt;li&gt;Install docker-compose&lt;/li&gt;
&lt;li&gt;Application Source Code &lt;a href="https://github.com/Divine4212/java-login-app" rel="noopener noreferrer"&gt;Java&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Set Up the Environment:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;1. Create an Amazon Linux EC2 Instance:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch an EC2 instance in a public subnet.&lt;/li&gt;
&lt;li&gt;Choose any instance type, such as t2.micro for testing.&lt;/li&gt;
&lt;li&gt;Allow port 80 (HTTP) in the security group.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;2. Install Docker and Docker Compose on the EC2 Instance:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;- Docker:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum update -y

sudo yum install -y docker

sudo service docker start

sudo usermod -a -G docker ec2-user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;- docker-compose:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo 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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;3. Install Java and Apache Maven (for building the Java application):&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Clone the Java Source Code:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To deploy this application, clone the source code into the Amazon Linux instance created using &lt;code&gt;git clone&lt;/code&gt; command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/Divine4212/java-login-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Write Dockerfiles:&lt;/strong&gt;&lt;br&gt;
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.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;- Dockerfile-sql:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The Dockerfile-sql will create custom &lt;code&gt;MySQL&lt;/code&gt; container image by taking &lt;code&gt;docker.io/mysql:8.0&lt;/code&gt; as reference image from Docker Hub registry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;- init.sql:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;- Dockerfile-app:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The Dockerfile-app is a simplified and optimized version for your Java Login App that takes &lt;code&gt;docker.io/openjdk:11-jre-slim&lt;/code&gt; as base image from Docker Hub registry.. It installs &lt;code&gt;unzip&lt;/code&gt;, &lt;code&gt;vim&lt;/code&gt;, &lt;code&gt;telnet&lt;/code&gt; and &lt;code&gt;mysql-client&lt;/code&gt; and copy &lt;code&gt;.war&lt;/code&gt; artifact to &lt;code&gt;/app.war&lt;/code&gt; and start the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Use OpenJDK 11 as the base image
FROM openjdk:11-jre-slim

# Install necessary packages (unzip, vim, telnet, mysql-client)
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y unzip vim telnet mysql-client &amp;amp;&amp;amp; \
    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"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;- Dockerfile-nginx:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
The Dockerfile creates a custom Nginx container image by taking &lt;code&gt;docker.io/amazonlinux&lt;/code&gt; as reference image from Docker Hub registry. Will installs &lt;code&gt;Nginx server&lt;/code&gt;, &lt;code&gt;telnet&lt;/code&gt; and also copy the custom &lt;code&gt;nginx.conf&lt;/code&gt; file with proxy_pass rule to forward the traffic to the app container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM amazonlinux:2

RUN yum update -y &amp;amp;&amp;amp; \
    amazon-linux-extras install nginx1 -y &amp;amp;&amp;amp; \
    yum install -y telnet

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;- nginx.conf:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Write the Docker Compose File (&lt;code&gt;docker-compose.yml&lt;/code&gt;):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;- docker-compose.yml:&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
Docker Compose Stack Builds and Runs the Nginx, MySQL, App containers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;services:
  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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After creating these files in your cloned application folder, run &lt;code&gt;mvn clean package&lt;/code&gt; command to build your application with Maven, run &lt;code&gt;docker-compose build&lt;/code&gt; command to verify if container images are getting created and the run Run &lt;code&gt;docker-compose up -d&lt;/code&gt; command to verify if all containers are running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to Nginx container shell and check App port is reachable.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it 'container-id-nginx' /bin/sh

curl http://app:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Login to App container shell and check MySQL port is reachable.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it 'container-id-app' /bin/sh

telnet db 3306
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker exec -it 'container-id-app' /bin/sh

mysql -h db -u admin -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Browse the application from public internet browser to verify the application is accessible.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the project setup has been completed, do not forget to clean up resources to avoid the billing for your test environment. Run &lt;code&gt;docker-compose down&lt;/code&gt; command to stop and remove the containers and finally, terminate the instance from AWS Console.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>nginx</category>
      <category>java</category>
    </item>
  </channel>
</rss>
