[CL] Docker 컨테이너화 배포 설계 - 100-hours-a-week/2-hertz-wiki GitHub Wiki

📚 목차


📄 Docker 도입 전략 설명서 (vs 기존 CI/CD 소스 배포)

1. 도입 배경 및 목적

우리 서비스는 짧고 빈번한 배포 준비로 기능이 자주 바뀌고, 푸쉬 알림을 통해 트래픽이 집중되는 시간대도 존재합니다. 이에 따라 개발과 운영 모두 빠르고 민감한 대응이 필수적입니다. 또한 기존 방식은 수동 설치와 운영 서버에 대한 빌드를 직접 수행해서 올려야하는 위험이 존재했습니다. 따라서 다음과 같은 근거로 Docker를 도입하려고 합니다.

1.1 기존 배포 방식의 구조

기존에는 수동으로 초기 인스턴스 환경을 구축하고, GitHub Actions 기반 CI/CD를 통해 소스 코드를 서버에 pull 하여, 해당 서버에서 deploy.sh를 실행해 빌드 및 서비스를 재시작하는 방식으로 배포를 수행했습니다.

GitHub Actions trigger → CI 테스트 → CD 서버로 코드 자동 배포 → 자동 빌드 및 서비스 재시작

1.2 기존 방식의 문제점

문제점 상세 내용
환경 일관성 부족 - 인스턴스마다 Node, Java, Python 등 실행 환경의 수동 설치 필요- 버전 차이로 로컬/서버 불일치 문제 발생
빌드 실패 위험 - 운영 서버 직접 빌드로 OS/의존성 충돌 발생 가능- 빌드 실패 시 운영 서비스 중단 위험
확장성/유연성 부족 - 새로운 인스턴스마다 환경 수동 세팅 필요- 오토스케일링, 무중단 배포 부적합
배포 추적/관리 어려움 - 현재 배포 버전의 커밋 파악 어려움- git 기록에만 의존한 배포 및 운영관리가 불편
롤백 복잡성 및 지연 - 문제가 생기면 pull → 빌드 → 재시작 과정 필요- 빠른 복구가 어려움

1.3 배포 방식 비교

항목 기존 방식 (소스 배포) Docker 기반 배포
배포 속도 5~10분 (서버에서 빌드 포함) 2~3분 (이미지 실행만)
환경 일관성 낮음 매우 높음
확장성 낮음 높음 (이미지 복제)
버전 관리 Git commit 기반 이미지 태그 기반
실패 복구 (롤백) 재배포 필요 이미지 교체로 즉시 복구
운영 복잡도 높은 운영 개입 필요 자동화 가능

1.4. 배포 절차 비교

Before) 기존 배포 절차 (CI/CD)

  1. 각 서비스 별 초기 세팅
  2. GitHub Actions → SSH 접속
  3. deploy.sh 실행 (git pull → PM2 or nohup)
  4. 헬스체크 자동화
  5. Discord 자동 알림 (성공/실패)
  6. 롤백 시 이전 커밋 기록 기반 재 빌드 후 실행

After) Docker 기반 배포 절차

  1. GitHub Actions → Docker Image Build
  2. ECR 푸시
  3. CodeDeploy + ASG 템플릿
  4. Green 인스턴스 생성 및 Docker Run
  5. 헬스체크 자동화
  6. ALB 트래픽 전환 → Blue→Green
  7. Discord 자동 알림 (성공/실패) + 성공 시 Blue 제거
  8. 롤백 시 태깅으로 관리한 이전 버전 이미지로 run(Blue로 전환)

1.5 Docker로 전환 시 기대 효과

  • 배포 시간 50% 이상 단축 빌드 과정 제거, 이미지 실행만으로 배포 완료

  • 운영 환경 일관성 확보 모든 환경에서 동일한 이미지 사용 → 실행 오류 최소화

  • 버전 통제 및 가시성 강화 어떤 이미지가 언제 배포되었는지 태그 및 GitHub Action 기록으로 추적

  • 롤백 용이성 이전 이미지로 교체만 하면 즉시 복구 가능

  • 확장성 및 마이크로서비스 대응력 향상 서비스별 분리된 이미지 관리 → 자동 확장(ASG, ECS 등) 용이

