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 실시간 알림 대응 보고서
Docker Named Volume 마이그레이션 트러블 슈팅 보고서
Nginx Certbot (Docker 기반) 설정 트러블슈팅
시스템 구성도
배포 환경: 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 외부에서 접근 가능 |
서비스 흐름
-
사용자가 웹에서 이미지를 업로드 요청
⮕ React가 Spring Boot 서버에 요청 (/api/presigned-url
) -
Spring Boot가 AWS S3용 Pre-signed URL을 생성
⮕ 클라이언트(React)에게 URL 전달 -
React가 S3에 이미지 직접 업로드
⮕ S3에 저장 완료 -
Spring Boot가 업로드된 이미지 URL을 DB(MySQL)에 저장
⮕ 메타데이터 및 앨범 매핑 -
Spring Boot가 S3 이미지 URL을 AI 서버에 전달
⮕ FastAPI (Private Subnet)로 요청 전송 -
AI 서버가 S3에서 이미지를 직접 가져와 분류 작업 수행
⮕ OpenAI CLIP, YOLOv5-Face, ArcFace 모델로 분석 ⮕ 결과를 Spring Boot로 반환 -
Spring Boot가 분석 결과를 DB에 저장하고, React에 응답
⮕ 사용자는 분류된 사진 정보를 웹에서 확인 가능
환경 구분
환경 | 목적 | 특징 |
---|---|---|
Dev | 개발용 | 개발 |
Prod | 실제 서비스 | 실제 운영 |
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 호출 등) |
- 최소 권한 원칙 (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 차단)
↓
[애플리케이션]
-
매주 월요일 오전 10시
이유: 장애발생시 정규 시간중에 빠르게 해결하기 위함(즉각 대응가능)
- 롤백 계획 수립
- 배포 후 알림 연동
- MySQL
- 백업 대상: 유저정보, 이미지 메타데이터, URL 매핑, 앨범 정보 등
- 백업 주기: 주 2회(월/목)
- 백업 방식:
mysqldump
를 활용한 일일 자동 백업 스크립트 -
S3
에 저장, 최대 2주 보관
- S3
- 백업 대상: S3
- 백업 방식: S3 버저닝 및 MFA 삭제 방지 활성화
- 로그
- 애플리케이션 로그 S3에 업로드
- 주 1회, 일요일 00:00
-
ongi.log
파일을tar.gz
로 압축해서 S3로 업로드 - 예시 경로:
s3://ongi-backup/logs/ongi-2025-05-05.tar.gz
- 애플리케이션 로그 S3에 업로드
-
RTO (Recovery Time Objective): 장애 발생 시 전체 시스템을 원상 복구하는 데 허용 가능한 최대 시간
- GCP VM 인스턴스: 이미지 스냅샷을 기반으로 빠르게 재생성
⮕ 30분이내
-
RPO (Recovery Point Objective): 장애 발생 시 복구 시점의 최대 데이터 손실 허용 범위
- MySQL 데이터는 5분 단위로 자동 백업 (InnoDB binlog 또는 스냅샷 기반)
- 이미지 파일은 S3 업로드 시점에 실시간 저장되므로 데이터 유실 없음
⮕ 최대 4일
신규 서비스 배포
- GitHub PR 생성
- 리뷰 및 머지
- VM 인스턴스 접근 후 git pull
- 서비스 중단
- 새로 빌드한 파일로 서버 재빌드
역할 | 머신 타입 | 사양 | 예상 월 요금 |
---|---|---|---|
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 |
자원 항목 | 설명 | 사용량 | 가격 (USD) |
---|---|---|---|
E2 vCPU | 서울 리전에서 vCPU 사용 | 540시간 | $15.13 |
E2 메모리 | RAM 사용량 (GB-시간 기준) | 2160GB-시간 | $8.08 |
영구 디스크 | SSD 디스크 (Balanced PD) 용량 | 50GB | $6.50 |
소계 | $29.71 |
자원 항목 | 설명 | 사용량 | 가격 (USD) |
---|---|---|---|
E2 vCPU | vCPU 사용 | 1080시간 | $30.27 |
E2 메모리 | RAM 사용 | 4320GB-시간 | $16.15 |
영구 디스크 | SSD 디스크 용량 | 30GB | $3.90 |
소계 | $50.32 |
자원 항목 | 설명 | 사용량 | 가격 (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 선정 이유