Skip to content

๐Ÿชต 3. ์ธํ”„๋ผ ์‹ค์Šต(5) : ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด๋ณด๊ธฐ

ssum1ra edited this page Dec 5, 2024 · 1 revision

Docker ๊ธฐ๋ฐ˜์˜ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์ถ•ํ•˜๊ธฐ

1. ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

image (23)

  • VPC (10.0.0.0/16)

    Public Subnet์€ ์™ธ๋ถ€์™€ ์—ฐ๊ฒฐ๋˜๋Š” ์„œ๋น„์Šค, Private Subnet์€ ๋‚ด๋ถ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์œ„ํ•œ ํ™˜๊ฒฝ์œผ๋กœ ๊ตฌ์„ฑ

  • Public Subnet (10.0.1.0/24)

    ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์›น ์„œ๋ฒ„์™€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋ฒ„๊ฐ€ ์œ„์น˜

  • Nginx

    ์ •์  ํŒŒ์ผ ์ œ๊ณต ๋ฐ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๋กœ ๋™์ž‘ํ•˜์—ฌ ์‚ฌ์šฉ์ž ์š”์ฒญ์„ ์ ์ ˆํ•œ ์„œ๋น„์Šค๋กœ ๋ผ์šฐํŒ…

  • NestJS

    /socket.io๋ฅผ ํ†ตํ•ด WebSocket ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, API ์„œ๋ฒ„ ์—ญํ•  ์ˆ˜ํ–‰.

  • Redis (Private Subnet, 10.0.2.0/24)

    ํด๋ผ์šฐ๋“œ ํ™˜๊ฒฝ์˜ Redis๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์„ธ์…˜ ๊ด€๋ฆฌ ๋ฐ ๋ฐ์ดํ„ฐ ์บ์‹ฑ ์ฒ˜๋ฆฌ

  • Docker

    Nginx์™€ NestJS ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ชจ๋‘ Docker ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ์ด๋ฏธ์ง€๋Š” Github Actions๋ฅผ ํ†ตํ•ด ๋นŒ๋“œ ๋ฐ Docker Hub์—์„œ ๊ด€๋ฆฌ

  • ๋ฐฐํฌ ์ž๋™ํ™”

    CI/CD ํŒŒ์ดํ”„๋ผ์ธ(Github Actions)์„ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌ ์ž๋™ํ™”

2. Docker ๊ตฌ์„ฑ

Dockerfile.server

FROM node:20-alpine AS builder

RUN corepack enable && corepack prepare pnpm@9.12.3 --activate

WORKDIR /app

COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY core/package.json ./core/
COPY server/package.json ./server/

RUN pnpm install --frozen-lockfile

COPY . .

RUN pnpm --filter @troublepainter/core build
RUN pnpm --filter server build

FROM node:20-alpine AS production
WORKDIR /app        

COPY --from=builder /app/pnpm-workspace.yaml ./
COPY --from=builder /app/server/package.json ./server/package.json
COPY --from=builder /app/server/dist ./server/dist
COPY --from=builder /app/core/package.json ./core/package.json
COPY --from=builder /app/core/dist ./core/dist

RUN corepack enable && corepack prepare pnpm@9.12.3 --activate && cd server && pnpm install --prod

WORKDIR /app/server

ENV NODE_ENV=production
ENV PORT=3000

EXPOSE 3000

CMD ["node", "dist/main.js"]
  • ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ: core์™€ server๊ฐ€ ํฌํ•จ๋œ ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ
  • ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค: core ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ํ›„ server ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ
  • ํ”„๋กœ๋•์…˜ ์„ค์ •
    • ๋นŒ๋“œ๋œ core/server dist ํŒŒ์ผ๋งŒ ๋ณต์‚ฌ
    • ํ”„๋กœ๋•์…˜ ์˜์กด์„ฑ๋งŒ ์„ค์น˜ (--prod ํ”Œ๋ž˜๊ทธ)
    • server ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ฉ”์ธ ์ž‘์—…๊ณต๊ฐ„์œผ๋กœ ์„ค์ •
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜: NODE_ENV=production, PORT=3000 ์„ค์ •
  • ํฌํŠธ: 3000๋ฒˆ ํฌํŠธ ๋…ธ์ถœ
  • ์‹คํ–‰ ๋ฐฉ์‹: Node.js๋กœ server/dist/main.js ์‹คํ–‰
  • ์ตœ์ ํ™”: ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋กœ ๊ฐœ๋ฐœ ์˜์กด์„ฑ ์ œ์™ธ