1.6 결론

우리 서비스는 기능이 자주 바뀌고, 트래픽이 집중되는 시간대도 존재합니다. 따라서 개발과 운영 모두 빠르고 민감한 대응이 필수적입니다.

현재는 GitHub Actions로 코드 배포는 자동화했지만, 운영 서버에서 직접 빌드하고 환경을 맞추는 구조는 여전히 불안정하며, 확장성 면에서도 한계가 뚜렷합니다. 그에 비해 Docker는 이미지 패키징을 통한 배포의 통일성을 보장하고, 이미지 태그를 통하여 QA·운영·롤백에 신속한 대응이 가능합니다. 이미지를 사용하기 때문에 단순한 컨테이너 및 인스턴스 복제로 트래픽 급증에 대한 대응이 가능합니다.

특히, FE/BE/AI/WebSocket 등 이기종 환경을 포함하는 3-Tier 구조에서 Docker는 빌드 자동화, 환경 일관성, 배포 속도, 확장성에서 확실한 경쟁력을 제공하여, 서비스의 안정성속도를 모두 확보할 수 있는 가장 현실적인 선택입니다.

따라서 우리는 Docker 기반 컨테이너 환경으로 아키텍처를 마이그레이션하여, 운영 효율성서비스 확장성을 획기적으로 개선하고자 합니다.

2. 컨테이너 관리 전략

2.1 이미지 레지스트리

  • Amazon ECR (Elastic Container Registry) 사용
  • 모든 컨테이너 이미지는 ECR에 저장 및 버전 관리됨
  • CI/CD 파이프라인(GitHub Actions 등)에서 이미지 빌드 후 ECR로 push
  • ECR에 Push → CodeDeploy → EC2 인스턴스 Pull & Deploy 구조 사용

2.2 태깅 정책: 커밋 기반 태그 (branch-shortCommitHash)

2.2.1 태깅 형식

[브랜치명]-[짧은 커밋 해시] ex) main-98a1f2c , develop-98a1f2c

2.2.2 사용 이유 및 장점

  1. 버전 추적성 확보
  • 어떤 커밋을 기준으로 이미지가 빌드되었는지를 명확하게 알 수 있습니다.
  • 특정 문제가 발생했을 때, 해당 커밋 해시를 기준으로 코드와 이미지 상태를 정확히 재현할 수 있습니다.
  1. CI/CD 파이프라인과 연계 용이
  • GitHub Actions에서 커밋 해시를 기반으로 자동으로 태그를 생성할 수 있어 자동화가 용이합니다.
  • 각 배포마다 고유한 태그가 부여되므로 동시 배포 충돌 방지이전 이미지 보존에 유리합니다.
  1. 브랜치별 관리 가능
  • main-xxx, develop-xxx, feature-xxx 식으로 브랜치명 접두어를 사용하면 태그만으로도 운영/테스트 환경 구분이 가능합니다.
  • develop-* 이미지는 스테이징에서만, main-* 이미지는 프로덕션에만 사용할 수 있도록 태그 기반 룰 설정 가능
  1. 롤백 대응이 빠름
  • 배포 시 문제가 발생한 커밋의 태그를 기반으로 즉시 해당 이미지로 롤백 가능
  • 운영 환경에서는 main-a3f1c2d 같은 태그를 기준으로 안전하게 이력 관리

2.3 리소스 할당 정책 (CPU/Memory)

각 컨테이너는 예상되는 부하와 트래픽 패턴 및 테스트를 기준으로 산정하였습니다.

  • 프론트엔드 (Next.js): t3.small(2 vCPU / 2GB)
    • Next.js: --cpus=1, --memory=2g
  • 백엔드 (Spring Boot): t3.medium(2 vCPU / 4GB)
    • cpus=1.5, --memory=3.0g
  • 웹소켓(Socket.IO): t3.medium (2 vCPU / 4GB)     - cpus=1, --memory=1.5g
  • kafka: t3.medium (2 vCPU / 4GB)
    • zookeeper : --cpus=0.5 , --memory=0.5g
    • broker1 : --cpus:2.0 , --memory=2g
    • broker2~3 : --cpus:1.0 , --memory=2g

