Home > Web Front-end > JS Tutorial > body text

Dockerize PERN-TypeScript App Using Prisma ORM With Docker Compose

Patricia Arquette
Release: 2024-10-17 06:29:29
Original
623 people have browsed it

Dockerize PERN-TypeScript App Using Prisma ORM With Docker Compose

Introduction

This article won't go into detailed explanations. Instead, I’ll just provide the code snippets you need to dockerize a PERN stack application. If you want a more detailed explanation, check out this article where I’ve covered everything in more depth.

The Project Structure

pern-project/
--- frontend/
------ .dockerignore
------ frontend.dockerfile
------ ...
--- backend/
------ .dockerignore
------ backend.dockerfile
------ ...
--- docker-compose.yml
Copy after login

Code Backend

Create a node.js-express.js app first:

mkdir backend && cd backend
npm init -y
Copy after login

Install all the necessary dependencies from npm:

npm install express dotenv cors
Copy after login

Install Typescript related dev dependencies as well:

npm install --save-dev typescript ts-node @types/express @types/node @types/cors
Copy after login

Generate tsconfig.json file:

tsc --init
Copy after login

Replace everything inside tsconfig.json with this piece of code in the following:

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    "rootDir": "./src",
    "outDir": "./dist",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*.ts", "data-types.d.ts"]
}
Copy after login

Create src folder and index.ts file inside src folder. So, now the backend folder structure:

backend/
--- node_modules/
--- src/
------ index.ts
--- package.json
--- tsconfig.json
--- ...
Copy after login

Integrate Postgres With Prisma

Install Prisma and Prisma Client first:

npm i @prisma/client
npm i --save-dev prisma
Copy after login

Generate a prisma folder:

npx prisma init
Copy after login

Write a User model in the schema.prisma file:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id        String   @id @default(uuid())
  name      String
  username  String
  email     String
  password  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("users")
}
Copy after login

Set DATABASE_URL in the .env file:

DATABASE_URL=postgresql://postgres:postgres@db:5432/pern_db?schema=public
Copy after login

Create a file prismadb.ts in the src folder:

import { PrismaClient } from "@prisma/client"
import "dotenv/config"

// Extend the global object with PrismaClient
declare global {
  var prisma: PrismaClient | undefined
}

// Prevent multiple instances of Prisma Client in development
const prisma = global.prisma || new PrismaClient()

if (process.env.NODE_ENV !== "production") global.prisma = prisma

export default prisma
Copy after login

Define /register endpoint in the index.ts file. The index.ts file:

import express, { Request, Response } from "express"
import "dotenv/config"
import cors from "cors"
import { corsOptions } from "./constants/config"

const app = express()
const PORT = process.env.PORT || 3000

app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cors({
    const corsOptions = {
    origin: process.env.CLIENT_URL || 'http://localhost:5173',
    credentials: true,
  }
}))

app.get("/", (req: Request, res: Response) => {
  res.json({
    message: "Hello, TypeScript with Express! Updated!",
  })
})

app.post("/register", async (req: Request, res: Response) => {
  const { name, username, email, password } = req.body

  await prisma.user.create({
    data: {
      name,
      username,
      email,
      password,
    },
  })

  res.json({
    message: "User created successfully",
  })
})

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`)
})

Copy after login

Backend Dockerfile

Create a file naming backend.dockerfile in the root of the backend directory and write:

FROM node:20
WORKDIR /app
COPY package*.json .
RUN npm install
COPY prisma ./prisma
RUN npx prisma generate
COPY . .
EXPOSE 3000
RUN npm install -g nodemon ts-node
CMD ["nodemon", "src/index.ts"]
Copy after login

To exclude node_modules, create a .dockerignore file:

node_modules
Copy after login

Code Frontend

Create the frontend:

npm create vite@latest frontend -- --template react-ts
Copy after login

Make API call in the React app:

// App.tsx

import { FormEvent, useEffect, useState } from "react"
....

function App() {
  const [name, setName] = useState("")
  const [username, setUsername] = useState("")
  const [email, setEmail] = useState("")
  const [password, setPassword] = useState("")

  const saveUser = async (e: FormEvent) => {
    e.preventDefault()
    await fetch("http://localhost:3000/register", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name,
        username,
        email,
        password,
      }),
    })
      .then((res) => res.json())
      .then((data) => console.log(data))
  }

  useEffect(() => {
    fetch("http://localhost:3000")
      .then((res) => res.json())
      .then((data) => console.log(data))
  }, [])

  return (
    <>
      <form onSubmit={saveUser}>
        <input
          type="text"
          onChange={(e) => setName(e.target.value)}
          placeholder="Enter your name"
        />
        <input
          type="text"
          onChange={(e) => setUsername(e.target.value)}
          placeholder="Enter your username"
        />
        <input
          type="email"
          onChange={(e) => setEmail(e.target.value)}
          placeholder="Enter your email"
        />
        <input
          type="password"
          onChange={(e) => setPassword(e.target.value)}
          placeholder="Enter your password"
        />
        <button type="submit">Submit</button>
      </form>
    </>
  )
}

export default App
Copy after login

Frontend Dockerfile

Create a file naming frontend.dockerfile in the root of the frontend directory and write:

FROM node:20
WORKDIR /app
COPY package*.json .
RUN npm install
EXPOSE 5173
COPY . .
CMD [ "npm", "run", "dev" ]
Copy after login

Docker-Compose file

Add the following in the .env file of the backend folder:

// backend/.env

POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=pern_db

DATABASE_URL=postgresql://postgres:postgres@db:5432/pern_db?schema=public
Copy after login

The docker-compose.yml file:

services:
  frontend:
    container_name: frontend
    build:
      context: ./frontend
      dockerfile: frontend.dockerfile
    ports:
      - "5173:5173"
    networks:
      - pern_net
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on:
      - server

  backend:
    container_name: backend
    build:
      context: ./backend
      dockerfile: backend.dockerfile
    env_file:
      - ./backend/.env
    ports:
      - "3000:3000"
    networks:
      - pern_net
    volumes:
      - ./backend:/app
      - /app/node_modules
    depends_on:
      - db

  db:
    container_name: db
    image: postgres:14
    restart: always
    ports:
      - "5432:5432"
    networks:
      - pern_net
    env_file:
      - ./backend/.env
    volumes:
      - pgdata:/data/db

networks:
  pern_net:
    driver: bridge

volumes:
  pgdata: {}
Copy after login

Run this command:

docker compose up -d
Copy after login

Migrate the prisma schema:

docker backend -it backend npx prisma migrate dev --name init
Copy after login

The above is the detailed content of Dockerize PERN-TypeScript App Using Prisma ORM With Docker Compose. For more information, please follow other related articles on the PHP Chinese website!

source:dev.to
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!