Dockerfile.nginx

FROM node:20-alpine AS builder

RUN corepack enable && corepack prepare pnpm@9.12.3 --activate

WORKDIR /app

COPY pnpm-workspace.yaml package.json pnpm-lock.yaml ./
COPY core/package.json ./core/
COPY client/package.json ./client/

RUN pnpm install --frozen-lockfile

COPY . .

ARG VITE_API_URL
ARG VITE_SOCKET_URL

RUN echo "VITE_API_URL=$VITE_API_URL" > client/.env && echo "VITE_SOCKET_URL=$VITE_SOCKET_URL" >> client/.env && pnpm --filter @troublepainter/core build && pnpm --filter client build

FROM nginx:alpine

COPY nginx.conf /etc/nginx/templates/default.conf.template
COPY --from=builder /app/client/dist /usr/share/nginx/html

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]
  • ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ: core์™€ client๊ฐ€ ํฌํ•จ๋œ ๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ
  • ํ™˜๊ฒฝ ๋ณ€์ˆ˜: VITE_API_URL, VITE_SOCKET_URL์„ ๋นŒ๋“œ ์‹œ์ ์— ์ฃผ์ž…
  • ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค: core ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ ํ›„ client ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ
  • ๋ฐฐํฌ ์„ค์ •: nginx ์›น์„œ๋ฒ„๋กœ ๋นŒ๋“œ๋œ ํด๋ผ์ด์–ธํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„œ๋น™
  • ํฌํŠธ: HTTP(80), HTTPS(443) ํฌํŠธ ๋…ธ์ถœ
  • ์ตœ์ ํ™”: ๋ฉ€ํ‹ฐ ์Šคํ…Œ์ด์ง€ ๋นŒ๋“œ๋กœ ์ตœ์ข… ์ด๋ฏธ์ง€ ํฌ๊ธฐ ์ตœ์†Œํ™”
  • ์‹คํ–‰ ๋ฐฉ์‹: nginx๋ฅผ ํฌ๊ทธ๋ผ์šด๋“œ์—์„œ ๊ตฌ๋™

3. Nginx ์„ค์ •

nginx.conf

server {
    listen 80;
    server_name www.troublepainter.site;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443 ssl;
    server_name www.troublepainter.site;

    ssl_certificate /etc/letsencrypt/live/www.troublepainter.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.troublepainter.site/privkey.pem;

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    location / {
        root /usr/share/nginx/html;
        index index.html;
        try_files $uri $uri/ /index.html;
    }

    location /api {
	    proxy_pass http://server:3000;
	    proxy_http_version 1.1;
	    proxy_set_header Host $host;
	    proxy_cache_bypass $http_upgrade;
		}

		location /socket.io {
	    proxy_pass http://server:3000;
	    proxy_http_version 1.1;
	    proxy_set_header Upgrade $http_upgrade;
	    proxy_set_header Connection "upgrade";
	    proxy_set_header Host $host;
		}
}
  • HTTP(80) ์„ค์ •
  • HTTPS(443) ์„ค์ •
  • ๋ผ์šฐํŒ… ๊ทœ์น™
    1. / (ํ”„๋ก ํŠธ์—”๋“œ)
      • ์ •์  ํŒŒ์ผ ์ œ๊ณต
      • SPA ๋ผ์šฐํŒ… ์ง€์› (/index.html๋กœ ํด๋ฐฑ)
    2. /api (HTTP API)
      • server:3000์œผ๋กœ ํ”„๋ก์‹œ
      • HTTP ํ†ต์‹ ์— ํ•„์š”ํ•œ ๊ธฐ๋ณธ ํ—ค๋”๋งŒ ์„ค์ •
    3. /socket.io (WebSocket)
      • server:3000์œผ๋กœ ํ”„๋ก์‹œ
      • WebSocket ์—ฐ๊ฒฐ์„ ์œ„ํ•œ upgrade ํ—ค๋” ์„ค์ •
  • ๋ชจ๋“  ํ†ต์‹ ์€ ํ•˜๋‚˜์˜ Node.js ์„œ๋ฒ„(server:3000)์—์„œ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ์šฉ๋„์— ๋”ฐ๋ผ ๊ฒฝ๋กœ๋งŒ ๊ตฌ๋ถ„๋˜์–ด ์žˆ์Œ.