2.4 개발 환경과 운영 환경의 컨테이너 활용 차이

항목 개발 환경(Dev) 운영 환경(Prod)
인프라 구성 단일 EC2 인스턴스에서 각 서비스 독립 실행 Auto Scaling Group(ASG) 기반 멀티 인스턴스 구성
배포 구조 블루그린 없이 직접 덮어쓰기 방식 배포 Blue-Green 배포 전략 적용 (ALB + 2개 ASG)
컨테이너 실행 방식 GitHub Actions → ECR → CodeDeploy로 자동 배포 GitHub Actions → ECR → CodeDeploy로 자동 배포
네트워크 구성 프론트엔드 ↔ 백엔드 간 직접 인스턴스 IP 통신 ALB가 모든 트래픽을 받아 프론트/백으로 분산
리버스 프록시 Nginx가 Next.js 컨테이너 앞에서 포워딩 동일하게 구성되며, 프론트 ASG 내에서 분산됨
데이터베이스 EC2 내부에서 MySQL, Redis 각 컨테이너 실행 (Private subnet) EC2 내부에서 MySQL, Redis 각 컨테이너 실행 (Private subnet)
헬스체크 및 모니터링 ALB Health Check 연동 예정 ALB Health Check 연동 예정
환경 변수 Github Actions → Dockerfile 빌드 시 Github Secrets로 전달 Github Actions → Dockerfile 빌드 시 Github Secrets로 전달
인증/보안 구성 보안 그룹 제한 없이 개발 편의 우선 EC2/ALB 보안 그룹으로 IP 및 포트 제한 설정

운영 환경은 가용성과 확장성, 장애 대응을 고려하여 Blue-Green 업데이트 및 ASG 등을 갖추고 있으며, 개발 환경은 빠른 테스트와 단일 진입점 구성을 우선시하여 단순한 구조로 유지됨.

3. 인스턴스 부하 테스트

3.1 Backend

wrk -t8 -c100 -d30s http://localhost:9411/api/v2/spans -s post-spans.lua

  • 옵션
    • t8: 8개의 쓰레드
    • c100: 100개의 동시 연결
    • d30s: 30초간 테스트

테스트 결과

항목 t3.medium t3.small
CPU 사용률 107.82% 110.73%
메모리 사용량 332.3MiB / 3GiB (10.82%) 336.3MiB / 1.857GiB (17.69%)
요청 처리량 (RPS) 9,329.94 req/sec 8,685.84 req/sec
총 요청 수 (30초간) 280,032 260,786
전송량 (총) 28.04MB 26.11MB
평균 응답 지연 시간 10.31ms 11.09ms
최대 응답 지연 시간 65.49ms 62.75ms

평가

기준 t3.small t3.medium
단기 테스트 ✅ 충분히 가능 ✅ 더 안정적
실서비스 운영 ⚠️ 성능은 되지만 크레딧/메모리 한계 위험 ✅ 추천
버스트 내성 ⚠️ 크레딧 바닥 시 급격한 저하 ✅ 탄력적 운영 가능
장시간 Span 수집 ⚠️ GC/메모리 스파이크 가능 ✅ 지속 가능성 높음

3.2 kafka

시나리오: “실시간 채팅 서비스 – 50명~70명 동시 접속”을 가정

  • 채팅 유형: 1:1 채팅과 그룹 채팅 혼합
  • 총 메시지 수:
    • 그룹 채팅: 20,000건 (40%)
    • 1:1 채팅: 30,000건 (60%)
  • 메시지 크기: 약 200바이트
  • Kafka 클러스터: 브로커 3개, replication factor 3
  • 전송 속도 제한 (throughput = 5,000 records/sec)
    • 급격한 폭주 없이 초당 약 5,000건 전송 (부드럽게 가하는 부하)
    • 약 10초에 50,000건 → 전체 테스트는 약 10~12초 소요 예상

t3.medium

