Astarix Assignment: Containerizing MERN Stack Application on AWS and Crafting CICD Pipeline.


📍Docker & Docker-Compose

Step 1: Launch an AWS EC2 instance of type t2.medium.

Step 2: Install Docker and Docker-Compose and permit the Ubuntu user.

Giving user permission:

sudo usermod -aG docker ubuntu

Step 3: Clone this GitHub repository:

https://github.com/Varunmargam/idurar-erp-crm

Step 4: Create a Dockerfile inside the front end and the backend directory.

Backend

FROM node:16

WORKDIR app/backend

COPY package*.json ./

RUN npm i

COPY . .

EXPOSE 8888

CMD ["npm","run","dev"]

Frontend

FROM node:16

WORKDIR app/frontend

COPY package*.json ./

RUN npm i

COPY . .

EXPOSE 3000

CMD ["npm","run","dev"]

Step 5: Edit the .env file inside the frontend directory and the backend directory.

For the MongoURL replace the username and the password with your credentials.

Step 6: Edit the vite.config.js file inside the frontend directory.

Add host: '0.0.0.0', at line 24.

Step 8: Build the Docker images from idurar-erp-crm directory.

Step 7: Create a Docker-compose file inside the idurar-erp-crm directory.

docker-compose.yml

version: '3'
services:

  backend:
    build:
      context: ./backend
    ports:
      - "8888:8888"
    depends_on:
      - database

  frontend:
    build:
      context: ./frontend
    ports:
      - "3000:3000"

  database:
    image: mongo:latest
    ports:
      - "27017:27017"

Step 8: Run the docker-compose file.

Step 9: Edit the inbound rules on the EC2 instance and give access to port 3000.

Step 9: You can access the application on the browser at http://<AWS_EC2_Pub_IP>:3000


📍CI/CD

Install Jenkins on the EC2 instance and set up a Pipeline. You can refer to this blog for the same:

https://varunmargam.hashnode.dev/cicd-pipeline-for-2-tier-flask-todo-web-application

To execute the "Login to the DockerHub" step via Jenkins, we have to first give the DockerHub credentials to Jenkins.

  • Go to Dashboard and click on "Manage Jenkins":

    • Go to the "Security" section and click on "Credentials":

    • Click on "(global)":

    • Click on "Add Credentials" at the top right:

    • Enter the Username and Password of your DockerHub Account:

      Enter ID as "DockerHub" and give Description as "These are DockerHub credentials."

      Your DockerHub credentials that contain the username and password for your DockerHub account will be identified using this ID by Jenkins.

    • Click "Create":

    • Your DockerHub credentials are created with the ID "DockerHub".

This is the Jenkinsfile which you can add to the GitHub repository but need to execute this you need to push the changes made to the files in the previous section and commit those changes to GitHub which would not be a good practice since it contains sensitive information like MongoDB URL.

If you want to execute this CICD pipeline you would also have to modify the Docker-compose file in the build section as given below.

pipeline {
    agent any

    stages {
        stage("Clone") {
            steps {
                git url: 'https://github.com/Varunmargam/idurar-erp-crm.git', branch: 'master'
            }
        }

        stage("Build Backend") {
            steps {
                dir('backend') {
                    script {
                        // Assuming Dockerfile is in the backend directory
                        sh "docker build -t backend ."
                    }
                }
            }
        }

        stage("Build Frontend") {
            steps {
                dir('frontend') {
                    script {
                        // Assuming Dockerfile is in the frontend directory
                        sh "docker build -t frontend ."
                    }
                }
            }
        }

        stage("Push to Repository") {
            steps {
                withCredentials([usernamePassword(credentialsId: "DockerHub", passwordVariable: "DockerHubPass", usernameVariable: "DockerHubUser")]) {
                    script {
                        sh "docker login -u ${DockerHubUser} -p ${DockerHubPass}"

                        // Correcting the Docker push commands
                        sh "docker tag frontend ${DockerHubUser}/frontend:latest"
                        sh "docker push ${DockerHubUser}/frontend:latest"

                        sh "docker tag backend ${DockerHubUser}/backend:latest"
                        sh "docker push ${DockerHubUser}/backend:latest"
                    }
                }
            }
        }

        stage("Deploy") {
            steps {
                // Consider using docker-compose.yml file in your project directory
                sh "docker-compose up -d"
            }
        }
    }
}
backend:
    image: "varunmargam/backend:latest"
    ports:
      - "8888:8888"
    depends_on:
      - database

  frontend:
    image: "varunmargam/frontend:latest"
    ports:
      - "3000:3000"