Deploying a MERN application over Kubernetes
Tags: devops, kubernetes, mongodb, react
Published: 2023-01-30 09:52:31

Deploying a MERN(mongo-db, express, react-js, node-js) application using kubernetes.
This is a simple authentication application where the users can Register and Login. The login details of the users are stored in mongo-db database.
We are using React-js for the front end.

https://github.com/rohitreddyk33/dock

 Registration page using React-js. The requests are made through API calls. 
---------

```


import {React,useState} from 'react'

function Register() {
  const[name,setName]=useState('')
  const[email,setEmail]=useState('')
  const[password,setPassword]=useState('')



  async function registerUser(event){
    event.preventDefault()
  const response=await fetch('http://<your service name after creating a service yaml file>.default.svc.cluster.local:7070/api/register',{
      method:'POST',
      headers:{
        'Content-Type':'application/json',
      },
      body:JSON.stringify({
        name,email,password
      }),
    })
    const data=await response.json()
    console.log(data)
    

  }
  return (
   <div>
    <h1>register</h1>
    <form onSubmit={registerUser}>
      <input type ="text" value={name} onChange={(e)=>setName(e.target.value)} placeholder="name"/>
      <input type ="email" value={email} onChange={(e)=>setEmail(e.target.value)} placeholder="email"/>
      <input type ="password" value={password} onChange={(e)=>setPassword(e.target.value)} placeholder="password"/>
      <input type="submit" value="register"/>
    </form>
   </div>

  )
  }

export default Register;
```

------
Login page : If the users are already registered then they'll be able to view a page after logging in. Duplicate E-mails can't be used.
```
import { React, useState } from 'react'
import { useNavigate } from 'react-router-dom'

function Login() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  const navigate=useNavigate()
  function loginUser(event) {
    event.preventDefault()
    fetch('http://<your service name after creating a service yaml file>.default.svc.cluster.local:7070/api/login', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        email, password
      }),
    }).then(res =>{
      return res.json();
    }).then(res =>{
      if(res.status==='ok'){
        localStorage.setItem('user',JSON.stringify(res))
      }
      
      navigate('/home')
    }) 
  }
  return (
    <div>
      <h1>Login</h1>
      <form onSubmit={loginUser}>
        <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="email" />
        <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="password" />
        <input type="submit" value="login" />
      </form>
    </div>

  )
}

export default Login;
```
--------
A basic home page after logging in: 

```
import React from 'react'

function Home() {
  return (
    <div>Welcome User</div>
  )
}

export default Home
```

------
Creating a schema and collection in the mongo-db database with the help of express
```

const mongoose=require('mongoose')
const User=new mongoose.Schema(
    {
    name:{type:String,required:true},
    email:{type:String,required:true,unique:true},
    password:{type:String,required:true},
    quote:{type:String},
    
},
{collection:'userdata'}
)
const model=mongoose.model('userdata',User)
module.exports=model
```
-------------

We are using Node-js for backend. It receives the requests from users and performs functions accordingly. It also authenticates users through jwt authentication where it generates Tokens for the users.
```
const express = require('express')
const app = express()
const cors = require('cors')
const User = require('./models/model')
const jwt = require('jsonwebtoken');
app.use(express.json())
app.use(cors())
const mongoose = require('mongoose')
mongoose.connect("<your connection string which can be found in mongodb atlas after creating a cluster>")
 mongoose.connection.on('error', err => {
     console.log(err);
  });


app.post('/api/register', async (req, res) => {
    console.log(req.body)
    try {
        await User.create({
            name: req.body.name,
            email: req.body.email,
            password: req.body.password
        })
        res.json({ status: 'ok' })

    } catch (err) {
        res.json({ status: 'error', error: 'duplicate email' })
    }

}
)

app.post('/api/login', async (req, res) => {
    const user = await User.findOne({
        email: req.body.email,
        password: req.body.password
    })
    console.log(user)
    if (user) {
        const token = jwt.sign({
            name: user.name,
            email: user.email

        },
            <Your secret key for tokenization>
        )
        console.log(token);
        const userToken={name:user.name,email:user.email,token}
        return res.json({"status":"ok",'user':userToken})
    }
    else {
        return res.json({ 'status': 'error', user: false })
    }
})


app.listen(7070, () => {
    console.log("port 7070")
})
```

----------------
Creating deployment yaml files for back-end.
```
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mern-node  
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mern-node
  template:
    metadata:
      labels:
        app: mern-node
    spec:
      containers:
      - name: mern-node
        image:(your repository in docker hub where you built and uploaded the Image of the back-end code)
        ports:
        - containerPort: 7070
```
-----------
Creating deployment yaml files for front-end.
 ```
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mern-react
  name: mern-react
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mern-react
  template:
    metadata:
      labels:
        app: mern-react
    spec:
      containers:
      - image: (your repository in docker hub where you built and uploaded the Image of the front-end code)
        name: mern-react
        ports:
        - containerPort: 3000
```
--------------
creating a service file for back-end deployment
```
apiVersion: v1
kind: Service
metadata:
  name: node-service
spec:
  selector:
    app: mern-node
  type: ClusterIP
  ports:
  - port: 7070
    targetPort: 7070
```
------------
creating a service file for front-end deployment
```
apiVersion: v1
kind: Service
metadata:
  name: node-service
spec:
  selector:
    app: mern-node
  type: ClusterIP
  ports:
  - port: 7070
    targetPort: 7070
```

Access your application through the service port of the node-port
Steps:
1. kubectl describe service mern-service
2. Get the port number for the node-port 
3. localhost: "node-port port number"