https://github.com/RitikaxG/Deploy-monorepo-cicd-docker

Setting up a turborepo using bun as package manager

Step 1 : Install bun globally

npm install -g bun

Step 2 : Initialising an empty turborepo with tailwind css

npx create-turbo@latest -e with-tailwind

Step 3 : Setting up Database

# 3.1 Creating db folder
	cd packages
	mkdir db
	cd db
	
	bun init # 3.2 Initialise empty bun file (node js/typescript backend)

	bun install prisma
	bunx prisma init # 3.3 Initialise prisma

# 3.4 Add a model
	model User{
	  id       String @default(cuid()) @id
	  username String @unique
	  password String
	}
	
# 3.5 Start postgres locally using docker

	# Step 1 : Create a volume
	docker create volume monorepo-postgres-container
	# Step 2 : Start container with volume mapping
	docker run -v monorepo-docker-postgres:/var/lib/postgresql/data -e POSTGRES_PASSWORD=mysecretpassword -p 5432:5432 -d postgres	

# 3.6 Update Environment Variable
	DATABASE_URL=postgresql://postgres:mysecretpassword@localhost:5432/postgres
	
# 3.7 Migrate Postgres Database
	bunx prisma migrate dev
	
# 3.8 Generate Prisma Client
	bunx prisma generate
	
# 3.9 Export prisma client from index.ts
	import { PrismaClient } from "@prisma/client";

	export const client = new PrismaClient();
	
# 3.10 Export prisma client in package.json
 "exports":{
    "./client" : "./index.ts"
  },

Step 4 : Create http-server ( Separate backend folder )

# Step 1
cd apps

# Step 2
mkdir http-server

# Step 3
cd http-server

# Step 4
bun init

# Step 5
bun install express @types/express

# Step 6 ( Add db as dependency ) in package.json
"dependencies": {
    "db" : "*"
  }
  
# Step 7 ( Do a global bun install )

# Step 8 ( Write a simple node js backend application )

import { client } from "db/client";
import express from "express";

const app = express();
app.use(express.json());

app.get("/",async(req,res) => {
    try{
        const users = await client.user.findMany();
        res.json({
            message : "Successfully fetched all users",
            users
        })
    }
    catch(err : any){
        res.json({
            message : "Error fetching users",
            error   : err.message
        })
    }
})

app.post("/",async(req, res) => {
    const { username, password } = req.body();

    try{
        const newUser = await client.user.create({
            data : {
                username,
                password
            }
        })
        res.json({
            message : "Successfully created new user",
            newUser
        })
    }
    catch(err : any){
        res.json({
            message : "Error creating new user",
            error   : err.message
        })
    }
})

app.listen(8080,() =>{
    console.log("Http server is listening on port 8080");
    
})

Step 5 : Add nextjs routes

# Step-1
cd apps/web

# Step-2
add db as dependency in package.json

# Step-3 ( Update page.tsx)
# Simple route to fetch users from http backend server

import { client } from "db/client";

export default async function App(){
  const users = await client.user.findMany();

  return(
    <div>{
      users.map(user => (
        <div key={user.id}>
           <div>{user.username}</div>
          <div>{user.password}</div>
        </div>
      ))}</div>
  ) 
}

Step 6 : Create web socket server

# Step 1
cd apps

# Step 2
mkdir ws-server

# Step 3
cd ws-server

# Step 4
bun init

# Step 5 ( Add db as dependency )
"dependencies": {
    "db" : "*"
  }
  
# Step 6 ( establish web socket connection ) in index.ts

import { client } from "db/client";
Bun.serve({
    port : 8081,
    fetch(req,server){
        // upgrade the request to a websocket
        if(server.upgrade(req)){
            return; // do not return a response
        }
        return new Response("Upgrade Failed",{ status : 500 })
    },
    websocket: {
        async message(ws,message){
            await client.user.create({
                data : {
                    username : Math.random().toString(),
                    password : Math.random().toString()
                }
            })
        }
    }
})

Step 7 : Test all 3 servers (nextjs / http / ws )

# http-server
 
# Step 1
cd apps/http-server
bun run index.ts 

# Step 2
Go to Postman and test the endpoints at port 8080

# nextjs-server

# When using bun as package manager
	# Step 1 : 
	bun add -D turbo  # ( Install turbo locally )
	
	# Step 2 :
	bun run build # Build the repo globally to use exports from packages/ui in apps/web
	
	# Step 3 :
	cd apps/web
	bun run dev
	
# ws-server

	# Step 1
	cd apps/ws-server
	bun run index.ts
	
	# Step 2
	Go to Postman and test the web socket connection at port 8081 send a message to see if it adds an entry to database

# You can see if database is getting updated by
	# Step 1 
	cd packages/db
	
	# Step 2
	bunx prisma studio
	

Writing Dockerfiles for all 3 services

IMPORTANT

You need separate DATABASE_URL for migrating the database ( from packages/db ) and generating prisma client from docker containers ( since docker containers for backend/ws/frontend port:5432 needs to be mapped to host machine port:5432 )