Cloud 1차 릴리즈 ‐ 단일 인스턴스 기반 MVP - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

이 페이지는 프로젝트의 1차 릴리즈(단일 인스턴스 기반 MVP)에 관한 전반적인 내용을 문서화한 페이지입니다.


단계별 작업

[1단계 - Big Bang 방식 수작업 배포]
[2단계 - CI(지속적 통합) 파이프라인 구축]
[3단계 - CD(지속적 배포) 파이프라인 구축]

관련 문서

Spring Boot 로그 S3 자동 저장 및 Discord 알림 시스템
MySQL, Bind Mount → Docker Named Volume
CloudFront S3를 통한 커스텀 도메인 이미지 제공 구성 가이드
Fail2Ban 기반 침입 차단 및 Discord 실시간 알림 대응 보고서

TroubleShooting

Docker Named Volume 마이그레이션 트러블 슈팅 보고서
Nginx Certbot (Docker 기반) 설정 트러블슈팅


01. 아키텍처 개요

5-ys-Architecture-단일 인스턴스 설계 drawio

시스템 구성도
배포 환경: GCP 단일 인스턴스 기반 + AWS S3 연동

GCP Pubulic Subnet VM1

구성요소 역할
Nginx 리버스 프록시, 정적 자원 처리
React (FE) 사용자에게 웹 UI 제공
Spring Boot (BE) Pre-signed URL 생성, 메타데이터 DB 저장
MySQL 이미지와 태그 정보, URL 매핑 데이터 저장
Redis 로그인 세션 저장

GCP Private Subnet VM2

구성요소 역할
FastAPI (AI 서버) 이미지 분류 모델 호출 (CLIP, YOLOv5-Face, ArcFace)

AWS

구성요소 역할
AWS S3 이미지 저장소 역할, Pre-signed URL 방식으로 직접 업로드/다운로드 수행

네트워크 구성

서브넷 설명
Public Subnet (10.10.10.0/24) 사용자 요청을 처리하는 React, SpringBoot, Nginx서버와 AI 서버(FastAPI 및 모델들)가 위치
VPC (10.10.0.0/16) GCP 내부 네트워크로 구성된 가상 네트워크
AWS Cloud (S3) 객체 스토리지 역할, GCP 외부에서 접근 가능

서비스 흐름

  1. 사용자가 웹에서 이미지를 업로드 요청
    ⮕ React가 Spring Boot 서버에 요청 (/api/presigned-url)

  2. Spring Boot가 AWS S3용 Pre-signed URL을 생성
    ⮕ 클라이언트(React)에게 URL 전달

  3. React가 S3에 이미지 직접 업로드
    ⮕ S3에 저장 완료

  4. Spring Boot가 업로드된 이미지 URL을 DB(MySQL)에 저장
    ⮕ 메타데이터 및 앨범 매핑

  5. Spring Boot가 S3 이미지 URL을 AI 서버에 전달
    ⮕ FastAPI (Private Subnet)로 요청 전송

  6. AI 서버가 S3에서 이미지를 직접 가져와 분류 작업 수행
    ⮕ OpenAI CLIP, YOLOv5-Face, ArcFace 모델로 분석 ⮕ 결과를 Spring Boot로 반환

  7. Spring Boot가 분석 결과를 DB에 저장하고, React에 응답
    ⮕ 사용자는 분류된 사진 정보를 웹에서 확인 가능

02. 환경 구성

환경 구분

환경 목적 특징
Dev 개발용 개발
Prod 실제 서비스 실제 운영

03. 보안 설계

보안그룹

inbound

대상 포트 소스 IP 설명
Nginx (Public Subnet) 80, 443 0.0.0.0/0 외부에서 접근 허용 (HTTP/HTTPS)
SpringBoot 8080 10.10.10.0/24 내부 IP에서만 허용 (ex. 10.10.10.0/24)
FastAPI (Private Subnet) 8000 10.10.10.0/24, 10.10.20.0/24 SpringBoot에서 AI 서버로 통신
MySQL 3306 10.10.10.0/24, 10.10.20.0/24 내부 접근만 허용
SSH (관리자만) 22 관리자 고정 IP만 관리자 IP로만 제한

outbound

대상 포트 소스 IP 설명
전체 443,80,53 0.0.0.0/0 외부 통신 허용 (S3, API 호출 등)

IAM 정책

  • 최소 권한 원칙 (Least Privilege)
  • Role 기반 접근 제어 (RBAC)
  • 외부 요청의 진입점인 Nginx에 대해 접근 제어