항목 결과
처리량 매우 안정적 (4900~5000 req/sec)
평균 지연 그룹 70210ms, 개인 2050ms 수준
최대 지연 500~800ms 구간, 점진적으로 개선
리소스 추정 CPU 1.5코어, 메모리 3GB 정도면 충분히 버틸 수 있음
부하 수준 “부드러운 부하”로 정상 작동

📄 시스템 구성도 및 기술 명세(기술 구성 명세)

1. 전체 시스템 구조 개요 (Docker 기반 구성)

아키텍처 다이어그램

Docker - 아키텍처

2. 이미지 빌드 및 배포 흐름

CI/CD 다이어그램

Docker - cicd 파이프라인

  1. GitHub Actions에서 브랜치 푸시(main, develop) 시 CI 트리거
  2. Dockerfile 기반으로 애플리케이션 빌드
  3. Docker 이미지에 다음과 같은 태그 부여 → 예시: main-a1b2c3d, develop-9z8y7x
  4. 빌드된 이미지를 Amazon ECR에 push
  5. 운영 환경에서는 CodeDeploy 와 Auto Scaling Group(ASG)을 통해 다음 절차로 무중단 배포를 수행
    • 신규 버전 배포를 위한 EC2 인스턴스를 ASG에 의해 자동 생성
    • 새 인스턴스에서 ECR로부터 최신 Docker 이미지 pull 및 컨테이너 실행
    • Blue ↔ Green 전환: CodeDeploy가 기존 Target Group에서 기존 인스턴스를 제거하고, 새 인스턴스를 새 Target Group에 등록
    • 헬스체크 성공 시, ALB 트래픽을 새로운 Target Group(Green)으로 전환
  6. 이전 버전은 일정 시간 유지 후 desired=0 설정으로 종료하거나 완전히 삭제

CI/CD 파이프라인은 서비스 단위로 분리되어 있으며, 프론트엔드와 백엔드, AI는 각각 독립적으로 배포됩니다.

3. 네트워크 및 연결 구조

  • 운영 환경: 프론트엔드, 백엔드, WebSocket 서버는 각각 독립된 Auto Scaling Group에서 실행되며, 모든 요청은 ALB를 통해 분산됩니다.
  • 컨테이너 내부 네트워크는 기본적으로 bridge 모드 사용
  • 프론트(Nginx)Next.js: 동일 EC2 내 컨테이너 간 http://nextjs:3000으로 연결
  • 프론트 → 백엔드 API 요청: ALB를 통해 백엔드 ASG로 라우팅됨
  • 프론트 → WebSocket 연결: wss://socket.example.com 도메인을 통해 직접 WebSocket 서버에 연결

4. 데이터 볼륨 및 영속성 전략

서비스 데이터 저장 방식
MySQL /data/mysql:/var/lib/mysql로 EC2의 로컬 디스크에 마운트
Redis /data/redis:/data로 RDB snapshot을 EC2 내에 보존
Next.js, Spring Boot, WebSocket Stateless 서비스로 데이터 저장 없음. 배포 및 재시작에 영향 없음
  • RDS 사용 전에는 DB 서버를 별도의 EC2 인스턴스에 구성하여 프론트/백엔드 컨테이너와 분리
  • 데이터 컨테이너는 private subnet에서 실행되며 외부 접근은 차단됨
  • 백엔드 컨테이너는 Redis와 MySQL에 내부 IP로 직접 접근

5. Dockerfile 예시

Frontend(Next.js+Nginx)

Dockerfile

# 1단계: 빌드
FROM node:18-alpine AS builder

WORKDIR /app
COPY ./package*.json ./
RUN npm install
COPY . .
RUN npm run build

# 2단계: 실행용
FROM node:18-alpine AS runner

WORKDIR /app

ENV NODE_ENV=production

# node_modules와 .next만 가져옴
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./

CMD ["npm", "run", "start"]

docker-compose.frontend.yml

version: '3.8'

services:
  nextjs:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: nextjs-app
    restart: always
    environment:
      - PORT=3000
    ports:
      - "3000:3000"  # 외부에서 바로 접근 가능하도록 매핑
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 2g
    networks:
      - frontend-net

