-
Notifications
You must be signed in to change notification settings - Fork 0
๐ณNext.js์ Docker๋ฅผ ์ฌ์ฉํ ๋น๋ ์ต์ ํํ๊ธฐ
์ด๋ฒ ๊ธ์์๋ Next.js์ Docker๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ ์ต์ ํ๋ฅผ ์งํํ ๋ฐฉ๋ฒ์ ๋ํด ์ค๋ช ํ๊ฒ ์ต๋๋ค.
๋จผ์ ๊ธฐ์กด ๋ฐฉ์์ Next.js์ default build ๋ฐฉ์์ ์ฌ์ฉํ์์ต๋๋ค. ํด๋น ๋น๋ ๋ฐฉ์์ .next
ํด๋๋ฅผ ์์ฑํฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด ๋ฉํฐ ์คํ
์ด์ง
๋ฐฉ์์ผ๋ก Next.js ์ ํ๋ฆฌ์ผ์ด์
์ ๋น๋ํ ํ production์ ํ์ํ .next
, node_modules
, package.json
, public
์ ๋ณต์ฌํ๋ ์์ผ๋ก Docker ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์์ต๋๋ค.
# 1. ๋น๋ ๋จ๊ณ
# ์์ฑํ Docker ์ด๋ฏธ์ง์ ๋ฒ ์ด์ค๊ฐ ๋๋ ์ด๋ฏธ์ง๋ฅผ ์ง์ ํฉ๋๋ค.
# node - ๊ฐ๋ฐ ํธ์์ฑ ๋ฐ ๋ค์ํ ๋๊ตฌ๊ฐ ํฌํจ๋ ์ด๋ฏธ์ง๋ก, ๊ฐ๋ฐ ํ๊ฒฝ์ด๋ ๋ณต์กํ ๋น๋ ์์
์ ์ ํฉํฉ๋๋ค.
# node:alpine - ํฌ๊ธฐ๊ฐ ์๊ณ ๊ฐ๋ฒผ์ด ์ด๋ฏธ์ง๋ก, ํ๋ก๋์
ํ๊ฒฝ์ด๋ ๋ฆฌ์์ค๊ฐ ์ ํ๋ ํ๊ฒฝ์ ์ ํฉํฉ๋๋ค.
FROM node:20-alpine AS build
# 1-1. ์์
๋๋ ํ ๋ฆฌ ์ค์
# ์ ํ๋ฆฌ์ผ์ด์
ํ์ผ์ ์ ์ฅํ๊ณ ์คํํ ๊ธฐ๋ณธ ์์
๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํฉ๋๋ค.
# /app ๋๋ ํ ๋ฆฌ๊ฐ ์๋์ผ๋ก ์์ฑ๋๋ฉฐ, ์ดํ์ ๋ชจ๋ ๋ช
๋ น์ด๊ฐ ์ด ๋๋ ํ ๋ฆฌ์์ ์คํ๋ฉ๋๋ค.
WORKDIR /app
# 1-2. ์์กด์ฑ ํ์ผ ๋ณต์ฌ
COPY package.json package-lock.json ./
# 1-3. ์์กด์ฑ ์ค์น
# ์ปจํ
์ด๋ ์์์ ๋ช
๋ น์ด๋ฅผ ์คํํ๊ณ ์ด๋ฏธ์ง๋ฅผ ๋น๋ํฉ๋๋ค.
RUN npm install --force
# 1-4. ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋ ๋ณต์ฌ
# ํ์ฌ ๋๋ ํ ๋ฆฌ์ ๋ชจ๋ ํ์ผ์ /app ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌํฉ๋๋ค.
COPY . .
**# 1-5. ํ๊ฒฝ ๋ณ์ ์ค์
ARG NEXT_PUBLIC_BACKEND_URL
ARG BACKEND_API_URL
ARG NEXT_PUBLIC_BACKEND_API_URL
ENV NEXT_PUBLIC_BACKEND_URL=${NEXT_PUBLIC_BACKEND_URL}
ENV BACKEND_API_URL=${BACKEND_API_URL}
ENV NEXT_PUBLIC_BACKEND_API_URL=${NEXT_PUBLIC_BACKEND_API_URL}**
# 1-6. ์ ํ๋ฆฌ์ผ์ด์
๋น๋
RUN npm run build
# 2. ๋ฐํ์ ๋จ๊ณ
FROM node:20-alpine
# 2-1. ๋น๋ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ํ์ํ ํ์ผ๋ง ๋ณต์ฌ
**WORKDIR /app
COPY --from=build /app/.next ./.next
COPY --from=build /app/node_modules ./node_modules
COPY --from=build /app/package.json ./package.json
COPY --from=build /app/public ./public**
# 2-2. ํฌํธ ์ค์
# ์ปจํ
์ด๋๊ฐ ์ฌ์ฉํ๋ ํฌํธ๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ ํ๋ ๋ช
๋ น์ด๋ก, ํธ์คํธ์ ํต์ ํ ํฌํธ๋ฅผ ์ค์ ํฉ๋๋ค.
EXPOSE 3000
# 2-3. ์ ํ๋ฆฌ์ผ์ด์
์คํ
# ์ปจํ
์ด๋๊ฐ ์์๋ ๋ ์คํํ ๊ธฐ๋ณธ ๋ช
๋ น์ด๋ฅผ ์ง์ ํฉ๋๋ค.
# CMD๋ Dockerfile์์ ํ ๋ฒ๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
**CMD [ "npm", "run", "start" ]**
์ด์ ๊ฐ์ด Docker ์ด๋ฏธ์ง๋ฅผ ๋น๋ํ ๊ฒฐ๊ณผ ํฌ๊ธฐ๊ฐ 1.2GB
๋ก ์๋นํ ์ปธ์ต๋๋ค.
๋น๋ ํ์ผ ์ฉ๋์ ์ค์ผ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฐพ์๋ณด๋ ์ค, ๋ค์๊ณผ ๊ฐ์ด Next.js ๊ณต์ ๋ฌธ์์์ ๋น๋ ์ถ๋ ฅ๋ฌผ ์ ํ์ ๊ฒฐ์ ํ๋ ๋ฐฉ์์ ํ์ธํ ์ ์์์ต๋๋ค.
๊ณต์ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด standalone
๋น๋ ๋ฐฉ์์ production์ ํ์ํ ์ต์ํ์ ํ์ผ๊ณผ ์์กด์ฑ๋ง ๋ณต์ฌํจ์ผ๋ก์จ ์ฉ๋์ ์๋นํ ์ค์ผ ์ ์์ต๋๋ค. ํนํ ํด๋น ๋น๋ ๋ฐฉ์์ Docker๋ก ๋ฐฐํฌํ ๋ ์ ์ฉํ๋ค๊ณ ์ค๋ช
๋์ด ์์์ต๋๋ค. ์ด๋ VSCode์์๋ ํ์ธํ ์ ์์์ต๋๋ค.
๋ฐ๋ผ์ ๋น๋ ์ถ๋ ฅ๋ฌผ ์ ํ์ standalone
์ผ๋ก ๋ณ๊ฒฝํ ํ ๋ค์๊ณผ ๊ฐ์ด Dockerfile์ ์์ ํ ํ Docker ์ด๋ฏธ์ง๋ฅผ ์์ฑํ์์ต๋๋ค.
// next.config.ts
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
/* config options here */
reactStrictMode: false,
**output: 'standalone',**
};
export default nextConfig;
// .dockerignore
# Node.js ํ๊ฒฝ
node_modules
# Git ๊ด๋ จ ํ์ผ
.git
.gitignore
# env ํ์ผ
.env
# ๋น๋ ๊ฒฐ๊ณผ๋ฌผ
.next
# ํ
์คํธ ๊ด๋ จ ํ์ผ
__tests__
.swc
playwright-report
test_results
tests
node_modules
# 1. ๋น๋ ๋จ๊ณ
# ์์ฑํ Docker ์ด๋ฏธ์ง์ ๋ฒ ์ด์ค๊ฐ ๋๋ ์ด๋ฏธ์ง๋ฅผ ์ง์ ํฉ๋๋ค.
# node - ๊ฐ๋ฐ ํธ์์ฑ ๋ฐ ๋ค์ํ ๋๊ตฌ๊ฐ ํฌํจ๋ ์ด๋ฏธ์ง๋ก, ๊ฐ๋ฐ ํ๊ฒฝ์ด๋ ๋ณต์กํ ๋น๋ ์์
์ ์ ํฉํฉ๋๋ค.
# node:alpine - ํฌ๊ธฐ๊ฐ ์๊ณ ๊ฐ๋ฒผ์ด ์ด๋ฏธ์ง๋ก, ํ๋ก๋์
ํ๊ฒฝ์ด๋ ๋ฆฌ์์ค๊ฐ ์ ํ๋ ํ๊ฒฝ์ ์ ํฉํฉ๋๋ค.
FROM node:20-alpine AS build
# 1-1. ์์
๋๋ ํ ๋ฆฌ ์ค์
# ์ ํ๋ฆฌ์ผ์ด์
ํ์ผ์ ์ ์ฅํ๊ณ ์คํํ ๊ธฐ๋ณธ ์์
๋๋ ํ ๋ฆฌ๋ฅผ ์ง์ ํฉ๋๋ค.
# /app ๋๋ ํ ๋ฆฌ๊ฐ ์๋์ผ๋ก ์์ฑ๋๋ฉฐ, ์ดํ์ ๋ชจ๋ ๋ช
๋ น์ด๊ฐ ์ด ๋๋ ํ ๋ฆฌ์์ ์คํ๋ฉ๋๋ค.
WORKDIR /app
# 1-2. ์์กด์ฑ ํ์ผ ๋ณต์ฌ
COPY package.json package-lock.json ./
# 1-3. ์์กด์ฑ ์ค์น
# ์ปจํ
์ด๋ ์์์ ๋ช
๋ น์ด๋ฅผ ์คํํ๊ณ ์ด๋ฏธ์ง๋ฅผ ๋น๋ํฉ๋๋ค.
RUN npm install --force
# 1-4. ์ ํ๋ฆฌ์ผ์ด์
์ฝ๋ ๋ณต์ฌ
# ํ์ฌ ๋๋ ํ ๋ฆฌ์ ๋ชจ๋ ํ์ผ์ /app ๋๋ ํ ๋ฆฌ๋ก ๋ณต์ฌํฉ๋๋ค.
COPY . .
**# 1-5. client-side ํ๊ฒฝ ๋ณ์ ์ค์
ARG ARG_NEXT_PUBLIC_BACKEND_URL
ARG ARG_NEXT_PUBLIC_BACKEND_API_URL
ENV NEXT_PUBLIC_BACKEND_URL=${ARG_NEXT_PUBLIC_BACKEND_URL}
ENV NEXT_PUBLIC_BACKEND_API_URL=${ARG_NEXT_PUBLIC_BACKEND_API_URL}**
# 1-6. ์ ํ๋ฆฌ์ผ์ด์
๋น๋
RUN npm run build
# 2. ๋ฐํ์ ๋จ๊ณ
FROM node:20-alpine
# 2-1. ๋น๋ ๊ฒฐ๊ณผ๋ฌผ๊ณผ ํ์ํ ํ์ผ๋ง ๋ณต์ฌ
**WORKDIR /app
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/public ./public**
**# 2-2. server-side ํ๊ฒฝ ๋ณ์ ์ค์
ARG ARG_BACKEND_API_URL
ENV BACKEND_API_URL=${ARG_BACKEND_API_URL}**
# 2-3. ํฌํธ ์ค์
# ์ปจํ
์ด๋๊ฐ ์ฌ์ฉํ๋ ํฌํธ๋ฅผ ๋ช
์์ ์ผ๋ก ์ง์ ํ๋ ๋ช
๋ น์ด๋ก, ํธ์คํธ์ ํต์ ํ ํฌํธ๋ฅผ ์ค์ ํฉ๋๋ค.
EXPOSE 3000
# 2-4. ์ ํ๋ฆฌ์ผ์ด์
์คํ
# ์ปจํ
์ด๋๊ฐ ์์๋ ๋ ์คํํ ๊ธฐ๋ณธ ๋ช
๋ น์ด๋ฅผ ์ง์ ํฉ๋๋ค.
# CMD๋ Dockerfile์์ ํ ๋ฒ๋ง ์ฌ์ฉํ ์ ์์ต๋๋ค.
**CMD [ "node", "server.js" ]**
๊ทธ ๊ฒฐ๊ณผ Docker ์ด๋ฏธ์ง ํฌ๊ธฐ๋ฅผ 202 MB
๋ก ์๋นํ ์ค์ผ ์ ์์์ต๋๋ค.
web12-MafiaCamp
๐ฏํ๋ก์ ํธ ๊ท์น
๐ปํ๋ก์ ํธ ๊ธฐํ
๐๊ธฐ์ ์คํ
- ๐ป Next.js 15๋ฅผ ์ ํํ ์ด์
- ๐ NestJS๋ฅผ ์ ํํ ์ด์
- ๐ฅ๏ธ OpenVidu๋ฅผ ์ ํํ ์ด์
- ๐ TypeORM์ ์ ํํ ์ด์
- ๐ฌ ์ฑํ ๊ธฐ๋ฅ ๊ตฌํ์ ์ํด WebSocket์ ์ ํํ ์ด์
- ๐ WebRTC ๊ฐ๋ ์ ๋ฆฌ
- ๐พ WebRTC โ Nest.js์ React๋ก ํ๋ ๊ฐ๋จ ํ์์ฑํ ์์
- ๐ฅ๏ธ GitHub Actions๋ก CI/CD ๊ตฌ์ถ ๋ฐฉ๋ฒ
- ๐ฆ Docker์ ๊ฐ๋ ๊ณผ ์ฌ์ฉ ๋ฐฉ๋ฒ
- ๐ OAuth ๊ธฐ๋ณธ ์ธ์ฆ ๊ณผ์ ๊ณผ ์์
๐๊ทธ๋ฃน ํ๊ณ
๐๊ฐ๋ฐ ์ผ์ง
๐๋ฌธ์ ํด๊ฒฐ ๊ฒฝํ
- ์น์์ผ ๋ฐฉ ๊ด๋ฆฌ ๊ตฌ์กฐ ๊ฐ์
- Pub-Sub ํจํด์ ํตํ ์ค์๊ฐ ๋ฐฉ ๋ชฉ๋ก ์กฐํ ๊ธฐ๋ฅ ๊ฐ๋ฐ
- ์ ํ ์ํ ๊ธฐ๊ณ๋ฅผ ์ด์ฉํ ๊ฒ์ ์งํ ๋ชจ๋ธ๋ง
- ๐ ๋์์ฑ ์ด์๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ LockManager ๋ง๋ค๊ธฐ
- โฐ RxJS๋ก ์ค์๊ฐ ํ์ด๋จธ ๊ตฌ์ถํ๊ธฐ
- ๐ณNext.js์ Docker๋ฅผ ์ฌ์ฉํ ๋น๋ ์ต์ ํํ๊ธฐ
- ๐ข Redis๋ฅผ ํตํ ์ ์ ์จ๋ผ์ธ ์ํ ๊ด๋ฆฌ ์์คํ ๊ตฌํํ๊ธฐ
- openvidu ์๋ฌ ๋๋ฒ๊น ์ ์ํ Docker ๊ฐ๋ฐํ๊ฒฝ ์ค์
๐งํธ๋ฌ๋ธ ์ํ
- NestJS, mkcert CA ์ธ์ฆ์ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ
- openvidu ICE ํ๋ณด ๊ด๋ จ ์ค๋ฅ
- Enterํค ์ด๋ฒคํธ ์ค๋ณต ํธ์ถ ๋ฌธ์
- mutex lock ๋ฌธ์
- ํฌํ ๋์์ ์ง์ ์ค๋ฅ
- openvidu ์ธ์ ์ข ๋ฃ ๋ฉ์๋ ์ค๋ฅ
- ์บ์๋ก ์ธํ ๋ฏธ๋ค์จ์ด ๋ฏธํธ์ถ ๋ฐ ํ์ด์ง ์ ํ ์ค๋ฅ
- ๋คํฌ ๋ชจ๋์์ ํ ์คํธ๊ฐ ๋ณด์ด์ง ์๋ ๋ฌธ์
- ๊ฒ์ ๋ฐฉ์์ ์๋ก๊ณ ์นจ ๋๋ ๋ธ๋ผ์ฐ์ ํญ์ ๋ซ์ ๋์ ์์ธ ์ฒ๋ฆฌ