☁️ 1단계 : Big Bang 방식 수작업 배포 - 100-hours-a-week/7-team-ddb-wiki GitHub Wiki

1. 개요 (Overview)

신규 서비스를 위해 인프라를 처음부터 구축해야 하는 상황이다.

개발 기간이 2주로 매우 짧고, MVP 단계에서는 사용자 수가 많지 않을 것으로 예상됨에 따라, 빠르게 시장에 진입하고 검증을 받기 위한 전략으로 Big Bang 배포 방식을 채택하였다.

이 방식은 GCP 기반의 단순한 인프라 환경에 Spring, FastAPI, Next.js로 구성된 서비스를 수작업으로 일괄 배포하는 구조이다.

2. 도입 배경 및 필요성

2.1 FTP vs Git + GitHub

버전 관리

  • Git은 파일의 변경 이력 전체를 추적한다. 언제, 누가, 무엇을 수정했는지 기록되며, 과거 버전으로 손쉽게 되돌릴 수 있다.
  • 반면 FTP는 단순한 "파일 업로드/다운로드 도구"일 뿐이다. 실수로 잘못된 파일을 덮어쓰면 되돌릴 방법이 없다.
  • 협업 중 충돌이 발생하더라도 Git은 병합 도구(merge, rebase 등)를 통해 이를 해결할 수 있다.

협업

  • GitHub에서는 branch, pull request, review, approve 등의 기능을 통해 팀원 간에 검토 절차를 거친 뒤에만 코드 반영이 가능하여 팀이 서로의 코드를 검토하고 품질을 높이는 문화를 가능하게 한다.
  • FTP는 누가 언제, 무엇을 수정했는지 알 수 없으며, 작업이 덮어쓰기되거나 충돌 날 위험이 크다.
  • FTP는 개인이 자기 책임 하에 코드를 수정하는 구조이기 때문에, 검토 없이 실수로 코드가 반영될 가능성이 크다.
  • 실무에서 여러 명이 동시에 같은 파일을 작업할 때, Git은 충돌을 방지하고 이력을 남기지만, FTP는 그런 장치가 전혀 없다.

백업과 복원

  • Git은 로컬 저장소뿐 아니라 GitHub 같은 원격 저장소에도 저장되므로, 로컬 PC가 손상되더라도 코드 유실이 없다.
  • 반면 FTP 방식은 파일을 하나의 서버에 업로드하는 형태이므로, 실수로 삭제하거나 서버에 문제가 생기면 복구가 어렵다.

자동화 및 CI/CD 파이프라인 연동

  • GitHub는 Jenkins, GitHub Actions, GitLab CI 같은 CI/CD 도구들과 쉽게 연동된다. push만 해도 테스트, 배포가 자동으로 수행될 수 있다.
  • FTP는 자동화가 거의 불가능하며, 수동으로 배포, 테스트, 수정해야 한다. 반복 작업에 시간을 낭비하게 된다.

2.2 GCP

Dolpin 프로젝트는 이번 MVP 개발에서는 GCP(Google Cloud Platform)를 선택하였다. 가장 큰 이유는 GCP 프로모션 크레딧 제공 정책이 개발 속도와 비용 측면에서 명확한 이점을 주었기 때문이다.

GCP 신규 사용자 크레딧 활용

  • GCP는 신규 가입자에게 별도 심사나 조건 없이 300달러의 크레딧을 즉시 제공하며, 이 금액은 Compute Engine, Cloud SQL, Storage, Application Load Balancer 등 GCP의 거의 모든 주요 리소스에서 자유롭게 사용 가능하다.
  • Dolpin은 Spring(BE), FastAPI(AI), Next.js(FE)로 구성된 3개의 VM 인스턴스, Cloud SQL, ALB 등을 운영 중이며, 이 모든 리소스를 300달러 크레딧으로 감당한다.
  • 크레딧 유효 기간은 90일로, 짧은 MVP 개발 일정에는 전혀 부담 없는 충분한 기간이다.

GCP 비용 계산 환경별 총 비용

