<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Prabir Kalwani on Medium]]></title>
        <description><![CDATA[Stories by Prabir Kalwani on Medium]]></description>
        <link>https://medium.com/@prabir.kalwani?source=rss-19f2379194fe------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*yNWx39gjYmMUwY4BCvOTpA.jpeg</url>
            <title>Stories by Prabir Kalwani on Medium</title>
            <link>https://medium.com/@prabir.kalwani?source=rss-19f2379194fe------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 16 May 2026 13:19:34 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@prabir.kalwani/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Harnessing the Power of GitHub Actions and Docker for Effortless Next.js CI/CD]]></title>
            <link>https://medium.com/@prabir.kalwani/harnessing-the-power-of-github-actions-and-docker-for-effortless-next-js-ci-cd-0faabd032291?source=rss-19f2379194fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/0faabd032291</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[ci-cd-pipeline]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[github-actions]]></category>
            <dc:creator><![CDATA[Prabir Kalwani]]></dc:creator>
            <pubDate>Tue, 30 Apr 2024 19:39:23 GMT</pubDate>
            <atom:updated>2024-04-30T19:58:00.465Z</atom:updated>
            <content:encoded><![CDATA[<h4>Setting Up Automated Build and Deployment Pipelines for Next.js Applications</h4><p>Working on small projects and deploying to cloud platforms like GCP and AWS or Your Own VPS ?</p><p>Implementing CI/CD can be a headache. In this blog, we’ll unravel the secrets of Continuous Integration and Continuous Deployment for Next.js apps. Streamline your development workflow and deploy , with a CI/CD pipeline tailored for the modern web using simple and beginner friendly tools such as GitHub Actions And Docker.</p><h3>Prerequisites:</h3><ol><li>A Virtual Cloud Machine from any cloud provider or a local Ubuntu VPS. In this case, we’ll be using <a href="http://aws.amazon.com">Amazon Web Services </a>(AWS) as our cloud provider.</li><li>Docker, Git, and Docker Compose installed on the given machine.</li><li>A NextJs Project You can check out a template <a href="https://nextjs.org/">here</a> .</li><li><a href="https://hub.docker.com/signup">DockerHub</a> And A <a href="https://github.com/signup?source=header-home">GitHub</a> Account</li></ol><p>To get started, we’ll launch an AWS EC2 instance and provide a bash script to install the required dependencies. This will ensure a smooth setup for implementing the CI/CD pipeline for our Next.js application.</p><pre>#!/bin/bash<br><br># install.sh<br># to run this file first : chmod +x install.sh<br># then you can run it using : ./install.sh<br><br># Update your system<br>sudo apt update<br><br># Install prerequisites<br>sudo apt install -y apt-transport-https ca-certificates curl software-properties-common<br><br># Install Docker<br>curl -fsSL https://get.docker.com -o get-docker.sh<br>sudo sh get-docker.sh<br><br># Add current user to docker group<br>sudo usermod -aG docker $USER<br><br># Install Docker Compose<br>sudo apt install -y docker-compose<br><br># Install Git<br>sudo apt install -y git<br><br># Clean up<br>rm get-docker.sh<br><br>echo &quot;Installation complete. Please reboot your system for changes to take effect.&quot;<br></pre><p>5. Add Your Docker Hub Username and <a href="https://docs.docker.com/security/for-developers/access-tokens/">Docker Hub Access</a> token into the repository Secrets by navigating into your repository &gt; Settings &gt; Secrets and Variables and add your repository secrets as show in the image below</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*enVtrzIrQzJoc6SAH2yrjg.png" /><figcaption>Repository secrets</figcaption></figure><h3>Understanding the CI/CD Workflow</h3><p>To better grasp the workings of GitHub Actions, let’s explore a practical example using my Next.Js portfolio website.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7_G7csRSvCoS097dnaSivQ.png" /><figcaption>flow diagram represents the CI/CD pipeline</figcaption></figure><p><strong>1. Trigger:</strong></p><ul><li>The workflow is triggered by a push event to the main branch.</li></ul><p><strong>2. Build Job (</strong><strong>build):</strong></p><ul><li>This job runs on the ubuntu-latest runner.</li><li>The workflow first checks out the source code using the actions/checkout@v4 action.</li><li>Then, it builds a Docker image using the docker build command. The image is tagged with prabirkalwani/portfolio:&lt;latest&gt;.</li><li>To push the image to Docker Hub, the workflow logs in using the provided Docker username and access token stored in secrets (presumably set up beforehand).</li><li>Finally, the built image is pushed to prabirkalwani/portfolio:latest on Docker Hub.</li></ul><p><strong>3. Deploy Job (</strong><strong>deploy):</strong></p><ul><li>This job depends on the successful completion of the build job. It won&#39;t run unless the image is built successfully.</li><li>The deploy job runs on a self-hosted runner (meaning your own server or infrastructure).</li><li>It starts by pulling the latest image (prabirkalwani/portfolio:latest) from Docker Hub.</li><li>Next, it removes any existing container named prabir-website (assuming an old deployment was running).</li><li>Finally, the workflow runs the container in detached mode (-d) and maps the container port 3000 to the host port 3000. The container is named prabir-website for easier identification.</li></ul><p><strong>Overall Flow:</strong></p><ol><li>You push code to the main branch.</li><li>The workflow triggers the build job which builds and pushes the Docker image to Docker Hub.</li><li>Once built, the deploy job pulls the image, removes any old container, and starts a new container running your application.</li></ol><h3>Setting Your CI/CD Pipeline:</h3><p>Start By Completing the <a href="#1ec5">Prerequisites</a> for this Project :</p><ol><li>Connect your GitHub Runner<br><a href="https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners">GitHub Runner</a> offers a self-hosted virtual machine to run workflows</li><li>Access your GitHub repository settings<br>Click on “Actions”<br>Click on “Runners”<br>Click on “Add a new self-hosted runner”</li></ol><p>Follow the steps and Connect your EC2 instance with GitHub<br>This will enable running CI/CD processes on the EC2 instance<br>The EC2 instance will act as the self-hosted runner for your repository</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PKBvMQTyNMnJEbJIv4pVxw.png" /><figcaption>Runner settings</figcaption></figure><p>3. Configuring the <a href="https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service">self hosted runner application as a service</a><br>This will configure the self-hosted runner application as a service to automatically start the runner application when the machine starts.Follow the commands below :-</p><pre>sudo ./svc.sh install<br>sudo ./svc.sh start</pre><p>Lets write the code for the action that was explained above in this <a href="#2005">section</a> :-</p><p>To set up the workflow, navigate to the Actions tab in your repository. Next, click on the New Workflow button and select the Docker configuration option.</p><p>Then, paste the following code snippet into the workflow editor:</p><pre>name: Docker-Deploy<br><br>on:<br>  push:<br>    branches:<br>      - main<br><br>jobs:<br>  build:<br>    runs-on: ubuntu-latest<br>    steps: <br>      - name: Checkout Source<br>        uses: actions/checkout@v4<br>      - name: Build docker image<br>        run: docker build -t prabirkalwani/portfolio .<br>      - name: Login to Docker Hub<br>        run: docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_ACCESS_TOKEN }}<br>      - name: Publish image to Docker Hub<br>        run: docker push prabirkalwani/portfolio:latest<br><br>  deploy:<br>    needs: build<br>    runs-on: self-hosted<br>    steps:<br>      - name: Pull image from Docker Hub<br>        run: sudo docker pull prabirkalwani/portfolio:latest<br>      - name: Delete old container<br>        run: sudo docker rm -f prabir-website  <br>      - name: Run Docker container<br>        run: sudo docker run -d -p 3000:3000 --name prabir-website prabirkalwani/portfolio:latest</pre><p>You can modify the repository name and tag name to suit your project’s requirements. Additionally, you can modify the command is configured to monitor changes on the main branch, but you can alter this branch name as per your preferences.</p><p>4.Dockerfile for the NextJs Application</p><p>Lastly, we require a Dockerfile to containerize your Next.js application for deployment.</p><pre># Docker file for NextJS Application <br>FROM node:20-alpine3.18 as builder <br><br># Creating an app directory <br>WORKDIR /app<br><br># copying the package-lock file <br>COPY package*.json ./<br><br># running npm install here <br>RUN npm install --production <br><br># copying rest of the files <br>COPY . . <br><br># creating a build folder<br>RUN npm run build<br><br># exposing the host port<br>EXPOSE 3000<br><br># running the application <br>CMD [&quot;npm&quot;, &quot;run&quot;, &quot;start&quot;]</pre><p>Upon committing changes, your continuous integration and continuous deployment (CI/CD) pipeline will be triggered, executing the following workflow steps.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2ZAGWjCHkDiZq2jdRrZO1A.png" /><figcaption>Docker Workflow that we just created</figcaption></figure><h3>Conclusion</h3><p>This article is one of many I plan to create on Docker, DevOps, and related technologies that I’m currently exploring and learning. Sharing insights like these is genuinely enjoyable, and I look forward to creating more informative content as I further delve into containerization and DevOps practices.</p><p>Thank you for following along, If there are any better alternatives to this approach or suggestions feel free to <a href="https://prabir.in">reach out</a>.</p><h4>Bonus</h4><p>Recently, I created a bash script that retrieves system vitals for a VPS, and I found the process immensely enjoyable. I encourage you to take a look at it as well.</p><pre>#!/bin/bash<br><br>#system_info.sh file<br><br># to run this file first : chmod +x system_info.sh<br># then you can run it using : ./system_info.sh<br># CPU Usage<br>CPU_USAGE=$(top -bn1 | grep &quot;Cpu(s)&quot; | sed &quot;s/.*, *\([0-9.]*\)%* id.*/\1/&quot; | awk &#39;{print 100 - $1&quot;%&quot;}&#39;)<br><br># Disk Usage<br>DISK_USAGE=$(df -h | awk &#39;$NF==&quot;/&quot;{printf &quot;Disk Usage: %.2f%\n&quot;, $5}&#39;)<br><br># Memory Usage<br>MEMORY_USAGE=$(free | awk &#39;/Mem/{printf(&quot;Memory Usage: %.2f%\n&quot;), $3/$2*100}&#39;)<br><br># System Uptime<br>UPTIME=$(uptime -p)<br><br># Load Average<br>LOAD_AVERAGE=$(uptime | awk -F&#39;average:&#39; &#39;{ print $2 }&#39; | awk &#39;{ print $1, $2, $3 }&#39;)<br><br># Display Information<br>echo &quot;System Information:&quot;<br>echo &quot;-------------------&quot;<br>echo &quot;CPU Usage: $CPU_USAGE&quot;<br>echo &quot;Memory Usage: $MEMORY_USAGE&quot;<br>echo &quot;Disk Usage: $DISK_USAGE&quot;<br>echo &quot;Uptime: $UPTIME&quot;<br>echo &quot;Load Average: $LOAD_AVERAGE&quot;</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YZyP6pmBXQ2PL54EFno5qQ.png" /><figcaption>a working example</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0faabd032291" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Leveraging React and Firebase for Efficient CRUD Operations in a College Management System]]></title>
            <link>https://medium.com/@prabir.kalwani/leveraging-react-and-firebase-for-efficient-crud-operations-in-a-college-management-system-af65f7096be9?source=rss-19f2379194fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/af65f7096be9</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[firestore-rules]]></category>
            <category><![CDATA[crud]]></category>
            <category><![CDATA[firestore]]></category>
            <category><![CDATA[firebase]]></category>
            <dc:creator><![CDATA[Prabir Kalwani]]></dc:creator>
            <pubDate>Sun, 24 Mar 2024 19:46:59 GMT</pubDate>
            <atom:updated>2024-03-24T19:46:59.069Z</atom:updated>
            <content:encoded><![CDATA[<h4>A Secure React-based Web application with Firebase Authentication and Scalable Document Database.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*85ed-iGCsw02EBbF8HF28Q.png" /></figure><p>Today, we( <a href="https://medium.com/u/19f2379194fe">Prabir Kalwani</a> , <a href="https://medium.com/u/ff7e519222e1">Snehil Sinha</a>, <a href="https://medium.com/u/0af4075332e1">Aayush Shah</a>, <a href="https://medium.com/u/a515301e10e6">Akshad Gawde</a>, <a href="https://medium.com/u/05c7dfc8241e">Karan Dwari</a>, and <a href="https://medium.com/u/642d1fa43634">ShashankShekhar</a>) will be guiding you through the process of building a Secure React-based Web application with Firebase Authentication and Scalable Document Database.</p><h4>Introduction</h4><p>This idea came to fruition by being frustrated by the college portal’s sluggish updates for assignments and attendance tracking. Waiting for changes felt like an eternity, and seeing attendance promptly? Forget about it! That’s when our engineering spirit started to work: why not create a prototype Firebase and Cloud Firestore integration with React?</p><p>Before we begin lets understand why are we using React / Firebase in the first case ?</p><p>Firebase offers scalable backend services, Firestore provides advanced NoSQL querying, and React excels in creating dynamic user interfaces. Together, they enable efficient development of high-performance and real-time applications such as a college portal.</p><h4>Installation</h4><p>Begin by initialising a React app using pnpm create vite.</p><blockquote>Follow the provided video guide to set up your Firebase console.</blockquote><p>Once you&#39;ve set up your Firebase project, add a new application to Firebase, selecting a web app. Within your project&#39;s src folder, create a firebase.js file and an .env file to store your Firebase configuration.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F926808936%3Fapp_id%3D122963&amp;dntp=1&amp;display_name=Vimeo&amp;url=https%3A%2F%2Fvimeo.com%2F926808936&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1821306280-731491d43ec09a62a07fd75b89a47491fe0706bf41aea07f9b14c432c6ce1dde-d_1280&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1247" frameborder="0" scrolling="no"><a href="https://medium.com/media/298e6630f9c8feb246a04150183bd84f/href">https://medium.com/media/298e6630f9c8feb246a04150183bd84f/href</a></iframe><p>In the firebase.js file, import the necessary Firebase SDK functions, and configure Firebase using the environment variables specified in your .env file.</p><pre>touch .env // fancy way just to create the file</pre><pre>VITE_APIKEY= YOUR_KEY_VALUE<br>VITE_AUTHDOMAIN= YOUR_KEY_VALUE<br>VITE_PROJECTID= YOUR_KEY_VALUE<br>VITE_STORAGEBUCKET= YOUR_KEY_VALUE<br>VITE_MESSAGESENDERID= YOUR_KEY_VALUE<br>VITE_APPID= YOUR_KEY_VALUE<br>VITE_MEASUREMENTID= YOUR_KEY_VALUE</pre><pre>touch Firebase.js  // fancy way just to create the file</pre><pre>// Import the functions you need from the SDKs you need<br>import { initializeApp } from &quot;firebase/app&quot;;<br>import { getAnalytics } from &quot;firebase/analytics&quot;;<br>import { getAuth } from &quot;firebase/auth&quot;;<br>// TODO: Add SDKs for Firebase products that you want to use<br>// https://firebase.google.com/docs/web/setup#available-libraries<br><br>// Your web app&#39;s Firebase configuration<br>// For Firebase JS SDK v7.20.0 and later, measurementId is optional<br>// im using an env file here <br>const firebaseConfig = {<br>  apiKey: import.meta.env.VITE_APIKEY,<br>  authDomain: import.meta.env.VITE_AUTHDOMAIN,<br>  projectId: import.meta.env.VITE_PROJECTID,<br>  storageBucket: import.meta.env.VITE_STORAGEBUCKET,<br>  messagingSenderId: import.meta.env.VITE_MESSAGESENDERID,<br>  appId: import.meta.env.VITE_APPID,<br>  measurementId: import.meta.env.VITE_MEASUREMENTID,<br>};<br><br>// Initialize Firebase<br>const app = initializeApp(firebaseConfig);<br>export const auth = getAuth(app);<br>const analytics = getAnalytics(app);<br><br>export default app;</pre><pre>npm install firebase // installing dependencies for firebase</pre><p>In your Firebase project, navigate to the Firestore Database section. Initialise the database, then proceed to the rules section.Replace the existing rules with the provided code snippet.</p><pre>// The provided code snippet sets your Firestore rules to allow unrestricted read and write access<br><br>rules_version = &#39;2&#39;;<br><br>service cloud.firestore {<br>  match /databases/{database}/documents {<br>    match /{document=**} {<br>      allow read, write: if true;<br>    }<br>  }<br>}</pre><p>Congratulations! You’ve successfully set up Firebase Authentication and Cloud Firestore for your React application. Now, you’re ready to start writing code to leverage these services in your project.</p><h4>Authentication &amp; Database</h4><p>Before authentication we need to store the user data in a context file you can use redux or any other service for this Im Using createContext&amp; useContext Hook by React</p><p>1.AuthContextProvider:</p><ul><li>Sets up a React context to manage user authentication state in the application.</li><li>Provides functions like createUser, signIn, and logout to interact with Firebase Authentication services.</li><li>Utilises Firebase’s onAuthStateChanged method to keep track of the current user and update the context accordingly.</li><li>Exposes the user object and authentication functions via the context provider for use throughout the application.</li></ul><pre>// Auth Context File <br>import { createContext, useContext, useEffect, useState } from &quot;react&quot;;<br>import {<br>  createUserWithEmailAndPassword,<br>  signInWithEmailAndPassword,<br>  signOut,<br>  onAuthStateChanged,<br>} from &quot;firebase/auth&quot;;<br>import { auth } from &quot;../firebase&quot;;<br><br>const UserContext = createContext();<br><br>export const AuthContextProvider = ({ children }) =&gt; {<br>  const [user, setUser] = useState({});<br><br>  const createUser = (email, password) =&gt; {<br>    return createUserWithEmailAndPassword(auth, email, password);<br>  };<br><br>  const signIn = (email, password) =&gt; {<br>    return signInWithEmailAndPassword(auth, email, password);<br>  };<br><br>    const logout = () =&gt; {<br>      return signOut(auth);<br>    };<br><br>  useEffect(() =&gt; {<br>    const unsubscribe = onAuthStateChanged(auth, (currentUser) =&gt; {<br>      setUser(currentUser);<br>    });<br>    return () =&gt; {<br>      unsubscribe();<br>    };<br>  }, []);<br><br>  return (<br>    &lt;UserContext.Provider value={{ createUser, user, logout, signIn }}&gt;<br>      {children}<br>    &lt;/UserContext.Provider&gt;<br>  );<br>};<br><br>export const UserAuth = () =&gt; {<br>  return useContext(UserContext);<br>};</pre><p>Lets a more detailed understanding of CRUD level Operations using Signup And signIN</p><p>handleSubmit Function:</p><ul><li>Triggers upon form submission, preventing default behavior.</li><li>Attempts to create a new user account using Firebase’s createUser function.</li><li>If successful, links user UID to Firestore data, navigates to account page, and displays success notification.</li></ul><p>linkUidToFirestore Function:</p><ul><li>The linkUidToFirestore function serves the purpose of associating the user&#39;s unique identifier (UID) with Firestore documents containing additional user information.</li><li>It ensures that user data is properly structured and stored in Firestore for further use and retrieval within the application.</li><li>It accesses the Firestore database instance (db) previously initialized within the component.</li><li>Documents are organized within collections, with each document containing specific user-related data.</li><li>Upon invocation, the function creates or updates a document within the “Users” collection in Firestore.</li><li>This document typically contains essential user information such as UID, email, user type, and course.</li><li>Additionally, the function establishes subcollections within the user document for specific purposes, such as attendance, assignments, and ID card details.</li><li>Within these subcollections, default or empty documents are created to accommodate data related to attendance records, assignments, and ID card information.</li></ul><blockquote>we use aysnc and await in these functions for better handling of promises</blockquote><pre>// SignUp Logic <br> const { theme } = useTheme();<br>  const { createUser } = UserAuth();<br>  const [placeholder, setPlaceholder] = useState({<br>    email: &quot;&quot;,<br>    password: &quot;&quot;,<br>  });<br>  const [email, setEmail] = useState(&quot;&quot;);<br>  const [password, setPassword] = useState(&quot;&quot;);<br>  const [error, setError] = useState(&quot;&quot;);<br>  const [course, setCourse] = useState(&quot;&quot;);<br>  const navigate = useNavigate();<br>  const db = getFirestore();<br><br>  const courses = [&quot;BTECH&quot;, &quot;MBATECH&quot;, &quot;BTI&quot;, &quot;MCA&quot;];<br><br>  const linkUidToFirestore = async (uid, email, course) =&gt; {<br>    const val = doc(db, &quot;Users&quot;, uid);<br>    await setDoc(<br>      val,<br>      { uid, email, type: &quot;student&quot;, course: course },<br>      { merge: true }<br>    );<br>    const attendanceCollection = collection(val, &quot;attendance&quot;);<br>    await setDoc(doc(attendanceCollection, &quot;day1&quot;), {<br>      present: true,<br>    });<br>    const assignmentCollection = collection(val, &quot;assignment&quot;);<br>    await setDoc(doc(assignmentCollection, &quot;assign1&quot;), {<br>      present: true,<br>    });<br>    const idCollection = collection(val ,&quot;ID_card&quot;);<br>    await setDoc(doc(idCollection,&quot;Card&quot;) , {<br>      Name : &quot;&quot;,<br>      DOB : &quot;&quot;,<br>      BloodGroup : &quot;&quot;,<br>      Department : &quot;&quot;,<br>      Course : &quot;&quot;,<br>      Email : &quot;&quot;,<br>      SAP_ID : &quot;&quot;,<br>      Year : &quot;&quot;,<br>      Address :&quot;&quot;,<br>      ClgEmail : &quot;&quot;,<br>    });<br>  };<br><br>  const handleSubmit = async (e) =&gt; {<br>    e.preventDefault();<br>    setError(&quot;&quot;);<br>    try {<br>      const response = await createUser(email, password);<br>      if (response.user) {<br>        await linkUidToFirestore(response.user.uid, email, course);<br>        navigate(&quot;/account&quot;);<br>      }<br>      toast.success(&quot;Account Created Successfully&quot;);<br>    } catch (error) {<br>      setError(error.message);<br>      toast.error(error.message);<br>    }<br>  };<br><br>  useEffect(() =&gt; {<br>    document.body.style.overflow = &quot;hidden&quot;;<br>    return () =&gt; {<br>      document.body.style.overflow = &quot;&quot;;<br>    };<br>  }, []);</pre><p>If your code is functioning properly, your database should exhibit the following structure.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NDkuJVvptvg1XRh0RRbL8w.png" /></figure><h4>Protective Routing</h4><p>To safeguard against potential security breaches from curious engineers within our college, we’ll implement protective routes to prevent backtracking through different links. This measure aims to ensure our system’s security and protect sensitive information from unauthorized access.</p><pre>// protectedRoutesByType.js<br>import React, { useEffect } from &quot;react&quot;;<br>import { Navigate } from &quot;react-router-dom&quot;;<br>import { getDoc, doc, getFirestore } from &quot;firebase/firestore&quot;;<br>import { UserAuth } from &quot;../Context/AuthContext&quot;;<br><br>const ProtectedRoutesByType = ({ children }) =&gt; {<br>  const { user, loading } = UserAuth();<br>  const db = getFirestore();<br><br>  useEffect(() =&gt; {<br>    const fetchUserType = async () =&gt; {<br>      if (user) {<br>        try {<br>          const userDocRef = doc(db, &#39;Users&#39;, user.uid);<br>          const userDocSnapshot = await getDoc(userDocRef);<br>          if (userDocSnapshot.exists()) {<br>            const userData = userDocSnapshot.data();<br>            const userType = userData.type;<br>            if (userType !== &quot;XYZ&quot;) {<br>              window.location.href = &quot;/account&quot;;<br>            }<br>          }<br>        } catch (error) {<br>          console.error(&quot;Error fetching user type:&quot;, error);<br>        }<br>      }<br>    };<br><br>    fetchUserType();<br>  }, [user, db]);<br><br>  if (loading) {<br>    return &lt;div&gt;Loading...&lt;/div&gt;;<br>  }<br><br>  if (!user) {<br>    return &lt;Navigate to=&quot;/&quot; /&gt;;<br>  }<br><br>  return children; <br>};<br><br>export default ProtectedRoutesByType;</pre><p>Authentication and User Type Retrieval: The ProtectedRoutesByType component first checks the user’s authentication status and loading state using the UserAuth hook in the React application.</p><p>User Type Validation: Upon successful authentication, the component retrieves the user’s document from Firebase Firestore, extracting their user type. It then compares this user type with an expected value (e.g., “XYZ”) to determine access to protected routes.</p><p>Routing and Redirection: If the user is authenticated and their type matches the expected value, the protected routes are rendered seamlessly using React Router’s Navigate component. However, if there’s a mismatch in user type, the user is redirected to the account page using window.location.href. In the case of authentication failure, users are redirected to the home page.</p><p>To use the above protected Routes :-</p><pre>&lt;Route path=&quot;/fac/home&quot; element={&lt;ProtectedRoutesByType&gt;&lt;Home /&gt;&lt;/ProtectedRoutesByType&gt;} /&gt;</pre><h4>Conclusion</h4><p>This guide offers a thorough walkthrough of integrating React with Firebase to build a robust college management system and a scalable database using Firestore Cloud.</p><p>Thank you for following along, and feel free to refer to the provided resources or reach out for further clarification or <a href="mailto:prabir.kalwani@gmail.com">assistance</a>.</p><p>references:-</p><ul><li><a href="https://github.com/PrabirKalwani/NMIMS-Student-Portal.git">GitHub - PrabirKalwani/NMIMS-Student-Portal: A redevelopment of the NMIMS College Student Portal leveraging Firebase and React, employing .</a></li><li><a href="https://portal.prabir.in">Portal SVKM</a></li><li><a href="https://firebase.google.com/docs/firestore/manage-data/structure-data">Choose a data structure | Firestore | Firebase</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=af65f7096be9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Flutter MVVM Architecture & Obfuscation]]></title>
            <link>https://medium.com/@prabir.kalwani/flutter-mvvm-architecture-obfuscation-3f34d2dadb67?source=rss-19f2379194fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/3f34d2dadb67</guid>
            <category><![CDATA[obfuscation]]></category>
            <category><![CDATA[mvvm]]></category>
            <category><![CDATA[production]]></category>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[secure-coding]]></category>
            <dc:creator><![CDATA[Prabir Kalwani]]></dc:creator>
            <pubDate>Tue, 12 Mar 2024 10:01:19 GMT</pubDate>
            <atom:updated>2024-03-12T10:01:19.829Z</atom:updated>
            <content:encoded><![CDATA[<p>Writing Clean Good Production Ready Code in Flutter</p><p>Knowing how to write production-level code is essential for developers, and it involves following specific methodologies that depend from organisation to organisation. For the case of Flutter, we have multiple such Architectures to write production ready code such as MVVM, MVP, and MCP.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yFAHA4F3eAMNPBCeg9X2Lw.png" /></figure><h3>Prerequisites</h3><p>Flutter Installation</p><ul><li>You have to first install Flutter using the flutter documentation Below :-</li></ul><p><a href="https://docs.flutter.dev/get-started/install">Choose your development platform to get started</a></p><p>After This You can proceed to clone the following Repository</p><p><a href="https://github.com/PrabirKalwani/MVVM_Boilerplate">GitHub - PrabirKalwani/MVVM_Boilerplate</a></p><p>Thats All Congratulations You have successfully Setup an Flutter Application with basic MVVM</p><h3>What is MVVM ?</h3><h4>Introduction</h4><p>MVVM Stands for model view view model.<br>Lets Create MVVM button application where each click results in an incremental change in its value, reflecting the total number of clicks :-</p><p>Model:</p><ul><li>Represents the user data, for the case of the application the above code it is counter to count the number of times the user has clicked.</li><li>Model Can also be used to interact with external services like F backend APIs, or databases.</li></ul><p>View:</p><ul><li>Contains the UI elements for the counter page which is the button which is to be clicked and the display of the counter variable .</li><li>Receives data and state updates from the ViewModel and displays them on the screen.</li><li>Captures user interaction events like button clicks and text field changes.</li></ul><p>ViewModel:</p><ul><li>Acts as the bridge between the View and the Model.</li><li>Exposes functions for user interaction events (e.g., button click.</li><li>Handles business logic like validation, error handling, and data formatting.</li><li>Fetches data from the Model and exposes it to the View in a suitable format.</li><li>Updates the UI by notifying the View when the state changes.</li></ul><p>State Management:</p><ul><li>Various state management solutions can be used to connect the ViewModel with the View. Popular options include:</li><li>Provider: Offers a simple and powerful way to manage state with ChangeNotifier classes. (being used in this project)</li><li>Riverpod: Provides dependency injection and state management with streams and providers.</li><li>GetIt and Bloc: Alternative state management libraries with different approaches.</li></ul><p>Additional Considerations:</p><ul><li>Navigation: Use a separate navigation service to handle transitions between different screens based on the authentication state.</li><li>Error Handling: Clearly display error messages to the user through the ViewModel and View.</li><li>Testing: Utilize unit and widget testing to ensure the functionality of each component individually and as a whole.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/318/1*eyMLSqVz3Trpl41Nz9IShg.png" /><figcaption>file structure of a MVVM Application</figcaption></figure><p>Great , Now you have developed a key undertanding of the flutter MVVM Application . Moving to how to secure your Flutter Enviornment .</p><h3>How To Secure Your Environment</h3><h4>Introduction</h4><p>There are multiple ways but for the simplicity of understanding we will Obfuscation and Environment Variables .</p><p>Obfuscation in Flutter Refers to the process of transforming your app’s binary code into a more complex and obscure form while preserving its functionality. This makes it harder for humans to understand the code and hinders reverse engineering efforts.</p><h4>Implementation</h4><p>Lets Create the example of the Obfuscation using the current project:-</p><blockquote>Note :- Please Dont commit this folder / file to Github</blockquote><ul><li>We can create a env folder in you project lib directory</li><li>Add envied to pubsec.yaml and pub get the package (install the envied package to your project)</li><li>post this create a .env file in your directory consisting of your environment secrets</li></ul><pre>YOUR_API_KEY = justasimpleapikey</pre><ul><li>After that create a file called env.g.dart which comprises of</li></ul><pre>import &#39;package:envied/envied.dart&#39;;<br>part &#39;env.g.dart&#39;;<br>@Envied(path: &#39;.env&#39;)<br>abstract class Env {<br>  @EnviedField(varName: &quot;YOUR_API_KEY&quot;, obfuscate: true)<br>  static final String yourapikey = _Env.yourapikey;<br>  <br>}</pre><ul><li>Post this run the following command to Obfuscate your project</li></ul><pre>dart run build_runner build</pre><ul><li>To declare / call your api key just use the following syntax</li></ul><pre>apiKey: Env.YOUR_API_KEY,</pre><p>You have now Successfully completed your env Obfuscation to protect your Environment secrets locally</p><p>I hope this article was helpful in making you understand the basics of how to write production ready code and in a secure manner.</p><h3>Queries</h3><p>For any issues with the above program please contact me and ill try to reply as soon as possible</p><p><a href="mailto:prabir.kalwani@gmail.com">prabir.kalwani@gmail.com</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3f34d2dadb67" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Your Own Secure Proxy Server on the Cloud]]></title>
            <link>https://medium.com/@prabir.kalwani/creating-your-own-secure-proxy-server-on-the-cloud-d3b33ca338a8?source=rss-19f2379194fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/d3b33ca338a8</guid>
            <category><![CDATA[ssh]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[vpn]]></category>
            <dc:creator><![CDATA[Prabir Kalwani]]></dc:creator>
            <pubDate>Sun, 26 Nov 2023 19:16:28 GMT</pubDate>
            <atom:updated>2023-11-27T04:55:24.681Z</atom:updated>
            <content:encoded><![CDATA[<h4>Establish a Secure Gateway to the Internet with Your Cloud-Based Proxy Server</h4><h4>Introduction</h4><p>Have you ever faced the frustration of trying to access a website, only to find it blocked on your college or office Wi-Fi? I know the feeling all too well. But fear not, because I’ve got a solution that will blow your mind — building your own proxy server on the cloud!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fdrXOB8KGQjcOjgcA9krog.png" /></figure><p><a href="#dfdb"><strong>Navigate to the steps by clicking here</strong></a>.</p><p>This idea struck me while I was preparing for my end-semester exams and couldn’t afford to waste time on blocked websites. In this article, I’ll be your guide on how to create your very own proxy server that will help you bypass any pesky website blocks and enjoy unrestricted internet access. Excited yet? Let’s get started!</p><p>So For Those Who Don’t Know what is a <strong>Proxy Server</strong> ?<br>A proxy server acts as a bridge between a user’s device and the internet, serving various purposes depending on the user’s needs, such as enhancing privacy, accessing geo-restricted content, optimising network performance, bypassing content filters, and facilitating secure remote access, making it a versatile tool for digital empowerment. So now lets see how to make it</p><figure><img alt="Proxy Server Description" src="https://cdn-images-1.medium.com/max/1024/1*ItQe20HZ5G_m_G5Yt0FqLg.jpeg" /><figcaption>Proxy Server Acts Like an Intermediate</figcaption></figure><h4>Getting Started</h4><p>As physical servers can be expensive, it’s not a necessity to own one. Cloud services like AWS, Azure, and GCP offer a great alternative. You can use a free-tier server with good bandwidth and still get the job done. In this example, I’ll be using AWS EC2, which has budget-friendly options to create a proxy server that’s both cost-effective and powerful.</p><p>Let’s dive into how we can leverage AWS EC2 to build a server that not only protects your online activities but also fits within your budget.</p><p>For This Fire up your AWS Console and go EC2 ( Elastic Compute)</p><ul><li>Initiate a new AWS Instance.</li><li>Select Ubuntu as your preferred operating system.</li><li>Opt for a key pair login for enhanced security.</li><li>Configure the instance with a basic amount of storage.</li><li>And then Launch Your Instance</li></ul><p>Now Connect to your instance using SSH and run the following Maintaince Commands</p><pre>Sudo apt upgrade <br>Sudo apt update</pre><p>Most Linux Distro’s Come with SSH installed … We will be leveraging this for our proxy server by using something called SSH tunnel.</p><p>Now, An SSH Tunnel also known as an SSH port forwarding, is a secure way to establish a connection between a local and a remote computer through an encrypted channel. Basically A connection to our Proxy Server.</p><h4>The Process</h4><ol><li>So Lets write a command to connect to our instance <br>Open Up Your Terminal and Run</li></ol><pre>ssh -i  &quot;[PATH OF YOUR KEY ]&quot; -D 1369 -N -C ubuntu@[YOUR PUBLIC IP]</pre><p>To Better Understand this we can break down</p><ul><li><strong><em>ssh -i ”[PATH OF YOUR KEY]”</em></strong> :- This option specifies the path to the private key file used for authentication</li><li><strong><em>D 1369 </em></strong>:- This option enables dynamic port forwarding. It opens a local port (1369 in this case) and sets up a SOCKS proxy on that port.</li><li><strong><em>-N</em></strong> :- This option tells SSH not to execute any commands on the remote server</li><li><strong><em>-C</em></strong> :- This option enables compression during data transfer.</li><li><strong><em>ubuntu@[YOUR PUBLIC IP] :- </em></strong>This specifies the username (ubuntu in this case) and the public IP address of the remote server you want to connect to</li></ul><blockquote>Optional Step</blockquote><p>We Can Save Us Some Time whenever we write this command by adding the following to our <a href="https://www.ssh.com/academy/ssh/config">ssh config</a> file :-</p><pre>Host VPN<br> Hostname &lt;YOUR IP&gt;<br> User ubuntu<br> IdentityFile &lt;YOUR FILEPATH&gt;<br> DynamicForward 1369<br> RequestTTY no<br> Compression yes<br> ExitOnForwardFailure yes<br> LogLevel ERROR</pre><p>You can now run this by the following command :-</p><pre>ssh VPN -N</pre><p>Now We have Successfully Established a connection to Our Server</p><p>For a more beginner-friendly approach, we’ll integrate this proxy with our web browser instead of applying it globally. So Fire up your web browser , Im going to be using Firefox for this demo</p><p>Now i will open up my firefox settings and search for proxy setting then a pop like the one shown here will open :-</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c_DY5AHI4ml7xpx5qbmd7g.png" /><figcaption>Firefox &gt; Settings &gt; Network Settings &gt; Configure how firefox connects to the internet</figcaption></figure><p>After this select Manual Proxy Configuration and in the SOCKS Host put in localhost 1369 as your configuration as shown in the image above and thats it your proxy is setup .</p><p>You Can Refer this quick Demonstration To understand more about it :-</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F888006356%3Fapp_id%3D122963&amp;dntp=1&amp;display_name=Vimeo&amp;url=https%3A%2F%2Fvimeo.com%2F888006356&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1758815184-787ad91db7ac2b46606d00dc3e412a395931911b20e0d4f402a9d96956e80809-d_1280&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1247" frameborder="0" scrolling="no"><a href="https://medium.com/media/1cdd384c0a10b6629fd77f7811bcd528/href">https://medium.com/media/1cdd384c0a10b6629fd77f7811bcd528/href</a></iframe><h4>Conclusion</h4><p>In this blog post, we have discussed how to establish a secure gateway to the internet with your cloud-based proxy server.<br>We have covered the basics of proxy servers, why you might want to use one, and how to set one up using AWS EC2 and Firefox.And We have also seen a video demonstration of the process.</p><p>Thank you for taking the time to read this guide on setting up your own cloud-based proxy server.All the References for the technologies used above are given below.</p><p>Feel free to <a href="https://prabir.in">reach out</a> to me if you have any queries/Suggestions</p><p><strong><em>References:</em></strong></p><ul><li><a href="https://www.ssh.com/academy/ssh/config">SSH config file syntax and how-tos for configuring the OpenSSH client</a></li><li><a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html">What is Amazon EC2?</a></li><li><a href="https://www.ssh.com/academy/ssh/tunneling">What is an SSH Tunnel &amp; SSH Tunneling?</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d3b33ca338a8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hosting a Website in Seconds : A Step-by-Step Guide to Using Amazon AWS S3 Serverless Platform]]></title>
            <link>https://medium.com/@prabir.kalwani/hosting-a-website-in-seconds-a-step-by-step-guide-to-using-amazon-aws-s3-serverless-platform-abdc6582a91f?source=rss-19f2379194fe------2</link>
            <guid isPermaLink="false">https://medium.com/p/abdc6582a91f</guid>
            <category><![CDATA[hosting]]></category>
            <category><![CDATA[beginners-guide]]></category>
            <category><![CDATA[s3]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Prabir Kalwani]]></dc:creator>
            <pubDate>Wed, 16 Aug 2023 17:01:07 GMT</pubDate>
            <atom:updated>2023-11-24T07:14:04.355Z</atom:updated>
            <content:encoded><![CDATA[<h3>Hosting a Website in Seconds : A Step-by-Step Guide to Using Amazon AWS S3 Serverless Platform</h3><p>Being a novice programmer, I’m captivated by websites . While creating digital realms feels natural, a key question arises: how do I share these websites online?</p><p>This is the start of a series that aims to make web hosting easy to understand. We’ll start with the basics, move to more advanced topics, and finally explore the detailed world of web hosting. The series will guide you through the basics and then into more complicated aspects step by step</p><p>In this article , we embark on a journey learning of web hosting, ushering you through each stage, each concept, and each practice. From the rudimentary building blocks to the more sophisticated mechanics, I’ll provide you with a comprehensive understanding of hosting websites using AWS S3, ensuring that by the series’ end, you’ll have traversed the entire A-to-Z spectrum of web hosting.</p><h3>So, what exactly is AWS ?</h3><p>Think of AWS (Amazon Web Services) as owning land or property, but in the digital world. When you own property in a country, you have your own space where you can build things, such as a house or a workshop. Similarly, in the digital realm, when you use AWS, you’re essentially “owning” a space on their cloud platform where you can set up and run various types of digital tools and services.</p><p>Imagine you’re a craftsman who needs a place to build things. Instead of constructing your own workshop from scratch, which can take a lot of time and resources, you decide to lease a ready-made workshop in a business park. This workshop comes fully equipped with tools, machinery, and utilities, and you only pay for what you use. Plus, if you ever need more space or specialised equipment, you can easily upgrade your workshop without the hassle of building or maintaining it yourself.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1018/1*hV2WjPE4TL2PshQYkCC1fQ.png" /><figcaption>This map illustrates the locations of AWS data centers where your website will be hosted.</figcaption></figure><h3><strong>Prerequisites</strong> :</h3><p><strong>AWS account</strong> :- If you Dont have an AWS account , click here to <a href="https://portal.aws.amazon.com/billing/signup?nc2=h_ct&amp;src=header_signup&amp;redirect_url=https://aws.amazon.com/registration-confirmation#/start/email">register</a></p><h3>Getting Started :</h3><p>Let’s begin by organising your website files into a dedicated folder. This beginner-friendly tutorial will cover HTML and CSS hosting, while the next tutorial will delve into hosting with React JS — so keep an eye out for that.</p><p>If you’re currently without HTML files, don’t fret. We’ve prepared demo files for you, accessible through this GitHub link. <a href="https://github.com/PrabirKalwani/404page.git">Click here</a> to access them and enrich your learning journey.</p><p><strong>For the people using GitHub for the files :-</strong></p><p>Clone the Github Repository to your local machine by the command below</p><pre>git clone https://github.com/PrabirKalwani/404page.git</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*loTHtRQgvitR2tqieWo5FQ.gif" /><figcaption>git cloning the repo</figcaption></figure><h4>Create A S3 Bucket:-</h4><ol><li>Access your AWS dashboard and locate the S3 (Simple Storage Service) through the search function. Once you’re on the S3 dashboard, continue with the next steps.</li><li>Navigate to the left-hand side and select <strong>“Buckets.”</strong> Proceed by clicking on the <strong>“Create Bucket”</strong> option, <em>highlighted in yellow.</em> <br>Think of a bucket as analogous to a Google Drive, where you can store your website files.</li><li>Moving forward, configure the bucket with general settings. Employ your domain name as the bucket name, as this setup will be employed for hosting purposes. If you lack a domain name, feel free to use a name of your preference.</li><li>Subsequently, click on <strong>“ACLs”</strong> to enable Access Control Lists (ACLs). More about ACLS <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html">here</a></li><li>It’s advisable to choose the region closest to your location. This reduces website latency and eliminates the need for a Content Delivery Network (CDN). Further details about CDNs will be covered in the upcoming article.</li><li>Within this setup, opt to grant unrestricted access to the bucket.</li><li>Subsequently, proceed to create your bucket by clicking the designated button. For a comprehensive walkthrough, a video outlining the entire process is provided below.</li></ol><blockquote>While it’s recommended to carefully review each security rule for enhanced safety, for the sake of efficiency, we’re proceeding with permitting public access for now.</blockquote><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F855124745%3Fapp_id%3D122963&amp;dntp=1&amp;display_name=Vimeo&amp;url=https%3A%2F%2Fvimeo.com%2F855124745&amp;image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1711348518-818050e1d59f659a5ea5d82910705f35516df8c55dc61675344121e75b8daf3e-d_1280&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=vimeo" width="1920" height="1355" frameborder="0" scrolling="no"><a href="https://medium.com/media/26460d2263489c89bdd45fc6d2302686/href">https://medium.com/media/26460d2263489c89bdd45fc6d2302686/href</a></iframe><h4>Make The Bucket Ready For Hosting</h4><ol><li>Following this, proceed to upload all your files and directories to your S3 bucket</li><li>Select the checkbox to highlight all files and folders. Then, access the “Actions” menu and choose the option to make them public by utilizing the ACL feature.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5Wi9ipYJpOr7Xwr66Y9g2A.png" /></figure><h4>Host Your Files</h4><p>Navigate to the upper section and select “Properties.” Proceed to scroll down to the “Static Website Hosting” option. Activate this feature and proceed to input the name of your primary HTML file in the designated “Index Document” tab.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HxLGDn_gbTqGQOKNqMyc2g.gif" /></figure><p>Subsequently, return to the properties tab where you’ll find a prepared link for your website.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TMFGtWDZQsUN9lJAd7a5oA.png" /></figure><h3>Conclusion</h3><p>In conclusion, Amazon S3 offers an accessible hosting solution with user-friendly features. However, this convenience comes at the cost of potential security vulnerabilities.</p><p>On the positive side, it simplifies file management and accommodates varying traffic levels while being cost-effective and ensuring high availability.</p><p>Conversely, limitations in customization, security measures, absence of server-side scripting, and potential performance constraints should be considered.</p><p>Deciding on Amazon S3 as a hosting solution requires weighing its ease of use against its security and functionality trade-offs, depending on your project’s specific requirements.</p><p>The subsequent pair of articles will explore the implementation of Server Hosting through NGINX Proxy Manager, Docker, AWS EC2, SSL Certificates, and Cloudflare.</p><p>This approach offers several advantages, including enhanced security, scalability, streamlined management through Docker, reliable SSL encryption, and improved performance through Cloudflare’s content delivery network.</p><p>Feel Free to <a href="http://prabir.in">react out</a> to me if you have any feedback / queries</p><p>Special Thanks to <a href="https://medium.com/u/4f5d437db10b">Darsh Mashru </a>and <a href="https://medium.com/u/424d673d3981">Aryan Irani </a>for inspiring me to write this article</p><p><em>References:-</em></p><ul><li><a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html">Hosting a static website using Amazon S3</a></li><li><a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingObjects.html?icmpid=docs_amazons3_console#access-control">Amazon S3 objects overview</a></li><li><a href="https://aws.amazon.com/what-is/cdn/">What is a CDN? - Content Delivery Network Explained - AWS</a></li><li><a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html">Buckets overview</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=abdc6582a91f" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>