구성원 필요한 권한(한글 이름) 역할 ID 설명
AI - 저장소 개체 관리자
- 저장소 관리자
- roles/storage.admin
- roles/storage.objectAdmin
학습/추론을 위한 이미지 파일 읽기, 분류 결과 전송
BE - 저장소 개체 관리자
- 저장소 객체 서명자
- Secret Manager 비밀 읽기 접근자
- 로깅 뷰어
- roles/storage.objectAdmin(객체에 접근 업로드)
- roles/storage.objectSigner (Signed URL 생성전용)
- roles/logging.viewer
- roles/secretmanager.secretAccessor
API 서버가 객체를 업로드하고 로그/비밀키 접근
FE - 스토리지 객체 뷰어 - roles/storage.objectViewer
- roles/firebasehosting.admin
정적 자산을 보기 위한 GCS 접근, Firebase 배포

보안 플로우

[인터넷]
    ↓
[Security Group] (1차 포트 필터)
    ↓
[서버: UFW 방화벽] (2차 포트/프로토콜 필터)
    ↓
[Fail2ban] (비정상 시도 감지 후 IP 차단)
    ↓
[애플리케이션]

04. 배포 전략

  1. 매주 월요일 오전 10시

    이유: 장애발생시 정규 시간중에 빠르게 해결하기 위함(즉각 대응가능)

배포 전 꼭 확인할 것

  • 롤백 계획 수립
  • 배포 후 알림 연동

05. 재해 복구 및 백업

백업 전략

  1. MySQL
    • 백업 대상: 유저정보, 이미지 메타데이터, URL 매핑, 앨범 정보 등
    • 백업 주기: 주 2회(월/목)
    • 백업 방식: mysqldump를 활용한 일일 자동 백업 스크립트
    • S3에 저장, 최대 2주 보관
  2. S3
    • 백업 대상: S3
    • 백업 방식: S3 버저닝 및 MFA 삭제 방지 활성화
  3. 로그
    • 애플리케이션 로그 S3에 업로드
      • 주 1회, 일요일 00:00
      • ongi.log 파일을 tar.gz로 압축해서 S3로 업로드
      • 예시 경로: s3://ongi-backup/logs/ongi-2025-05-05.tar.gz

복구 전략

  • RTO (Recovery Time Objective): 장애 발생 시 전체 시스템을 원상 복구하는 데 허용 가능한 최대 시간

    • GCP VM 인스턴스: 이미지 스냅샷을 기반으로 빠르게 재생성

    ⮕ 30분이내

  • RPO (Recovery Point Objective): 장애 발생 시 복구 시점의 최대 데이터 손실 허용 범위

    • MySQL 데이터는 5분 단위로 자동 백업 (InnoDB binlog 또는 스냅샷 기반)
    • 이미지 파일은 S3 업로드 시점에 실시간 저장되므로 데이터 유실 없음

    ⮕ 최대 4일

06. 운영 가이드

신규 서비스 배포

  1. GitHub PR 생성
  2. 리뷰 및 머지
  3. VM 인스턴스 접근 후 git pull
  4. 서비스 중단
  5. 새로 빌드한 파일로 서버 재빌드

07. 사용 도구 및 버전

역할 머신 타입 사양 예상 월 요금
Web 서버 (Nginx + React + Spring Boot) e2-standard-4 4vCPU / 16GB RAM 약 $106.56
AI CPU 서버 e2-medium 2vCPU / 4GB RAM 약 $24.19
AI GPU 서버 n1-standard-4 + NVIDIA T4 4vCPU / 15GB RAM + 1 GPU 약 $247.92

08. GCP 비용 정리 (예상 총합: $249.11 / 약 34만 원)

FE + BE + DB 인스턴스 (웹/백엔드/DB 서버)

자원 항목 설명 사용량 가격 (USD)
E2 vCPU 서울 리전에서 vCPU 사용 540시간 $15.13
E2 메모리 RAM 사용량 (GB-시간 기준) 2160GB-시간 $8.08
영구 디스크 SSD 디스크 (Balanced PD) 용량 50GB $6.50
소계 $29.71

AI 서버 (CPU 서버)

자원 항목 설명 사용량 가격 (USD)
E2 vCPU vCPU 사용 1080시간 $30.27
E2 메모리 RAM 사용 4320GB-시간 $16.15
영구 디스크 SSD 디스크 용량 30GB $3.90
소계 $50.32

AI 서버 (GPU 서버)

자원 항목 설명 사용량 가격 (USD)
N1 vCPU vCPU 사용 1068시간 $43.38
N1 메모리 RAM 사용 4005GB-시간 $21.70
NVIDIA T4 GPU GPU 사용 267시간 $98.79
영구 디스크 HDD 디스크 용량 100GB $5.20
소계 $169.07

총합: $249.11 (약 34만 원/월)

📎 참고 링크


기술 선정 배경

S3 도입 - 이미지 업로드 성능 비교

Nginx 도입 - Proxy Server 사용 이유 및 Nginx 선정 이유

⚠️ **GitHub.com Fallback** ⚠️