환경 월 예상 비용 (USD)
dev (하루 평균 11시간 운영) 94
prod (하루 평균 7시간 운영) 61.44
공통 / 공유 30.74
총합 186.18

서비스별 상세 비용

환경 서비스 GCP 제품 월 예상 비용 (USD)
- dns Cloud DNS 0.6
- alb Networking (L7 LB) 30.14
dev Instances (3) Compute Engine (n1-standard-1) 63.77
dev Instance Compute Engine (g1-small) 12.07
dev database PostgreSQL (db-f1-micro) 14.02
dev bucket Cloud Storage 2.30
dev cdn Cloud CDN 1.84
prod Instances (3) Compute Engine (n1-standard-1) 40.22
prod Instance Compute Engine (g1-small) 8.16
prod database PostgreSQL (db-f1-micro) 8.92
prod bucket Cloud Storage 2.30
prod cdn Cloud CDN 1.84

GCP Cloud Pricing Calculator 보기 (dev + 공통)

GCP Cloud Pricing Calculator 보기 (prod)

2.3 Big Bang 배포

항목 설명
빠른 시장 진입 2주라는 촉박한 일정 내 서비스를 빠르게 테스트하고 사용자 반응을 확인하기 위해 간단한 수작업 배포 방식 선택
낮은 초기 트래픽 커뮤니티 및 추천 기능은 초기 사용자 확보 후 점진적으로 확장되므로, 다운타임 이슈가 서비스 품질에 미치는 영향이 크지 않음
단순한 인프라 구조 GCP 기반 Compute Engine 3대 + Cloud SQL + ALB 등 최소 구성으로, 별도의 자동화 없이도 직접 관리가 가능함
자원 최적화(시간·비용) CI/CD 시스템 구축보다 핵심 기능 개발에 리소스를 집중하는 것이 더 중요한 단계

하지만 빅뱅 배포는 다운타임, 인적 오류, 담당자 의존도 등의 한계를 가지며, 사용자 수 증가 및 서비스 확장에 따라 자동화된 배포 체계(CI/CD)로의 전환이 필연적이다.

3. 목표 & 적용 범위

  • 목표

    • 최소 구성의 클라우드 인프라를 신속히 구축하고, 서비스 전체를 빅뱅 방식으로 일괄 배포
    • 다운타임 15분 이내로 관리, 기능별 인스턴스 분리를 통해 향후 확장성 대비
  • 적용 범위

    • 운영 환경: 실제 사용자 대상 배포 (초기 트래픽이 낮은 상황)
    • 인스턴스 구성: Bastion+NAT(통합), Application 서버, Cloud SQL, Load Balancer, Cloud Storage, Cloud DNS

4. 설계 상세

4.1 아키텍처 다이어그램

목표 아키텍처

image

배포 다이어그램