4. CI/CD ํŒŒ์ดํ”„๋ผ์ธ

client-ci-cd.yml

name: Client CI/CD

on:
  push:
    branches: [develop]
    paths:
      - 'client/**'
      - 'core/**'
      - 'nginx.conf'
      - '.github/workflows/client-ci-cd.yml'
      - 'Dockerfile.nginx'

jobs:
  ci-cd:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: '9'

      - name: Install Dependencies
        run: pnpm install --frozen-lockfile

      - name: Lint Client
        working-directory: ./client
        run: pnpm lint | true

      - name: Test Client
        working-directory: ./client
        run: pnpm test | true

      - name: Docker Setup
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.nginx
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter-nginx:latest
          build-args: |
            VITE_API_URL=${{secrets.VITE_API_URL}}
            VITE_SOCKET_URL=${{secrets.VITE_SOCKET_URL}}

      - name: Deploy to Server
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SSH_HOST }}
          username: mira
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /home/mira/web30-stop-troublepainter
            export DOCKERHUB_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}
            docker pull ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter-nginx:latest
            docker compose up -d nginx
  • Workflow ํŠธ๋ฆฌ๊ฑฐ
    • develop ๋ธŒ๋žœ์น˜ push ์ด๋ฒคํŠธ
    • ํด๋ผ์ด์–ธํŠธ, ์ฝ”์–ด, Nginx ๊ด€๋ จ ํŒŒ์ผ ๋ณ€๊ฒฝ ์‹œ์—๋งŒ ์‹คํ–‰
  • ci-cd
    • ์ดˆ๊ธฐ ์„ค์ •
      • Ubuntu ํ™˜๊ฒฝ ์„ค์ •
      • Node.js 20 ์„ค์น˜
      • pnpm 9 ์„ค์น˜
      • ์˜์กด์„ฑ ์„ค์น˜
      • core ํŒจํ‚ค์ง€ ๋นŒ๋“œ
    • ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์ฆ
      • ํด๋ผ์ด์–ธํŠธ ๋ฆฐํŠธ ๊ฒ€์‚ฌ
      • ํด๋ผ์ด์–ธํŠธ ํ…Œ์ŠคํŠธ ์‹คํ–‰
      • (์‹คํŒจํ•ด๋„ ํŒŒ์ดํ”„๋ผ์ธ ๊ณ„์† ์ง„ํ–‰)
    • ๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ/๋ฐฐํฌ
      • Docker Buildx ์„ค์ •
      • Docker Hub ๋กœ๊ทธ์ธ
      • Nginx ์ด๋ฏธ์ง€ ๋นŒ๋“œ ๋ฐ ํ‘ธ์‹œ
      • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฃผ์ž…
    • ์„œ๋ฒ„ ๋ฐฐํฌ
      • SSH๋กœ ์„œ๋ฒ„ ์ ‘์†
      • ์ตœ์‹  ์ด๋ฏธ์ง€ pull
      • nginx ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘

server-ci-cd.yml

name: Server CI/CD

on:
  push:
    branches: [develop]
    paths:
      - 'server/**'
      - 'core/**'
      - '.github/workflows/server-ci-cd.yml'
      - 'Dockerfile.server'

