Cloud 과제 1단계: Big Bang 방식 수작업 배포 - 100-hours-a-week/5-yeosa-wiki GitHub Wiki

☁️ Cloud 배포 설계


1단계: Big Bang 방식 수작업 배포

이 문서는 <온기> 서비스의 클라우드 초기 단계에서 적요되는 Bing Bang 방식 수작업 배포 방식을 정리한 것입니다.

왜 Big Bang 배포를 도입하였는가?

<온기>는 프로젝트 초기 단계로 사용자 수가 적고 배포 빈도도 낮아 자동화 도입보다는 수작업이 빠르다고 판단했습니다.

단일 GCP 인스턴스에서 운영되므로, 단순한 구조에서 빠르게 배포하고 검증할 수 있는 점이 현재 상황에 적합했습니다.

다음은 서비스 동작방식, MVP 아키텍쳐, 배포 프로세스 설명 그리고 Bing Bang 배포의 한계점과 개선점을 정리하였습니다.

1. 서비스 동작방식

<온기> 서비스는 사용자 요청에 따라 이미지 업로드, AI 분류, 태그 저장 및 앨범 생성까지의 흐름을 단일 GCP 인스턴스 기반으로 처리하고 있으며, 전체 서비스는 다음과 같은 방식으로 동작합니다.

  • 사용자는 React 기반 프론트엔드를 통해 이미지를 업로드합니다.
  • 이미지 파일은 Presigned URL을 통해 Google Cloud Storage(GCS)에 직접 저장됩니다.
  • 업로드 완료 후, Spring Boot 백엔드 서버는 해당 이미지들의 경로와 앨범 정보를 AI 서버에 전달하고, AI는 이미지 내용을 분석하여 태그별로 분류합니다.
  • AI 서버는 분류된 태그 정보를 백엔드에 반환하고, 백엔드는 이를 MySQL에 저장하여 앨범과 태그 정보로 활용합니다.
  • 프론트엔드는 다시 사용자가 요청할 때 저장된 태그 기반으로 이미지를 불러오고, 앨범 내 사진 추가 시에는 전체 이미지를 기반으로 다시 분류가 진행됩니다.

이러한 전체 흐름은 React → Nginx → Spring Boot → AI 서버 → GCS/MySQL로 이어지는 단방향 또는 피드백 기반의 구성입니다.

2. MVP 아키텍쳐

[GCP Project]
   └── VPC: ongi-mvp-vpc (10.0.0.0/20)
         └── Subnet: asia-northeast3 (10.178.0.0/20)
                └── VM1: Nginx, React, Spring Boot, MySQL
                └── VM2: AI CPU 인스턴스
                └── VM3: AI GPU 인스턴스
  • Google Cloud Platform의 인스턴스를 활용
  • 단일 인스턴스 + AI(CPU,GPU서버) 총 3개 인스턴스 사용
  • 단일 인스턴스 nginx(proxy server)-front-back-db 구축
  • AI 모델이 들어갈 GPU 인스턴스
  • 정적 파일 Presigned URL로 S3에 저장 후 서버에서 호출
  • 현재 서비스 웹의 모든 구성 요소(frontend, backend, DB)는 동일 인스턴스 내부에서 동작하고, AI 모델은 총 3개로 CPU 인스턴스에서 2개, GPU인스턴스에서 1개의 모델을 처리
구성 요소 역할 머신 타입 사양 예상 월 요금
VM1 Web 서버 (Nginx + React + Spring Boot) e2-standard-4 4vCPU / 16GB RAM 약 $48.40
VM2 AI CPU 서버 e2-standard-4 4vCPU / 16GB RAM 약 $48.40
VM3 AI GPU 서버 n1-standard-4 + NVIDIA T4 4vCPU / 15GB RAM + 1 GPU 약 $247.92
GCS 사용자 이미지 저장소 (Presigned URL 방식 사용) - - 약 $5.2 (약 200GB 기준)

2-1. 구성도

5-ys-MVP-v2

간단한 구조도: 단일 GCP VMnginx → frontend → backend → DB -> AI

구성 요약:

  • Frontend: React (정적 빌드 파일) → Nginx 통해 /에서 서비스
  • Backend: Spring Boot (8080 포트) → MySQL, GCS, AI 서버 연동
  • AI 서버:
    • 썸네일 생성 인스턴스
    • 이미지 분류 인스턴스
  • Cloud Storage (GCS): 이미지 저장
  • MySQL: 메타데이터 저장

2-2. AI 서버 분리 이유

온기 서비스는 총 3개의 AI 모델을 사용하고 있으며, 이 중 2개는 CPU에서, 1개는 GPU에서 실행됩니다.

특히 CPU 기반 AI 모델들은 동시 다중 이미지 처리를 위해 CPU 전체 코어(400%)를 점유하며 작동하기 때문에,