image 1

  • 구성 요소

    구성 요소 설명
    Instance 실제 서비스가 동작하는 서버. 보안을 위해 private subnet에 배치하고, 기능별로 분리(예: 웹/백엔드)하여 추후 스케일 확장이 쉽도록 설계.
    Bastion + NAT • Public subnet에 위치한 Bastion Host를 통해 개발자 SSH 접근을 제어.
    • NAT 기능도 동시에 수행하여 private subnet 인스턴스들의 외부 통신을 지원.
    • 두 역할을 하나의 인스턴스로 통합해 비용 효율 극대화.
    Cloud SQL 클라우드 관리형 DB 서비스. 자동 백업, 장애 복구 지원 등 운영 편의성이 높아, 빠른 개발과 안정적 운영에 적합.
    Load Balancer 트래픽 분산 및 고가용성 제공. 서버마다 개별 리버스 프록시를 구성하는 대신, 클라우드의 관리형 로드밸런서를 활용해 유지보수 부담을 줄임.
    Cloud Storage 정적 파일(이미지 등)을 저장하는 클라우드 스토리지. 사용량에 따라 자동 확장 가능하며, 높은 내구성과 가용성을 제공.
    Cloud DNS 도메인 기반 접근 지원.
  • 사용 이유

    • GCP Load Balancer vs Nginx
      • 무중단 배포 및 헬스 체크 기반 트래픽 제어

        GCP Load Balancer는 각 백엔드 인스턴스의 상태를 주기적으로 헬스 체크하고, 비정상 인스턴스는 트래픽 대상에서 자동 제외한다. 이로 인해 수작업 배포 중 일부 인스턴스가 재시작되더라도 서비스 전체 중단 없이 순차적 배포가 가능하다. 반면 Nginx는 별도 헬스 체크 설정과 동적 구성 리로드가 필요하고, 실시간 반영이 어렵다.

      • HTTPS 및 인증서 관리 간소화 GCP Load Balancer는 무료 SSL 인증서를 자동으로 발급 및 갱신하며, HTTPS 트래픽을 종단에서 종료할 수 있다. Nginx는 Let's Encrypt 등을 직접 설정해야 하고, 만료 시 갱신 실패로 전체 서비스 장애가 발생할 가능성이 있다.

      • Cloud DNS와의 통합 운영 GCP Load Balancer는 GCP Cloud DNS와 자연스럽게 연동되어, 도메인 → 외부 IP → 인스턴스 연결을 간결하게 구성할 수 있다. Nginx는 별도로 외부 IP 및 DNS 라우팅 구성을 해야 하며, 고정 IP 구성에도 주의가 필요하다.

      • 비용 효율성

        비교 항목 GCP Load Balancer Nginx (Compute Engine 상 설치)
        초기 구성 비용 없음 (사용 기반 과금) 낮음 (VM 1대에 설치 가능)
        운영/유지보수 없음 (GCP가 관리) 있음 (보안 패치, SSL 관리 직접 필요)
        가용성 보장 고가용성 내장 (멀티 리전/존 대응) 단일 장애점 → 별도 이중화 필요
        헬스 체크/확장성 기본 제공 수동 구성 필요
      • 결론 : GCP Load Balancer 사용

    • GCP Cloud Storage vs Persistent Disk
      • VM 간 공유 저장소 역할

        AI 서버는 장소의 이미지를 크롤링하여 저장하며, 해당 이미지는 프론트엔드에서 사용자에게 보여주기 위해 사용된다. Persistent Disk는 단일 VM에만 마운트되기 때문에, 크롤링한 이미지 파일을 프론트엔드 서버에서 사용하려면 공유 디스크 구성, 파일 복사, 별도의 API 게이트웨이 개발 등 번거롭고 복잡한 작업이 필요하다. GCS는 이미지를 업로드한 후 URL 하나만 공유하면 다른 서버에서도 즉시 접근 가능하기 때문에, 서버 간 통신 없이 간단하고 효율적으로 파일을 공유할 수 있다.

      • 정적 파일 저장소로의 활용 장소 이미지는 실시간으로 자주 변경되지 않기 때문에, 정적 파일 저장소인 GCS와 잘 맞는다. 필요할 경우 Cloud CDN과 연동하여 이미지 로딩 속도를 개선할 수도 있어, 사용자 경험 측면에서도 유리하다.

      • 서비스 로그 / 백업 파일 저장 용도 PD는 로그가 지속적으로 누적되면 디스크 용량 초과로 인한 서비스 장애 가능성이 존재하며, 운영자가 수동으로 파일을 정리하거나 디스크 용량을 확장해야 한다. GCS는 백업, 로그 파일을 저렴한 비용으로 무제한 저장할 수 있으며, Lifecycle Rule 설정을 통해 자동 삭제/이동도 가능하다.

      • 보안 및 접근 제어 PD는 VM 내 파일 권한 설정에 의존하므로, 세밀한 외부 접근 제어나 감사 로깅에는 한계가 있다. GCS는 IAM 기반의 접근 제어를 통해 버킷, 폴더, 객체 단위까지 권한을 세밀하게 설정할 수 있다.

      • 결론 : GCP Cloud Storage 사용

4.2 배포 상세

Git Branch 전략
git-branch

배포 결정 및 스케줄 확인

  • 담당자(배포 책임자)가 당일 배포 일정을 확정 후 팀원에게 공지
  • 서비스 트래픽이 적은 시간대를 택해 다운타임 최소화

배포 플로우

