diff --git a/Dockerfile b/Dockerfile index 079acabe..aa44f81a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,19 +3,13 @@ #---------------------------------- # Import docker image with maven installed -FROM maven:3.8.3-openjdk-17 as builder - -# Add maintainer, so that new user will understand who had written this Dockerfile -MAINTAINER Madhup Pandey - -# Add labels to the image to filter out if we have multiple application running -LABEL app=bankapp +FROM maven:3.8.3-openjdk-17 AS builder # Set working directory -WORKDIR /src +WORKDIR /app # Copy source code from local to container -COPY . /src +COPY . /app # Build application and skip test cases RUN mvn clean install -DskipTests=true @@ -25,13 +19,13 @@ RUN mvn clean install -DskipTests=true #-------------------------------------- # Import small size java image -FROM openjdk:17-alpine as deployer +FROM openjdk:17-alpine AS deployer # Copy build from stage 1 (builder) -COPY --from=builder /src/target/*.jar /src/target/bankapp.jar +COPY --from=builder /app/target/*.jar /app/target/bankapp.jar # Expose application port EXPOSE 8080 # Start the application -ENTRYPOINT ["java", "-jar", "/src/target/bankapp.jar"] +ENTRYPOINT ["java", "-jar", "/app/target/bankapp.jar"] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index aea12103..8fd759a0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,30 +1,80 @@ -@Library("shared-library@DevOps") _ - pipeline { - agent {label 'runner_1'} - + agent { + label 'agent-slave' + } stages { - stage('Checkout code') { + stage("Code Clone") { steps { - codeCheckout('DevOps', 'https://github.com/joakim077/Springboot-BankApp.git') + echo "Code Clone Stage" + git url: "https://github.com/sushmithavs/Springboot-BankApp.git", branch: "DevOps" } } - stage('build') { + stage("Code Build & Test") { steps { - buildImage("springboot-application") + script { + try { + echo "Starting Code Clone Stage" + git url: "https://github.com/sushmithavs/Springboot-BankApp.git", branch: "DevOps" + echo "Starting Build and Test" + sh 'mvn clean package' + sh 'mvn test' + sh 'docker build -t bankapp:latest + } catch (Exception e) { + error "Failed to clone repository: ${e.message}" + } + } } } - stage('Push Image') { + stage("Push To DockerHub") { steps { - pushImage("springboot-application") + withCredentials([usernamePassword( + credentialsId: "dockerhub-creds", + usernameVariable: "dockerHubUser", + passwordVariable: "dockerHubPass" + )]) { + sh ''' + echo $dockerHubPass | docker login - u $dockerHubUser --password + - stdin + VERSION = $(git rev - parse -- short HEAD) docker image tag bankapp: latest $ { + dockerHubUser + }/bankapp:${VERSION} + docker image tag bankapp:latest ${dockerHubUser}/bankapp: latest + docker push $ { + dockerHubUser + }/bankapp:${VERSION} + docker push ${dockerHubUser}/bankapp: latest + docker rmi $ { + dockerHubUser + }/bankapp:${VERSION} + docker rmi ${dockerHubUser}/bankapp: latest + ''' + } + } catch (Exception e) { + error "Failed to push Docker image: ${e.message}" + } } } - stage('Deploy'){ - steps{ - deploy() + stage("Deploy") { + steps { + script { + sh "docker compose down && docker compose up -d --build" + // Wait for application to be ready + sh ''' + max_attempts = 30 + attempt = 1 + echo "Waiting for application to be ready..." + while [$attempt - le $max_attempts]; do if curl - s http: //localhost:8080/health; then + echo "Application is ready!" + exit 0 + fi + attempt = $((attempt+1)) + sleep 10 + done + echo "Application failed to start within timeout" + exit 1 + ''' + } } } - } } - diff --git a/README.md b/README.md index b21647fd..ee166802 100644 --- a/README.md +++ b/README.md @@ -1,96 +1,273 @@ -## End-to-End Bank Application Deployment using DevSecOps on AWS EKS -- This is a multi-tier bank an application written in Java (Springboot). - -![Login diagram](images/login.png) -![Transactions diagram](images/transactions.png) - -### PRE-REQUISITES FOR THIS PROJECT: -- AWS Account -- AWS Ubuntu EC2 instance (t2.medium) -- Install Docker -- Install docker compose -# -### DEPLOYMENT: -| Deployments | Paths | -| -------- | ------- | -| Deployment using Docker and Networking | Click me | -| Deployment using Docker Compose | Click me | -| Deployment using Jenkins on EKS | Click me | -| Deployment using Argocd on EKS| Click me | - -# -### STEPS TO IMPLEMENT THE PROJECT -- **

Deployment using Docker