jobs:
  ci-cd:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: '9'

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build Core Package
        working-directory: ./core
        run: pnpm build

      - name: Create .env file
        working-directory: ./server
        run: |
          echo "REDIS_HOST=${{ secrets.REDIS_HOST }}" >> .env
          echo "REDIS_PORT=${{ secrets.REDIS_PORT }}" >> .env
          echo "CLOVA_API_KEY=${{ secrets.CLOVA_API_KEY }}" >> .env
          echo "CLOVA_GATEWAY_KEY=${{ secrets.CLOVA_GATEWAY_KEY }}" >> .env

      - name: Run tests
        run: pnpm --filter server test | true

      - name: Docker Setup
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v5
        with:
          context: .
          file: ./Dockerfile.server
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter-server:latest
          build-args: |
            REDIS_HOST=${{ secrets.REDIS_HOST }}
            REDIS_PORT=${{ secrets.REDIS_PORT }}
            CLOVA_API_KEY=${{ secrets.CLOVA_API_KEY }}
            CLOVA_GATEWAY_KEY=${{ secrets.CLOVA_GATEWAY_KEY }}

      - name: Deploy to Server
        uses: appleboy/ssh-action@v1.0.0
        with:
          host: ${{ secrets.SSH_HOST }}
          username: mira
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /home/mira/web30-stop-troublepainter
            export DOCKERHUB_USERNAME=${{ secrets.DOCKERHUB_USERNAME }}
            docker pull ${{ secrets.DOCKERHUB_USERNAME }}/troublepainter-server:latest
            docker compose up -d server
  • Workflow ํŠธ๋ฆฌ๊ฑฐ
    • develop ๋ธŒ๋žœ์น˜ push ์ด๋ฒคํŠธ
    • ์„œ๋ฒ„, ์ฝ”์–ด, Dockerfile ๊ด€๋ จ ํŒŒ์ผ ๋ณ€๊ฒฝ ์‹œ์—๋งŒ ์‹คํ–‰
  • ci-cd
    • ์ดˆ๊ธฐ ์„ค์ •
      • Ubuntu ํ™˜๊ฒฝ ์„ค์ •
      • Node.js 20 ์„ค์น˜
      • pnpm 9 ์„ค์น˜
      • ์˜์กด์„ฑ ์„ค์น˜
      • core ํŒจํ‚ค์ง€ ๋นŒ๋“œ
    • ์ฝ”๋“œ ํ’ˆ์งˆ ๊ฒ€์ฆ
      • ์„œ๋ฒ„ ํ™˜๊ฒฝ๋ณ€์ˆ˜(.env) ์„ค์ •
      • ์„œ๋ฒ„ ํ…Œ์ŠคํŠธ ์‹คํ–‰
      • (์‹คํŒจํ•ด๋„ ํŒŒ์ดํ”„๋ผ์ธ ๊ณ„์† ์ง„ํ–‰)
    • ๋„์ปค ์ด๋ฏธ์ง€ ๋นŒ๋“œ/๋ฐฐํฌ
      • Docker Buildx ์„ค์ •
      • Docker Hub ๋กœ๊ทธ์ธ
      • Server ์ด๋ฏธ์ง€ ๋นŒ๋“œ ๋ฐ ํ‘ธ์‹œ
      • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฃผ์ž… (Redis, Clova API)
    • ์„œ๋ฒ„ ๋ฐฐํฌ
      • SSH๋กœ ์„œ๋ฒ„ ์ ‘์†
      • ์ตœ์‹  ์ด๋ฏธ์ง€ pull
      • server ์ปจํ…Œ์ด๋„ˆ ์žฌ์‹œ์ž‘

5. Docker Compose

docker-compose.yml

services:
  server:
    image: ${DOCKERHUB_USERNAME}/troublepainter-server:latest
    container_name: troublepainter_server
    environment:
      - NODE_ENV=production
      - REDIS_HOST=${REDIS_HOST}
      - REDIS_PORT=${REDIS_PORT}
      - CLOVA_API_KEY=${CLOVA_API_KEY}
      - CLOVA_GATEWAY_KEY=${CLOVA_GATEWAY_KEY}
    networks:
      - app_network
    restart: unless-stopped

  nginx:
    image: ${DOCKERHUB_USERNAME}/troublepainter-nginx:latest
    container_name: troublepainter_nginx
    volumes:
      - /etc/letsencrypt:/etc/letsencrypt
    ports:
      - "80:80"
      - "443:443"
    depends_on:
      - server
    networks:
      - app_network
    restart: unless-stopped