단계 절차 내용 담당자 사용 도구 / 명령어 예상 소요 시간 다운타임 여부 비고
0 기능 개발 및 GitHub Push 개발자 git push - 사전 기능 개발 및 테스트 완료 전제
1 인스턴스 접속 및 상태 확인 배포 책임자 gcloud compute ssh, top, lsof -i:<port> 1~2분 사전 점검 단계
2 실행 중인 앱 종료 배포 책임자 kill -9, lsof -ti:<port> 1분 다운타임 시작
3 기존 배포 백업 배포 책임자 cp -r /service/{fe/be}/{version} /backup/ 2분 롤백용
4 코드 Pull 및 의존성 설치 개발자, 배포 책임자 git pull, npm install, ./gradlew build, pip install 3~5분 최초 1회 또는 변경 시
5 애플리케이션 실행 개발자, 배포 책임자 nohup 명령어 사용 2~3분 로그 및 포트 확인 필수
6 상태 점검 및 기능 확인 배포 책임자 curl, 브라우저, Cloud Monitoring 2분 오류 시 롤백 여부 판단
7 최종 완료 보고 배포 책임자 채널 공유, 모니터링 대시보드 1분 장애 발생 시 대응

수동 체크리스트

단계 작업 항목 세부 내용 완료 여부
준비 배포 일정 및 담당자 확인 당일 배포 시간 및 담당자 지정, 팀원에게 사전 공지 - [ ]
준비 최종 테스트 & 빌드 완료 여부 GitHub PR 병합 완료 / 로컬 또는 dev 환경에서 테스트 성공 - [ ]
준비 Cloud SQL 백업 수행 콘솔 또는 gcloud sql backups create 명령어 사용 - [ ]
준비 서버 백업 & 롤백 포인트 확보 기존 코드 디렉토리 또는 실행 파일 백업(/backup/) - [ ]
종료 기존 애플리케이션 종료 lsof -ti:<port>kill -9 방식으로 종료 (전체 인스턴스) - [ ]
배포 파일 전송 및 버전 확인 Git pull → 변경 내용 반영 여부 및 commit hash 확인 - [ ]
배포 서비스 재시작 Frontend, Backend 서비스에 대해 빌드, 실행 프로세스 재시작 수행 - [ ]
확인 서비스 재시작 후 간단 기능 검증 각 포트 또는 도메인에서 /, /health, /docs 등 호출 - [ ]
점검 로그 확인 tail -f *.log 로 에러 및 실행 상태 실시간 확인 - [ ]
마무리 배포 완료 공지 & 모니터링 시작 Discord/내부 채널 공지 + Cloud Monitoring 확인 - [ ]
마무리 배포 기록 문서화 배포 일시, 담당자, 로그 내용 등을 Wiki나 Google Docs에 기록 - [ ]

Downtime 전략

실시간 공지 페이지로 라우팅

  • 배포 시작과 동시에 모든 트래픽을 공지 페이지로 전환

    Ingress 또는 ALB, Nginx 등의 라우팅 설정을 통해 사용자가 기존 서비스에 접근할 경우, 자동으로 점검 안내 페이지로 이동되도록 설정한다.

  • 라우팅 예시

    • / 요청 시 → 정적 HTML 공지 페이지로 리다이렉트
    • 배포 완료 시 다시 /로 복구

공지 페이지 구성 요소

[서비스 점검 안내]

현재 서비스 안정화를 위한 배포가 진행 중입니다.
🙏 불편을 드려 죄송합니다. 더 나은 서비스를 제공하기 위한 작업입니다.
➡ 점검 완료 후 자동으로 서비스가 복구됩니다.

4.3 설정 · 스크립트 명세

BE

#!/bin/bash

ZONE="asia-northeast3-a"
INSTANCE="spring-instance"
APP_DIR="/home/ubuntu/app"
REPO_URL="https://github.com/100-hours-a-week/7-team-ddb-be.git"
PORT=8080

echo "[Spring] $INSTANCE 배포 시작..."

