Build A Chat Room With MERN Stack

This post is about my experience on how to build a chat room using the MERN (MongoDB, Express, React JS, Node JS), WebSocket and deploy to Docker Hub.

My goal is to build a web application to chat. Anyone can connect to room with username and room Id from an open web browser.

You can clone the final result of this post from: (Source: https://bitbucket.org/demo-chat-room/) Note: It is available only on develop branch.

The chat room application have 3 parts: Frontend, Backend and Deploy.

Frontend

The client-side will use ReactJS to build user interfaces and store state of message into Redux. Futhermore, using the Webpack to bundle files realtime when developing project.

What is React?

React is a JavaScript library for building user interfaces.

What is Redux?

Redux is a predictable state container for JavaScript apps.

What is Webpack?

Webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

Chatroom UI

Login Page: Where the user will input room Id and username for identify before enter chat room.

Message Page: User can send message and read message from other on current room.

Setup
  1. Create Frontend folder
  2. Go to Frontend folder, then create a package.json that to manage nodeJS package.
    axios: To fetch conversation from back-end and to validate username, room id before enter chat room.
    redux: To store conversation, room id and username that is support for chat conversation.
    react-router: to navigate among views. It mean, allow change URL and keeps the UI in sync with the URL.
    webpack-dev-server: This is only supported for develop environment. This provides live reloading page after code changed.
  3. Create a file named .env to save enviroment variables we will be using.
BASE_URL=http://localhost:3000/
BASE_WS=ws://localhost:3001
Running in developer environment
npm install
npm run start

or

yarn install
yarn start

Backend

The server-side use two type to connections: HTTP request and WebSocket.
HTTP request to enter or create new chat room with the username which is input from user.
WebSocket to manage incoming and outcoming messages to all connected clients in real time.

What is Node JS?

Node.js is an open-source, cross-platform, back-end JavaScript runtime environment that runs on the V8 engine and executes JavaScript code outside a web browser.

What is MongoDB?

MongoDB is a document-oriented NoSQL database used for high volume data storage. MongoDB is a database which came into light around the mid-2000s.

What is Websocket?

WebSocket is bidirectional, a full-duplex protocol that is used in the same scenario of client-server communication.

Tablle Diagram

Sequence Diagram

Setup
  1. Create Backend folder

  2. Go to Backend folder, then create a package.json that to manage nodeJS package.
    migrate-mongo: To create new database migration for MongoDB.
    ws: module that helps to set up a realtime server for accepting and broadcasting messages to connected clients.
    tslint: To check TypeScript code.
    prettier: To ensure consitent style code.
    mongoose: ODM for performing transactions with MongoDB.
    module-alias: To declare aliases that map to a certain absolute path in TypeScript Node.js projects.
    jsonwebtoken: To create/validate JSON Web Token.
    body-parser: Body parsing middleware to parse incoming request bodies to pass to our routes.

  3. Create a file named .env to save enviroment variables we will be using.

# Environment Name
NODE_ENV=develop

# Server listen to this port
PORT=3000

# Websocket listen this port
WSS_PORT=3001

# AWS credential
ACCESS_KEY_ID=
SECRET_ACCESS_KEY=
REGION=

# Secret key
JWT_SECRET_KEY = '@DEMOCHATROOM'

#Cors
CORS_URL=*

# database connection string
DATABASE_URL=mongodb://localhost:27017/demo_chat_room
Running in developer environment
npm install
npm run start

or

yarn install
yarn start

Deploy

What is docker?

Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.

What is docker-compose?

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

What is docker hub?

Docker Hub is a service provided by Docker for finding and sharing container images with your team.

Setup
  1. Create a folder Deploy that is the same level with Frontend and Backend folder
  2. Ceate docker-compose.yml on Deploy folder
  3. Modify docker-compose file
version: "3.4"
services:
  demochatroompage:
    container_name: demochatroompage
    image: demochatroompage
    restart: unless-stopped
    build: ./../frontend
    ports:
      - "80:80"
    links:
      - demochatroom
    depends_on:
      - demochatroom
    environment:
      NODE_ENV: production
      BASE_URL: http://demochatroom:3000/
      BASE_WS: ws://demochatroom:3001
  demochatroom:
    container_name: demochatroom
    image: demochatroom
    restart: unless-stopped
    build: ./../backend
    ports:
      - "3000:3000"
      - "3001:3001"
    links:
      - mongo
    depends_on:
      - mongo
    environment:
      DATABASE_URL: mongodb://mongo:27017/demo_chat_room
  mongo:
    container_name: mongo
    restart: unless-stopped
    image: mongo
    ports:
      - "27017:27017"
    volumes:
      - dbdata:/data/mongo
volumes:
  dbdata:
  1. Push image to docker hub
docker build -t demo-chat-room
docker login --username <username> --password <password>
docker push demo-chat-room
  1. SSH to AWS EC2
  2. Pull docker image
docker pull demo-chat-room
  1. Run docker container
docker run -d -p 80:80 --name chat demo-chat-room

Note: EC2 security group need open port 80 (HTTP), 443 (HTTPS), 22 (SSH), 27017 (MongoDB)

Thank you for reading!!! I hope this post added some value.