networks:
  app_network:
    name: app_network
    driver: bridge
  • ์—ฌ๋Ÿฌ Docker ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ •์˜ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์„ค์ • ํŒŒ์ผ
  • ์„œ๋น„์Šค ๊ตฌ์„ฑ
    • Server ์„œ๋น„์Šค (Node.js ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜)
    • Nginx ์„œ๋น„์Šค (์›น์„œ๋ฒ„/ํ”„๋ก์‹œ)
  • API ์„œ๋น„์Šค ์„ค์ •
    • ์ปจํ…Œ์ด๋„ˆ๋ช…: troublepainter_server
    • ํ™˜๊ฒฝ๋ณ€์ˆ˜: NODE_ENV, Redis ์—ฐ๊ฒฐ ์ •๋ณด, Clova API ์ธ์ฆํ‚ค
    • ์ž๋™ ์žฌ์‹œ์ž‘ ์ •์ฑ… ์ ์šฉ
    • app_network์— ์—ฐ๊ฒฐ
  • Nginx ์„œ๋น„์Šค ์„ค์ •
    • ์ปจํ…Œ์ด๋„ˆ๋ช…: troublepainter_nginx
    • SSL ์ธ์ฆ์„œ ๋ณผ๋ฅจ ๋งˆ์šดํŠธ (/etc/letsencrypt)
    • 80/443 ํฌํŠธ ๋…ธ์ถœ
    • API ์„œ๋น„์Šค์— ์˜์กด์„ฑ ์„ค์ •
    • app_network์— ์—ฐ๊ฒฐ
  • ๋„คํŠธ์›Œํฌ ์„ค์ •
    • ๋„คํŠธ์›Œํฌ๋ช…: app_network
    • ํƒ€์ž…: bridge ๋„คํŠธ์›Œํฌ
      • ๊ฐ™์€ Docker ํ˜ธ์ŠคํŠธ ๋‚ด์—์„œ ์‹คํ–‰๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋“ค์ด ์„œ๋กœ ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฐ€์ƒ์˜ ๋„คํŠธ์›Œํฌ

ํ˜„์žฌ ๊ตฌ์กฐ์˜ ๋‹จ์ ๊ณผ ํ–ฅํ›„ ๊ณ„ํš

1. Nginx์˜ ์—ญํ•  ์ค‘๋ณต

  • Nginx๊ฐ€ ์ •์  ํŒŒ์ผ ํ˜ธ์ŠคํŒ…๊ณผ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ๋‘ ๊ฐ€์ง€ ์—ญํ•  ์ˆ˜ํ–‰
  • ์„œ๋ฒ„ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ ์ฆ๊ฐ€

2. ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ Nginx ์ด๋ฏธ์ง€ ๋นŒ๋“œ

  • ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๋ณ€๊ฒฝ์‹œ๋งˆ๋‹ค Nginx ์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ ํ•„์š”
  • ๋ฐฐํฌ ์‹œ๊ฐ„ ์ฆ๊ฐ€, ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„
  • Nginx ์„ค์ • ๋ณ€๊ฒฝ๋งŒ ํ•„์š”ํ•  ๋•Œ๋„ ์ „์ฒด ๋นŒ๋“œ ํ•„์š”

3. ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ๋ชจ๋“  ์ž‘์—… ์ฒ˜๋ฆฌ

  • HTTP API์™€ Socket.IO๊ฐ€ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ๋™์ž‘
  • ํŠธ๋ž˜ํ”ฝ ์ฆ๊ฐ€ ์‹œ ๊ฐœ๋ณ„ ์Šค์ผ€์ผ๋ง ๋ถˆ๊ฐ€
  • ํ•œ ๊ธฐ๋Šฅ์˜ ์žฅ์• ๊ฐ€ ์ „์ฒด ์„œ๋น„์Šค์— ์˜ํ–ฅ

1. Nginx์˜ ์—ญํ•  ์ค‘๋ณต ๋ฌธ์ œ ํ•ด๊ฒฐ

  • ์ •์  ํŒŒ์ผ ๋ถ„๋ฆฌ
    • ์ •์  ํŒŒ์ผ์€ Nginx๊ฐ€ ์•„๋‹Œ AWS S3์™€ ๊ฐ™์€ ์˜ค๋ธŒ์ ํŠธ ์Šคํ† ๋ฆฌ์ง€์— ์—…๋กœ๋“œํ•˜๊ณ , CDN(Content Delivery Network)์„ ํ™œ์šฉํ•ด ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ๋ฐฐํฌ
    • ์ด๋ฅผ ํ†ตํ•ด Nginx๊ฐ€ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ ์—ญํ• ์—๋งŒ ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ฐœ์„ 
  • HTTPS ์ง€์› ๊ฐ•ํ™”
    • Cloudflare ๊ฐ™์€ CDN ์„œ๋น„์Šค์—์„œ HTTPS๋ฅผ ์ œ๊ณตํ•˜๋„๋ก ์„ค์ •ํ•ด ๋ณด์•ˆ ๊ฐ•ํ™”
    • ๋‚ด๋ถ€ ๋„คํŠธ์›Œํฌ์—์„œ๋Š” HTTP ํ†ต์‹ ์œผ๋กœ ์ „ํ™˜ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค ์ตœ์ ํ™”

2. ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ ๋ณ€๊ฒฝ ์‹œ Nginx ์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ ๋ฌธ์ œ ํ•ด๊ฒฐ

  • Nginx ์ด๋ฏธ์ง€์™€ ์ •์  ํŒŒ์ผ์˜ ๋ถ„๋ฆฌ
    • Nginx ์ด๋ฏธ์ง€๋Š” ์ •์  ํŒŒ์ผ ์—†์ด ์„ค์ • ํŒŒ์ผ๋งŒ ํฌํ•จ
    • ํด๋ผ์ด์–ธํŠธ ๋นŒ๋“œ ๊ฒฐ๊ณผ๋ฌผ์€ Nginx ์ปจํ…Œ์ด๋„ˆ์˜ ์™ธ๋ถ€ ๋ณผ๋ฅจ์œผ๋กœ ์—ฐ๊ฒฐํ•˜์—ฌ ์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ ์—†์ด ๋™์ ์œผ๋กœ ์ œ๊ณต
  • ๋ฐฐํฌ ์ž๋™ํ™”
    • CI/CD ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ์ •์  ํŒŒ์ผ ๋นŒ๋“œ ํ›„ ์Šคํ† ๋ฆฌ์ง€๋กœ ์—…๋กœ๋“œํ•˜๊ฑฐ๋‚˜ Nginx ์ปจํ…Œ์ด๋„ˆ์˜ ๋ณผ๋ฅจ์— ๋ฐ”๋กœ ๋ณต์‚ฌ

3. ๋ชจ๋“  ์ž‘์—…์„ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฌธ์ œ ํ•ด๊ฒฐ

  • ์„œ๋น„์Šค ๋ถ„๋ฆฌ
    • HTTP API ์„œ๋ฒ„์™€ WebSocket ์„œ๋ฒ„(Socket.IO)๋ฅผ ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค ๋˜๋Š” ์ปจํ…Œ์ด๋„ˆ๋กœ ๋ถ„๋ฆฌ
    • ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ๋ฐฐํฌ ๋ฐ ์Šค์ผ€์ผ๋ง ๊ฐ€๋Šฅ
  • ๋กœ๋“œ ๋ฐธ๋Ÿฐ์‹ฑ
    • API ์„œ๋ฒ„์™€ WebSocket ์„œ๋ฒ„ ์•ž๋‹จ์— ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ๋ฅผ ๋‘์–ด ํŠธ๋ž˜ํ”ฝ์„ ๊ท ๋“ฑ ๋ถ„๋ฐฐ
    • Nginx๋‚˜ HAProxy, AWS ELB์™€ ๊ฐ™์€ ๋กœ๋“œ ๋ฐธ๋Ÿฐ์„œ ์‚ฌ์šฉ
  • ์˜คํ†  ์Šค์ผ€์ผ๋ง

๐Ÿ˜Ž ์›จ๋ฒ ๋ฒ ๋ฒ ๋ฒฑ

๐Ÿ‘ฎ๐Ÿป ํŒ€ ๊ทœ์น™

๐Ÿ’ป ํ”„๋กœ์ ํŠธ

๐Ÿชต ์›จ๋ฒ ๋ฒฑ ๊ธฐ์ˆ ๋กœ๊ทธ

๐Ÿช„ ๋ฐ๋ชจ ๊ณต์œ 

๐Ÿ”„ ์Šคํ”„๋ฆฐํŠธ ๊ธฐ๋ก

๐Ÿ“— ํšŒ์˜๋ก

Clone this wiki locally