gcloud compute ssh "$INSTANCE" --zone "$ZONE" --command "
  set -e
  
  # [1] Java 및 Gradle 설치 
  sudo apt update -y && sudo apt upgrade -y
  sudo apt install -y git openjdk-17-jdk gradle
 
  # [2] 앱 디렉토리 생성 및 Git 저장소에서 코드 다운로드
  mkdir -p $APP_DIR
  cd $APP_DIR
  if [ ! -d .git ]; then
    git clone $REPO_URL .   # 최초 클론
  else
    git pull origin main    # 변경 사항 반영
  fi
  
  # [3] 포트 사용 중인 기존 프로세스 종료
  PID=\$(lsof -ti:$PORT)
  if [ -n \"\$PID\" ]; then
    kill -9 \$PID
  fi
  
  # [4] 애플리케이션 빌드 및 백그라운드 실행
  echo '[4] 빌드 및 실행'
  ./gradlew build -x test
  nohup java -jar build/libs/*.jar > app.log 2>&1 &
"

AI

#!/bin/bash

ZONE="asia-northeast3-a"
INSTANCE="fastapi-instance"
APP_DIR="/home/ubuntu/app"
REPO_URL="https://github.com/100-hours-a-week/7-team-ddb-ai.git"
PORT=8000

echo "[FastAPI] $INSTANCE 배포 시작..."

gcloud compute ssh "$INSTANCE" --zone "$ZONE" --command "
  set -e

  # [1] Python3 및 pip 설치 
  sudo apt update -y && sudo apt upgrade -y
  sudo apt install -y git python3 python3-pip
  pip3 install --upgrade pip
  pip3 install fastapi uvicorn

  # [2] 앱 디렉토리 생성 및 Git 저장소에서 코드 다운로드
  mkdir -p $APP_DIR
  cd $APP_DIR
  if [ ! -d .git ]; then
    git clone $REPO_URL .   # 최초 클론
  else
    git pull origin main    # 변경 사항 반영
  fi
  
  # [3] 포트 사용 중인 기존 프로세스 종료
  PID=\$(lsof -ti:$PORT)
  if [ -n \"\$PID\" ]; then
    kill -9 \$PID
  fi

  # [4] 의존성 설치 및 애플리케이션 실행
  echo '[4] 실행'
  pip3 install -r requirements.txt
  nohup uvicorn main:app --host 0.0.0.0 --port $PORT > uvicorn.log 2>&1 &
"

FE

#!/bin/bash

ZONE="asia-northeast3-a"
INSTANCE="fe-instance"
APP_DIR="/home/ubuntu/app"
REPO_URL="https://github.com/100-hours-a-week/7-team-ddb-fe.git"
PORT=3000

echo "[Frontend] $INSTANCE 배포 시작..."

gcloud compute ssh "$INSTANCE" --zone "$ZONE" --command "
  set -e
  
  # [1] Node.js 설치 및 serve 글로벌 설치
  sudo apt update -y && sudo apt upgrade -y
  sudo apt install -y git curl
  curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
  sudo apt install -y nodejs
  npm install -g npm serve
  
  # [2] 앱 디렉토리 생성 및 Git 저장소에서 코드 다운로드
  mkdir -p $APP_DIR
  cd $APP_DIR
  if [ ! -d .git ]; then
    git clone $REPO_URL .   # 최초 클론
  else
    git pull origin main    # 변경 사항 반영
  fi
  
  # [3] 포트 사용 중인 기존 프로세스 종료
  PID=\$(lsof -ti:$PORT)
  if [ -n \"\$PID\" ]; then
    kill -9 \$PID
  fi
  
  # [4] 앱 의존성 설치 및 빌드, 백그라운드 실행
  npm install
  npm run build
  nohup npm run start > next.log 2>&1 &
"

롤백

  • 장애 발생 시 /service/backup/{previous_version} 폴더로 교체
  • 기존 프로세스 재시작 후 새 버전 프로세스 종료

5. 한계 및 방식 비교

5.1 빅뱅 배포 방식의 한계

항목 핵심 내용
반복 작업 부담 VM 수만큼 동일한 빌드, 설치, 실행을 반복해야 하며 병렬 수행 없이는 배포 시간이 오래 걸림
인적 오류 및 복구 지연 수작업 입력에 따른 오타, 순서 누락 등의 실수가 발생할 수 있으며, 복구까지 시간이 소요됨
무중단 배포 불가 전체 서비스를 일괄 중단 후 배포하기 때문에, 다운타임이 발생할 수 있음
환경 불일치 위험 의존성 설치, 환경변수 등이 사람마다 달라져 서버 간 상태가 불균형해질 수 있음
확장성 부족 트래픽 증가나 배포 빈도 상승 시, 매번 수작업으로 대응하면 오히려 장애 위험·업무 부담이 커짐
담당자 의존도 높음 특정 담당자에게 절차 숙련도가 집중되어 인수인계, 대체 인력 투입이 어렵고 리스크가 큼

5.2 빅뱅 배포 vs 자동화 배포

항목 수작업 배포 (Big Bang) 자동화 배포 (CI/CD 기반)
배포 방식 SSH 접속 → 명령어 수동 실행 Git Push → 자동 파이프라인 실행
사용 도구 SSH, Git, 터미널 명령어 Jenkins, GitHub Actions, ArgoCD 등
속도 느림 (반복 작업 필요) 빠름 (병렬 및 조건 처리 가능)
정확성 낮음 (사람이 작업 → 오타, 누락 가능) 높음 (정형화된 흐름)
가용성 낮음 (순차 재시작 중 다운타임 발생) 높음 (Blue-Green, Rolling 등 가능)
확장성 낮음 (VM 늘수록 배포도 수작업 증가) 높음 (서버 수 상관없이 동일 방식 반복)
협업 효율성 낮음 (작업 이력 및 배포 상태 공유 어려움) 높음 (버전 관리 및 상태 가시화)
문제 대응 속도 느림 (장애 원인 수동 추적) 빠름 (로그 자동 수집, 상태 추적)
롤백 수동 재배포 (느리고 실수 여지 많음) 명확한 커밋 기반 자동 롤백 가능
운영 위험도 높음 낮음
학습 곡선 낮음 (기초 명령어 수준) 중간~높음 (CI/CD 도구 이해 필요)
초기 구축 비용 낮음 (즉시 배포 가능) 중간 (CI/CD 파이프라인 구성 필요)

6. 기대 효과 & 적용 후 평가

6.1 기대 효과

  • 빠른 개발→배포→시장 검증: 2주 내 MVP를 완성하고 빠르게 배포함으로써 사용자 피드백을 빠르게 수집할 수 있다.
  • 단순한 운영·유지보수: 복잡한 툴 없이도 구성 요소가 명확하여, 초기 운영 부담이 낮다.
  • 장애 대응 용이: 인프라 규모가 작기 때문에, 장애 발생 시 직접 접속하여 빠르게 수작업으로 조치 가능하다

6.2 회고 항목

항목 확인할 점
다운타임 발생 여부 배포 과정 중 예상보다 긴 서비스 중단 시간이 발생하지는 않았는가?
Git pull 시 충돌 누락된 커밋, 병합 충돌, 수정되지 않은 파일 등이 문제되지 않았는가?
사용자 불편/피드백 배포 직후 사용자 측에서 에러 보고나 접속 문제 등이 있었는가?

7. 결론 및 향후 계획

  • 결론

    • 본 단계에서는 빅뱅 방식의 수작업 배포를 통해, 짧은 기간 안에 서비스를 전체적으로 가동시키는 데 집중했다.

    • 서비스가 본격 성장하기 전까지는 문제없이 운영 가능하지만, 확장성(Scalability)과 다운타임 측면에서 한계가 명확하다.

  • 향후 계획

    • 2단계에서 CI(지속적 통합) 파이프라인을 도입하여, 코드 통합 및 빌드·테스트 자동화를 구축할 예정이다.
    • 점차 배포 자동화, 무중단 배포 전략(Blue-Green / Rolling Update 등)도 모색할 것이며, 이로써 안정적인 서비스를 제공하고 배포 리스크를 줄이고자 한다.
⚠️ **GitHub.com Fallback** ⚠️