Skip to content

nishoof/chat

Repository files navigation

nchat

Real-time microservices chat app. Discord / Slack style messaging with Google OAuth.

Stack + Architecture

Services

There is the frontend service and 3 backend microservices

Service Responsibility Tech Stack
Frontend UI, Socket.io client TypeScript + React. Built with Vite. Served with Nginx.
Auth Service Google OAuth + JWT Go + Gin
Realtime Chat Service WebSocket messaging TypeScript + NestJS (Node.js framework) + Socket.io
Chat History Service Storing messages in db Java + Maven + Spring Boot + JPA/Hibernate + Flyway

Observability

Prometheus for metrics. Infra metrics per service process (such as CPU usage) + app metrics (such as # of active websocket connections or message send rate)

Loki to store and query logs. Promtail to ship logs to Loki from containers

Grafana for visualization

Deployment

Local

Set env vars:

  • GOOGLE_CLIENT_ID
  • GOOGLE_CLIENT_SECRET
  • GOOGLE_REDIRECT_URL
  • JWT_PRIVATE_KEY_PEM
  • JWT_PUBLIC_KEY_PEM

Start all services with:

docker compose up --build

See frontend at http://localhost.

Stop all services with:

docker compose down

To also remove volumes (clears database):

docker compose down -v

Terraform

Terraform variables in terraform/envs/<ENV>.tfvars.

export AWS_REGION="${AWS_REGION:-us-west-2}"
export AWS_ACCOUNT_ID="$(aws sts get-caller-identity --query Account --output text)"
export ENV=dev
export REGISTRY="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/chat"
export IMAGE_TAG="${ENV}-$(git rev-parse --short HEAD 2>/dev/null || echo local)-$(date +%s)"

aws ecr get-login-password --region "${AWS_REGION}" | docker login --username AWS --password-stdin "${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com"

terraform -chdir=terraform/infra init -reconfigure -backend-config="key=infra/${ENV}/terraform.tfstate"
terraform -chdir=terraform/infra apply -var-file="envs/${ENV}.tfvars"

aws eks update-kubeconfig --region us-west-2 --name chat-prod
kubectl create namespace chat --dry-run=client -o yaml | kubectl apply -f -

terraform -chdir=terraform/kubernetes init -reconfigure -backend-config="key=kubernetes/${ENV}/terraform.tfstate"
terraform -chdir=terraform/kubernetes apply -var-file="envs/${ENV}.tfvars"

docker buildx build --platform linux/amd64 -t $REGISTRY/frontend:${IMAGE_TAG} ./frontend --push
docker buildx build --platform linux/amd64 -t $REGISTRY/auth-service:${IMAGE_TAG} ./backend/auth-service --push
docker buildx build --platform linux/amd64 -t $REGISTRY/realtime-chat-service:${IMAGE_TAG} ./backend/realtime-chat-service --push
docker buildx build --platform linux/amd64 -t $REGISTRY/chat-history-service:${IMAGE_TAG} ./backend/chat-history-service --push

./scripts/deploy-blue-green.sh --env "${ENV}" --registry "${REGISTRY}" --image-tag "${IMAGE_TAG}"

About

Real-time microservices chat app. Discord / Slack style messaging with Google OAuth. Deployed on AWS using Terraform and Kubernetes

Resources

Stars

Watchers

Forks

Contributors