** - - Clone the repository - ```bash - git clone -b DevOps https://github.com/DevMadhup/Springboot-BankApp.git - ``` - # - - Install docker, docker compose and provide neccessary permission - ```bash - sudo apt update -y - - sudo apt install docker.io docker-compose-v2 -y - - sudo usermod -aG docker $USER && newgrp docker - ``` - # - - Move to the cloned repository - ```bash - cd Springboot-BankApp - ``` - # - - Build the Dockerfile - ```bash - docker build -t madhupdevops/springboot-bankapp . - ``` -> [!Important] -> Make sure to change docker build command with your DockerHub username. - # - - Create a docker network - ```bash - docker network create bankapp - ``` - # - - Run MYSQL container - ```bash - docker run -itd --name mysql -e MYSQL_ROOT_PASSWORD=Test@123 -e MYSQL_DATABASE=BankDB --network=bankapp mysql - ``` - # - - Run Application container - ```bash - docker run -itd --name BankApp -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 madhupdevops/springboot-bankapp - ``` - # - - Verify deployment - ```bash - docker ps - ``` - # - - Open port 8080 of your AWS instance and access your application - ```bash - http://:8080 - ``` - ### Congratulations, you have deployed the application using Docker - # -- **

Deployment using Docker compose

** -- Install docker compose +# 🚀 Bank Application Project +The bank application project involves setting up jenkins pipeline on AWS EC2 using docker. +This pipeline is used to build,test and deploy bank application. + +--- + +![App Architecture Diagram](images/login.png) + +--- + +**Project Features** +------------------- + +* Jenkins pipeline for building, testing, and deploying a software project +* Dockerized Jenkins instance on an AWS EC2 instance +* EC2 instance as a master node and EC2 instance as a worker node +* Dockerfile for building the project image +* Jenkinsfile for configuring the Jenkins pipeline + +**Pre-requisites** +----------------- + +Ensure you have the following: +*AWS Account** with EC2 instances (Ubuntu 20.04 or later) +*Ubuntu EC2 Instance** (Recommended: `t2.medium`) +*Docker** installed on the EC2 instances +*Basic knowledge** of Docker, Jenkins, and AWS + +**Step-by-Step Guide** +---------------------- + +### Step 1: Set up the Master Node (EC2 Instance) + +1. Launch an EC2 instance (Ubuntu 20.04 or later) and connect to it using SSH. +2. Install Docker on the instance: `sudo apt update && sudo apt install docker.io` +3. Start the Docker service: `sudo systemctl start docker` +4. Enable the Docker service to start at boot: `sudo systemctl enable docker` + +### Step 2: Set up the Worker Node (EC2 Instance) + +1. Launch another EC2 instance (Ubuntu 20.04 or later) and connect to it using SSH. +2. Install Docker on the instance: `sudo apt update && sudo apt install docker.io` +3. Start the Docker service: `sudo systemctl start docker` +4. Enable the Docker service to start at boot: `sudo systemctl enable docker` + +### Step 3: Configure the Master Node as a Jenkins Server + +1. Install Jenkins on the master node: `sudo apt update && sudo apt install jenkins` +2. Start the Jenkins service: `sudo systemctl start jenkins` +3. Enable the Jenkins service to start at boot: `sudo systemctl enable jenkins` +4. Configure Jenkins to use the Docker daemon: `sudo tee /etc/jenkins/jenkins.yaml <:8080 +``` +### Step 5: Create a Dockerfile for the Project + +1. Create a new file named `Dockerfile` in the project directory: +```dockerfile +FROM ubuntu:20.04 + +# Install dependencies +RUN apt update && apt install -y build-essential + +# Copy the project code +COPY . /app + +# Build the project +RUN make build + +# Expose the port +EXPOSE 8080 + +# Run the command +CMD ["make", "run"] +``` +### Step 6: Create a Jenkinsfile for the Project + +1. Create a new file named `Jenkinsfile` in the project directory: +```groovy +pipeline { + agent any + + stages { + stage('Build') { + steps { + sh 'make build' + } + } + stage('Test') { + steps { + sh 'make test' + } + } + stage('Deploy') { + steps { + sh 'make deploy' + } + } + } +} +``` +### Step 7: Build the Project Image using Docker + +1. Navigate to the project directory and run the command: `docker build -t my-project .` + +### Step 8: Configure Jenkins to Build the Project + +1. Log in to the Jenkins web interface and create a new pipeline job. +2. Configure the job to use the `Jenkinsfile` and build the project image using Docker. + +### Step 9: Establish the Connection between the Master Node and Worker Node + +1. Configure the Jenkins master node to connect to the worker node: `sudo tee /etc/jenkins/jenkins.yaml +```yaml +jenkins: + agent: + docker: + enabled: true + worker: + url: http://:8080 +``` +2. Restart the Jenkins service on the master node: `sudo systemctl restart jenkins` + +##### That's it! You have now set up a Jenkins pipeline on an AWS EC2 instance using Docker, with a master node and worker node. You can use this pipeline to build, test, and deploy your software project. + +--- + +## 🏗 Deployment Steps + +### **

Deployment Using EC2 Instance