Web 서버(Spring Boot, React 등)와 동일한 인스턴스에서 실행할 경우 자원 충돌로 인해 웹 서버가 다운될 위험이 매우 높습니다.

이에 따라 아래와 같은 구조적 분리를 적용하였습니다.

  • CPU 모델 분리: CPU 리소스를 많이 사용하는 AI 모델 2개는 전용 e2-standard-4 서버에서 독립 실행
  • GPU 모델 분리: 대형 AI 모델은 별도의 GPU 인스턴스에서 운영
  • 웹 서비스와 분리: Web 서버는 사용자 요청 처리 및 API 응답을 안정적으로 유지하기 위해 AI와 분리

이렇게 역할 기반으로 인스턴스를 분리함으로써, 각 구성 요소의 성능을 최대한 활용하고

서비스 안정성확장 가능성을 동시에 확보할 수 있습니다.

2-3. 프록시 경로 설정

  • /etc/nginx/sites-available/ongi.conf
server {
    listen 80;
    server_name localhost;

    # React 정적 파일 제공
    root /var/www/html;
    index index.html index.htm;

    location / {
        try_files $uri /index.html;
    }

    # Spring Boot API 프록시
    location /api/ {
        proxy_pass http://localhost:8080/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 이미지 등 정적 리소스 요청
    location /static/ {
        alias /var/www/html/static/;
    }
}

3. 배포 프로세스 설명서

단계 작업 내용 도구/명령어 예상 시간 담당자
1 기존 프로세스 중지 sudo kill -9 <PID> 또는 pkill -f jar 1분
2 프로젝트 디렉토리 이동 및 최신 코드 Pull cd ~/5-yeosa-ongi-be && git pull origin main 1분
3 Spring Boot 빌드 ./gradlew clean build 1~2분
4 jar 실행 java -jar build/libs/ongi-server-0.0.1-SNAPSHOT.jar & 1분
5 React 빌드 cd ~/5-yeosa-ongi-fe && npm run build 1~2분
6 빌드된 프론트엔드 파일을 Nginx 디렉토리로 복사 cp -r build/* /var/www/frontend/ 1분
7 Nginx 재시작 sudo systemctl restart nginx 1분
8 배포 확인 브라우저 접속 후 테스트 1~2분

⏱️ 총 소요 시간 약 8~10분

⚠️ Spring Boot 재시작 중 약 2~3분간 API 중단 발생 가능


3-1. 배포 전 준비 사항

  • GCP 인스턴스에 SSH 접속 가능한 상태인지 확인
  • GitHub 접근을 위한 SSH Key 또는 Personal Access Token 등록 여부 확인
  • MySQL DB, GCS, AI 서버 등 외부 연동 서비스 정상 작동 여부 확인

3-2. 배포 절차

  1. GCP 인스턴스에 SSH 접속
  2. Spring Boot 프로젝트 디렉토리로 이동 후 git pull로 최신 코드 반영
  3. ./gradlew clean build로 jar 파일 빌드
  4. 기존 프로세스 종료 후 새 jar 실행
  5. 프론트엔드 디렉토리로 이동해 npm run build
  6. 빌드된 정적 파일을 Nginx 디렉토리에 복사
  7. Nginx 재시작 후 서비스 정상 여부 확인

3-3. 배포 스크립트

#!/bin/bash

# 변수 정의
APP_DIR="/home/ubuntu/ongi"
FRONT_DIR="$APP_DIR/frontend"
BACK_DIR="$APP_DIR/backend"
JAR_NAME="ongi-server-0.0.1-SNAPSHOT.jar"
NGINX_HTML_DIR="/var/www/html"
BACKUP_DIR="/home/ubuntu/backup/$(date +'%Y%m%d-%H%M')"

# 백업 과정
mkdir -p $BACKUP_DIR/html
mkdir -p $BACKUP_DIR/backend

# 백엔드 백업
if [ -f "$JAR_PATH" ]; then
  cp $JAR_PATH $BACKUP_DIR/backend/
fi

if [ -d "$NGINX_HTML_DIR" ]; then
  cp -r $NGINX_HTML_DIR/* $BACKUP_DIR/html/
fi

# 1. 기존 백엔드 프로세스 종료
pkill -f $JAR_NAME

# 2. 코드 최신화
cd $APP_DIR || exit
git reset --hard HEAD
git pull origin main

# 3. 백엔드 빌드 및 실행
cd $BACK_DIR || exit
./gradlew clean build

# 백엔드 애플리케이션 실행
nohup java -jar build/libs/$JAR_NAME > logs/backend.log 2>&1 &

# 4. 프론트엔드 빌드
cd $FRONT_DIR || exit
npm install
npm run build

# 5. Nginx 경로로 프론트엔드 파일 복사
sudo rm -rf $NGINX_HTML_DIR/*
sudo cp -r build/* $NGINX_HTML_DIR/

# 6. Nginx 재시작
sudo systemctl restart nginx

# 7. 완료 메시지
echo "배포 완료"

사용방법

  1. GCP 인스턴스에 저장 (예: /home/ubuntu/deploy.sh)

  2. 실행 권한 부여

    chmod +x deploy.sh
  3. 배포할 때마다 실행

    ./deploy.sh

3-4. 롤백 전략

서비스 배포 중 문제가 발생했을 경우, 이전 정상 버전으로 빠르게 되돌릴 수 있는 절차입니다. <온기> 서비스는 VM환경이므로 jar파일과 정적 파일(build 디렉토리)의 백업/복구를 통해 롤백합니다.

수동 롤백 전략 (배포 전 백업)

# 백업 디렉토리 생성
mkdir -p ~/backup/$(date +"%Y%m%d-%H%M")

# jar 및 빌드 파일 백업
cp ~/ongi/backend/build/libs/on.jar ~/backup/$(date +"%Y%m%d-%H%M")/
cp -r /var/www/html ~/backup/$(date +"%Y%m%d-%H%M")/html

3-5. 문제 발생 시 롤백 절차

단계 설명 명령어 예시
1 현재 애플리케이션 종료 pkill -f ongi-server-0.0.1-SNAPSHOT.jar
2 백업된 jar 복원 cp ~/backup/20250417-1125/ongi-server-0.0.1-SNAPSHOT.jar ~/ongi/backend/build/libs/
3 이전 버전 jar 실행 nohup java -jar ~/ongi/backend/build/libs/ongi-server-0.0.1-SNAPSHOT.jar &
4 프론트엔드 정적 파일 롤백 sudo rm -rf /var/www/html/* && sudo cp -r ~/backup/20250417-1125/html/* /var/www/html/
5 Nginx 재시작 sudo systemctl restart nginx
6 롤백 완료 확인 브라우저에서 서비스 정상 작동 여부 확인

3-6. 배포 체크리스트

단계 체크 항목 체크
1. 서버 접속 및 권한 확인 GCP VM 인스턴스에 SSH 접속 가능한지 확인 (ssh ubuntu@<IP>) [ ]
배포 스크립트에 실행 권한 부여 완료 (chmod +x deploy.sh) [ ]
GitHub 접근을 위한 SSH Key 또는 Personal Access Token 설정 완료 [ ]
sudo 명령어 실행 가능 여부 확인 (Nginx 재시작 등) [ ]
2. 코드 및 환경 점검 백엔드 디렉토리에서 git pull origin main으로 최신 코드 반영 [ ]
프론트엔드 디렉토리에서도 최신 코드 반영 [ ]
백엔드 빌드 (./gradlew clean build) 성공 여부 확인 [ ]
프론트엔드 빌드 (npm install, npm run build) 성공 여부 확인 [ ]
3. 외부 서비스 연동 확인 MySQL 서버 정상 작동 및 연결 여부 확인 [ ]
GCS Bucket에 Presigned URL로 이미지 업로드 테스트 완료 [ ]
AI 서버(CPU/GPU 인스턴스)와 통신 가능 여부 확인 [ ]
4. 배포 준비 상태 확인 기존 JAR 파일 및 프론트 정적 파일 백업 경로 및 복사 완료 [ ]
Nginx 설정 포트 및 프록시 경로가 현재 인스턴스에 맞게 작성되어 있는지 확인 [ ]
deploy.sh 파일 내 경로(backend, frontend, jar 등) 정확성 확인

Big Bang 배포의 한계점 & 개선점

  1. 단일 인스턴스 의존: 한 인스턴스에 컴포넌트가 밀집되어있어서 장애발생시 전체 서비스 중단
    → 계층 분리: 프론트엔드, 백엔드, DB, AI를 별도 인스턴스로 분리하여 장애 전파 최소화

  2. 수작업 오류 위험: 잘못된 파일 복사, 포트 충돌 등
    → CI/CD자동화: GitHub Actions를 통한 자동화로 수동 실수 방지 및 일관된 배포 보장

  3. 롤백 어려움: 배포 실패 시 빠르게 되돌릴 수 있는 구조가 없음
    무중단 배포 도입: Blue-Green 방식으로 새로운 버전 배포 후 정상 확인 시 트래픽 전환 → 문제 시 즉시 롤백 가능

  4. 확장성 부족: 멀티 인스턴스 운영 시 복잡도 상승
    → 컨테이너 기반 구조 또는 멀티 인스턴스로 확장 용이하게 설계

  5. 다운타임: 약 2~3분
    → 무중단 배포 도입: 서비스 중단 없이 신규 버전 전환 가능 (Nginx 라우팅)

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