networks:
  frontend-net:
    driver: bridge

Backend(Spring Boot)

Dockerfile

# 1. Java 17 기반 이미지 사용
FROM eclipse-temurin:17-jdk-alpine as builder

# 2. 작업 디렉토리 설정
WORKDIR /app

# 3. 빌드에 필요한 파일 복사
COPY gradlew .
COPY gradle gradle
COPY build.gradle settings.gradle ./
COPY src src

# 4. 의존성 캐시
RUN ./gradlew dependencies || return 0

# 5. 애플리케이션 빌드
RUN ./gradlew clean build -x test

# --- 실제 실행 이미지로 옮기기 ---
FROM eclipse-temurin:17-jdk-alpine

# 앱 실행 디렉토리
WORKDIR /app

# JAR 파일 복사 (최신 버전 자동 복사)
COPY --from=builder /app/build/libs/*.jar app.jar

# 8080 포트 오픈
EXPOSE 8080

# 실행
ENTRYPOINT ["java", "-jar", "app.jar"]

docker-compose.backend.yaml

version: "3.8"

services:
  springboot-server:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: springboot-server
    ports:
      - "8080:8080"
    deploy:
      resources:
        limits:
          cpus: "1.5"
          memory: 3g
    environment:
      SPRING_PROFILES_ACTIVE: prod
    restart: always
****

Socket.IO

Dockerfile

FROM node:18-alpine

WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

EXPOSE 5000
CMD ["node", "server.js"]

docker-compose.websocket.yml

version: "3.8"

services:
  socket-server:
    build: .
    container_name: socket-server
    ports:
      - "5000:5000"
    environment:
      - PORT=5000
      - CORS_ORIGIN=https://app.example.com
      - REDIS_HOST=redis://redis:6379
    depends_on:
      - redis
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 1.5g

AI(Fast API)

Dockerfile

FROM python:3.10-slim

# 기본 디렉토리 생성
WORKDIR /app

# requirements.txt 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 애플리케이션 소스 복사
COPY . .

EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

docker-compose.ai.yaml

version: "3.8"

services:
  ai-server:
    build: ./ai-server
    container_name: ai-server
    ports:
      - "8000:8000"
    volumes:
      - ./ai-server:/app
      - ./ai-server/model:/app/model  # 파인튜닝 모델 경로 공유
    environment:
      - CHROMA_HOST=http://chroma-db:8001
    depends_on:
      - chroma-db

  chroma-db:
    image: chromadb/chroma
    container_name: chroma-db
    ports:
      - "8001:8000"
    volumes:
      - chroma_data:/chroma/.chromadb

volumes:
  chroma_data:

kafka

docker-compose.kafka.yaml

version: '3.8'

services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.5.0
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka1:
    image: confluentinc/cp-kafka:7.5.0
    container_name: kafka1
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

  kafka2:
    image: confluentinc/cp-kafka:7.5.0
    container_name: kafka2
    ports:
      - "9093:9093"
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9093
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

  kafka3:
    image: confluentinc/cp-kafka:7.5.0
    container_name: kafka3
    ports:
      - "9094:9094"
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

6. Docker 기술 요소 요약

구성 요소 베이스 이미지 컨테이너 수 주요 포트 역할
Next.js node:18-alpine EC2 당 1개 3000 클라이언트 UI 및 SSR
Spring Boot eclipse-temurin:17-jdk-alpine EC2 당 1개 8080 API 서버
Socket.IO node:18-alpine EC2 당 1개 5000 실시간 메시지 송수신 처리 (WebSocket 기반)
FastAPI python:3.10-slim 인스턴스 당 1개 8000 AI API 서버 + 추론 모델
MySQL mysql:8.0 EC2 당 1개 3306 사용자 및 메시지 저장
Redis redis:7.0-alpine EC2 당 1개 6379 Pub/Sub 및 캐시
Kafka Broker confluentinc/cp-kafka:7.5.0 EC2 당 3개 9092~9094 메시지 큐 역할, WebSocket ↔ Backend 연계
Zookeeper confluentinc/cp-zookeeper:7.5.0 EC2 당 1개 2181 Kafka 클러스터 메타데이터 저장 및 브로커 관리

7. 전체 환경 변수 목록

Next.js

환경변수 설명 예시
NEXT_PUBLIC_API_URL 브라우저에서 사용할 백엔드 API의 주소 https://api.example.com
NODE_ENV 환경 구분 (개발/운영) production 또는 development

Spring Boot

환경변수 설명 예시
SPRING_DATASOURCE_URL MySQL DB 접속 주소 (JDBC 포맷) jdbc:mysql://db:3306/appdb
SPRING_DATASOURCE_USERNAME DB 접속 ID appuser
SPRING_DATASOURCE_PASSWORD DB 접속 비밀번호 securepassword
JWT_SECRET JWT 서명 키 (보안 정보) super-secret-key
REDIS_HOST Redis 접속 주소 redis://redis:6379
FAST_API_URL AI 서버 URL https://ai-api.example.com

Socket.IO

환경변수 설명 예시
PORT Socket.IO 서버가 리스닝할 포트 5000
CORS_ORIGIN 허용된 CORS Origin 주소 https://app.example.com
REDIS_HOST Redis Pub/Sub 백엔드 주소 redis://redis:6379
NODE_ENV 실행 환경 구분 production

AI (fastAPI + ai model)

환경변수 설명 예시
API_HOST FastAPI가 바인딩할 호스트 0.0.0.0
API_PORT FastAPI가 리스닝할 포트 8000
ENV 실행 환경 development, production
CHROMA_HOST ChromaDB가 실행 중인 호스트명 localhost 또는 chroma
CHROMA_PORT ChromaDB 포트 8001
CHROMA_COLLECTION_NAME 유사도 검색에 사용할 컬렉션명 user_embeddings

MySQL

환경변수 설명 예시
MYSQL_ROOT_PASSWORD 루트 비밀번호 (초기화 시 필요) rootpass123
MYSQL_DATABASE 자동 생성할 기본 DB 이름 appdb

Redis

환경변수 설명 예시
없음 Redis는 별도 환경변수 없이 기본 설정으로 실행 가능 -

Kafka

경변수 설명 예시
KAFKA_BROKER_ID 브로커 고유 ID (중복 불가) 1, 2, 3
KAFKA_ZOOKEEPER_CONNECT 연결할 Zookeeper 호스트 목록 zookeeper:2181
KAFKA_ADVERTISED_LISTENERS 외부 클라이언트가 접속할 주소 (컨테이너 외부 노출) PLAINTEXT://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP 리스너 명칭 → 프로토콜 매핑 PLAINTEXT:PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR Consumer Group 오프셋 저장용 토픽 복제 수 1 (테스트) / 3 (운영)
KAFKA_LOG_RETENTION_HOURS 메시지 보관 시간 (기본값: 168시간 = 7일) 168
KAFKA_MESSAGE_MAX_BYTES 최대 메시지 크기 (Byte) 1000000

환경 변수는 모두 Github Secrets을 이용해서 관리할 예정임


📄 AWS 최종 비용 산정

1. 비용 산정 기준

  • 일일 활성 사용자 (DAU): 약 150명
  • 프론트엔드(Next.js) 평균 트래픽: 500MB~1GB/일
  • 웹소켓(Socket.IO) 활성 연결 수: 평균 100명 동시 접속
  • API 호출량: 약 10,000~20,000회/일
  • Kafka 트래픽: 소형 메시지 기준, 10GB/월 미만
  • DB 트래픽(MySQL/Redis): 소형 트래픽, 캐시 중심 구조

2. 세부 예상 비용

그룹 리전 서비스 설명 구성 요약 월별 비용 (USD)
ALB-public 서울(ap-northeast-2) Application Load Balancer 프론트엔드 트래픽 수용 ALB 수 (1) 19.35
ALB-private 서울(ap-northeast-2) Application Load Balancer 백엔드 API 트래픽 수용 ALB 수 (1) 17.89
NAT G/W 서울(ap-northeast-2) NAT Gateway 워커노드, 백엔드 아웃바운드 NAT G/W 수 (1) 43.1
S3-deploy-script (Storage) 서울(ap-northeast-2) S3 Standard Deploy Script 저장 1GB 스토리지, PUT/COPY/POST/LIST 요청(60), GET 요청(100) 0.03
S3-deploy-script (Data Transfer) 서울(ap-northeast-2) Data Transfer 스크립트 파일 전송 트래픽 Inbound/Outbound 0TB 0
ECR-docker 서울(ap-northeast-2) Elastic Container Registry Docker Image 저장 저장 5GB, Pull 5GB/월 1.13
WAF 서울(ap-northeast-2) AWS Web Application Firewall 웹 공격 방어 웹 ACL 1개, 규칙 5개, 그룹 1개 16.6
EC2-frontend 서울(ap-northeast-2) EC2 (t3.small) Next.js 프론트엔드 서버 1대, 20GB EBS 20.8
EC2-backend 서울(ap-northeast-2) EC2 (t3.medium) Spring Boot 백엔드 서버 1대, 30GB EBS 40.7
EC2-websocket 서울(ap-northeast-2) EC2 (t3.medium) Socket.IO 웹소켓 서버 1대, 30GB EBS 40.7
EC2-kafka 서울(ap-northeast-2) EC2 (t3.medium) Kafka 브로커 + Zookeeper 서버 1대, 30GB EBS 40.7
EC2-DB 서울(ap-northeast-2) EC2 (t3.medium) MySQL + Redis 서버 1대, 100GB EBS 54.33

3. 리소스 설명

  • ALB-public: Next.js(프론트엔드) 트래픽 수용
  • ALB-private: 프론트 → 백엔드 API 요청 수용
  • NAT Gateway: 워커노드 및 백엔드 서버의 외부 요청 처리
  • S3-deploy-script: GitHub Actions용 배포 스크립트 저장
  • ECR-docker: Docker 이미지 저장소
  • WAF: Application Load Balancer 보안 강화
  • EC2-frontend: Next.js 서버 구동
  • EC2-backend: Spring Boot API 서버 구동
  • EC2-websocket: Socket.IO 기반 WebSocket 서버 구동
  • EC2-kafka: Kafka 브로커 및 Zookeeper 구동
  • EC2-DB: MySQL, Redis 데이터베이스 서버 구동

4. 총 월 예상 비용

총 월 예상 비용: 약 295.33 USD

👉 AWS Pricing Calculator 링크 보기


📄 GCP 최종 비용 산정

1. 비용 산정 기준

  • GCP 리소스는 모두 서울 리전(asia-northeast3) 에 배치합니다.
  • GCE 인스턴스는 월 730시간을 기준으로 고려했습니다.
  • GPU 서버는 월 90시간만 사용하여, 비용 최적화를 고려했습니다.

2. 세부 예상 비용

그룹 리전 서비스 설명 구성 요약 월별 비용 (USD)
GCE-ai-embeded 서울(asia-northeast3) Compute Engine AI 임베딩 서버 (CPU Only) e2-standard-4, 4vCPU, 16GB RAM, 50GB 디스크 132.01
GPU-ai (NVIDIA L4) 서울(asia-northeast3) Cloud GPU AI Inference용 GPU 서버 (90시간 사용) g2-standard-4, 4vCPU, 16GB RAM, L4 GPU 0.1개 81.69
GCE-ai-moderation 서울(asia-northeast3) Compute Engine Moderation 서버 (채팅 클린봇 서버) e2-standard-2, 2vCPU, 8GB RAM, 10GB 디스크 64.05

3. 리소스 설명

  • GCE-ai-embeded: 사용자 추천, 검색 임베딩 서비스용 CPU 서버
  • GPU-ai (NVIDIA L4): 대형 LLM 기반 인퍼런스 처리용 GPU 서버 (90시간/월 가동)
  • GCE-ai-moderation: 채팅 Moderation(클린봇) 처리용 경량 AI 서버

4. 총 월 예상 비용

총 월 예상 비용: 약 277.76 USD

(※ GCP 온디맨드 기준, 별도 할인 프로그램 적용 없음)

👉 GCP Calculator 링크 보기