** + +#### Step 1: Set up the Master Node (EC2 Instance) +**Go to AWS your master-node instances and select security groups and go to add rule `8080` save this.** +**Configure EC2 Security Group:** ++1. Navigate to your EC2 instance's security group ++2. Add inbound rule: ++ - Port: 8080 ++ - Protocol: TCP ++ - Source: Custom (Recommended: Your IP) or 0.0.0.0/0 (Not recommended for production) ++3. Save the changes +```bash +ssh -i "your pem- key" ubuntu@ec2-44-244-168-242.us-west +``` +Install [Docker](https://docs.docker.com/engine/install/ubuntu/), [java](https://www.jenkins.io/doc/book/installing/linux/), [Jenkins](https://www.jenkins.io/doc/book/installing/linux/) +```bash +sudo apt update -y +``` +```bash +sudo apt install docker.io -y +sudo apt install docker-compose-v2 +``` ```bash sudo apt update -sudo apt install docker-compose-v2 -y +sudo apt install fontconfig openjdk-17-jre +java -version +``` +```bash +sudo wget -O /usr/share/keyrings/jenkins-keyring.asc \ + https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key +echo "deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc]" \ + https://pkg.jenkins.io/debian-stable binary/ | sudo tee \ + /etc/apt/sources.list.d/jenkins.list > /dev/null +sudo apt-get update +sudo apt-get install jenkins +``` +```bash +sudo usermod -aG docker $USER && newgrp docker +``` +```bash +sudo usermod -aG jenkins docker +``` +Access :8080 + * To Access your jenkins server. + +--- + +![Transaction Flow Diagram](images/Jenkinsbank1.png) + + +🎉 Congratulations! Your Jenkins Server is live. + +#### Step 2: Set up the Worker Node (EC2 Instance) +**Go to AWS your master-node instaces and select security groups and go to add rule `8080` save this.** +```bash +ssh -i "your pem- key" ubuntu@ec2-44-244-168-242.us-west +``` +Install [Docker](https://docs.docker.com/engine/install/ubuntu/), [java](https://www.jenkins.io/doc/book/installing/linux/) +```bash +sudo apt update -y +``` +```bash +sudo apt install docker.io && docker-compose-v2 -y ``` -# -- Run docker-compose file present in the root directory of a project ```bash -docker compose up -d +sudo apt update +sudo apt install fontconfig openjdk-17-jre +java -version ``` -# -- Access it on port 8080 + ![App pipeline flow Diagram](images/Jenkins-Pipeline.png) +Step 1: Go to the AWS EC2 instance and copy your worker-node public ip address and paste it in the jenkins Agent config windows. +Craete a Directory in your `workernode.` ```bash - http://:8080 +mkdir workernode +``` +Copy the Present Working Directory and paste it in the Agent config window. +``bash +pwd +``` +Step 2: +![Jenkins Output](images/jenkinsbank3.png) +Step 3: Configure your pipeline. + +```groovy +pipeline{ + agent { label 'workernode' } + + stages{ + stage("Code Clone"){ + steps{ + echo "Code Clone Stage" + git url: "https://github.com/sushmithavs/Springboot-BankApp.git", branch: "DevOps" + } + } + stage("Code Build & Test"){ + steps{ + echo "Code Build Stage" + sh "docker build -t bankapp ." + } + } + stage("Push To DockerHub"){ + steps{ + withCredentials([usernamePassword( + credentialsId:"dockerhub-creds", + usernameVariable:"dockerHubUser", + passwordVariable:"dockerHubPass")]){ + sh 'echo $dockerHubPass | docker login -u $dockerHubUser --password-stdin' + sh "docker image tag bankapp:latest ${env.dockerHubUser}/bankapp:latest" + sh "docker push ${env.dockerHubUser}/bankapp:latest" + } + } + } + stage("Deploy"){ + steps{ + sh "docker compose down && docker compose up -d --build" + } + } + } +} ``` -> [!Important] -> If you face issues with exiting docker container while running docker compose, run ``` docker compose down``` and then ``` docker compose up -d ```. +Step 4: Navigate to bank app dashboard and click on `Build Now` button. + +Step 5: Your Pipeline has been created + +![Jenkins Logs](images/Jenkins-Logs.png) + +🎉 Congratulations! Your bankapp is running on workernode port `8080.` + +👨‍💻 Author: Sushmitha -#### CICD pipeline [guide](cicd.md) diff --git a/images/Docker-hub.png b/images/Docker-hub.png new file mode 100644 index 00000000..cd53b9ff Binary files /dev/null and b/images/Docker-hub.png differ diff --git a/images/Jenkins-Logs.png b/images/Jenkins-Logs.png new file mode 100644 index 00000000..9255eae3 Binary files /dev/null and b/images/Jenkins-Logs.png differ diff --git a/images/Jenkins-Pipeline.png b/images/Jenkins-Pipeline.png new file mode 100644 index 00000000..12f2b2cb Binary files /dev/null and b/images/Jenkins-Pipeline.png differ diff --git a/images/Jenkinsbank1.png b/images/Jenkinsbank1.png new file mode 100644 index 00000000..a8df9c5c Binary files /dev/null and b/images/Jenkinsbank1.png differ diff --git a/images/jenkinsbank3.png b/images/jenkinsbank3.png new file mode 100644 index 00000000..582296df Binary files /dev/null and b/images/jenkinsbank3.png differ diff --git a/images/pipeline.png b/images/pipeline.png deleted file mode 100644 index 9a80ab15..00000000 Binary files a/images/pipeline.png and /dev/null differ