Deploying Multitier Application with Docker

Amitabh soniAmitabh soni
4 min read

This guide provides a comprehensive overview of setting up a Dockerized Banking Application using both Docker and Docker Compose. It covers the essential steps for deploying the application, setting up MySQL with persistent storage, and organizing services for seamless containerized deployment. Below is a detailed walkthrough:


Project Overview

The BankApp Project demonstrates containerizing a Spring Boot application using Docker's multi-stage builds and managing MySQL as a database with Docker Compose.

Pre-requisites

  • AWS Account: Ensure an active AWS account.

  • AWS Ubuntu EC2 Instance: Deploy a t2.medium instance for better performance.

  • Docker Installation: Install Docker on the EC2 instance. using ‘sudo apt install docker.io‘ and add current user using ‘sudo usermod -aG docker $USER && newgrep docker‘

  • Docker Compose Installation: Install Docker Compose for managing multi-container applications. install using ‘sudo apt install docker-compose-v2‘

Tools Used

  • Docker (Multi-Stage Builds): For building and deploying the application in different stages.

  • Maven: Compiles and packages the Java application.

  • Spring Boot: Backend framework for the BankApp.

  • MySQL: Relational database for storing application data.

  • Docker Compose: Manages and links multiple services.


Deployment Without Docker Compose

The initial deployment setup involves managing each container manually without a docker-compose.yml file.

  1. Clone the Repository

    • Clone the project repository and navigate to the project code.

    • Command: git clone <repository-url> && cd <project-directory>

  2. Multi-Stage Dockerfile Setup

    • Create a multi-stage Dockerfile to separate the build environment from the production environment.
    # Stage 1 - Build Environment
    FROM maven:3.8.3-openjdk-17 AS builder
    WORKDIR /app
    COPY . /app
    RUN mvn clean install -DskipTests=true

    # Stage 2 - Production Environment
    FROM openjdk:17-jdk-alpine
    COPY --from=builder /app/target/*.jar /app/target/bankapp.jar
    EXPOSE 8080
    ENTRYPOINT ["java", "-jar", "/app/target/bankapp.jar"]
  1. Creating Docker Volume for MySQL

    • Use Docker volumes to store MySQL data persistently.

    • Command: docker volume create mysql-bankapp

  2. Creating Docker Network

    • Create a Docker network to enable communication between containers.

    • Command: docker network create bankapp

  3. Running MySQL Container

    • Run the MySQL container within the bankapp network.

    • Command:

        docker run -d --name mysql \
        -e MYSQL_ROOT_PASSWORD=Test@123 \
        -e MYSQL_DATABASE=BankDB \
        --network=bankapp mysql:latest
      
  4. Build and Run the BankApp Container

    • Build the Docker image for the BankApp and run it within the network.

    • Commands:

        docker build -t bankapp-mini .
        docker run -d --name bankapp-mini \
        -e SPRING_DATASOURCE_USERNAME="root" \
        -e SPRING_DATASOURCE_URL="jdbc:mysql://mysql:3306/BankDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC" \
        -e SPRING_DATASOURCE_PASSWORD="Test@123" \
        --network=bankapp -p 8080:8080 bankapp-mini:latest
      
  5. Access the Application

    • Configure EC2 inbound rules to allow traffic on port 8080. Access the BankApp at <EC2-instance-public-IP>:8080.

Deployment with Docker Compose

Using Docker Compose simplifies the multi-container setup.

  1. Stop and Remove Existing Containers

    • Ensure any previous containers are stopped and removed.

    • Command: docker stop <container-ids> && docker rm <container-ids>

  2. Docker Compose YAML Setup

    • Create a docker-compose.yml file to define services and configurations for MySQL and the BankApp.
    version: "3.8"

    services:
      mysql:
        image: mysql:latest
        container_name: mysql
        environment:
          MYSQL_ROOT_PASSWORD: Test@123
          MYSQL_DATABASE: BankDB
        volumes:
          - mysql-bankapp:/var/lib/mysql
        networks:
          - bankapp
        restart: always
        healthcheck:
          test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-uroot", "-pTest@123"]
          interval: 10s
          timeout: 5s
          retries: 10
          start_period: 30s

      bankapp:
        image: bankapp-mini
        container_name: bankapp
        environment:
          SPRING_DATASOURCE_USERNAME: "root"
          SPRING_DATASOURCE_PASSWORD: "Test@123"
          SPRING_DATASOURCE_URL: "jdbc:mysql://mysql:3306/BankDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"
        ports:
          - "8080:8080"
        depends_on:
          mysql:
            condition: service_healthy
        networks:
          - bankapp
        restart: always

    volumes:
      mysql-bankapp:

    networks:
      bankapp:
  1. Run Docker Compose

    • Command: docker-compose up -d

    • This command will start all services, with MySQL and the BankApp container linked and configured as specified.

Testing the Application

Access the application through the EC2 instance's public IP on port 8080. The BankApp should be fully operational, with MySQL data being persistently stored via Docker volumes.

For step by step implementation with images follow this Notion notes here

For code, refer Github Repo.

Output images for reference :


This setup efficiently organizes a multi-container banking application, separating concerns with a Docker multi-stage build and Docker Compose for simplified management. The application is scalable and can be deployed on AWS EC2 for real-world testing.

0
Subscribe to my newsletter

Read articles from Amitabh soni directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Amitabh soni
Amitabh soni

DevOps Enthusiast | Passionate Learner in Tech | BSc IT Student I’m a second-year BSc IT student with a deep love for technology and an ambitious goal: to become a DevOps expert. Currently diving into the world of automation, cloud services, and version control, I’m excited to learn and grow in this dynamic field. As I expand my knowledge, I’m eager to connect with like-minded professionals and explore opportunities to apply what I’m learning in real-world projects. Let’s connect and see how we can innovate together!