[CL]3단계_CD(지속적_배포)_설계_문서 - 100-hours-a-week/12-marong-Wiki GitHub Wiki
📚 목차
0. CD 파이프라인 흐름도
1. 도구 선택 및 도입 배경
선택 Tools
- CD 도구: GitHub Actions
- 배포 방식: SFTP 기반 원격 스크립트 실행
- 운영 서버: GCP Compute Engine (Docker 미사용)
- 알림 도구: Discord Webhook API
CD 도입 배경 및 필요성
빅뱅 배포 이후 버전을 업데이트하며 기능을 추가하다보니 개발 후 배포 환경에서 테스트 하는 횟수가 많아졌고, 기존의 수동 배포 프로세스에서는 코드 변경 후 배포 승인 및 수동 반영까지 상당한 시간과 노력이 소요되었습니다. 이는 다음과 같은 문제를 야기했습니다.
- 기능 출시 지연
- 배포 시 발생하는 실수와 장애 가능성 증가
이에 따라 CD 체계 도입을 통해 다음과 같은 효과를 기대할 수 있습니다:
- 배포 속도 향상: 기능이 커밋된 이후 운영 반영까지의 시간을 단축
- 배포 안정성 향상: 자동화된 테스트 및 검증을 통해 실수를 최소화
- 고객 피드백 수렴 속도 향상: 반복적인 변경 사항을 더 빠르게 반영 가능
2. CD 설계 설명서
개요
본 문서는 마니또 기반 SNS 서비스의 지속적 배포(CD: Continuous Deployment) 체계를 설계하기 위한 설명서입니다. CD의 도입 목적, 적용 범위, 배포 전략, 롤백 방식, 그리고 전체 프로세스의 변화 내용을 포함하여 기술하며, Github Actions를 기반으로 하는 배포 자동화의 구체적인 설계 방향을 담고 있습니다.
CD 파이프라인 구성
배포 흐름 요약
release/*
브랜치 또는 특정 Tag가 푸시되면 Github Actions가 트리거됨- Lint / Test 단계 이후 배포 스크립트 실행
- SFTP를 통해 서버에 파일을 업로드 → 신규 버전 Pull → 프로세스 재시작 (PM2 등 사용)
- 성공 여부 및 에러 로그를 Discord Webhook으로 전송
배포 전략
전략 선택: Rolling Update + 자동화된 CD
마롱(Marong)
은 실시간 사용자 피드와 마니또 미션을 포함한 SNS 기반 플랫폼입니다.
초기에는 EC2 단일 서버에 SFTP 수동 업로드 방식으로 배포하는 BigBang 배포를 사용했지만, 다음과 같은 문제가 있었습니다:
- 전체 서비스가 동시에 중단되어 사용자 경험 저하
- 배포 직후 발견된 버그 → 전체 롤백 필요
- 배포 실패 시 전체 서비스 다운
이를 해결하기 위해 Rolling Update 방식의 배포 전략을 채택하여 다음과 같은 이점을 확보했습니다:
문제점 | 해결 방안 |
---|---|
전체 중단 위험 | 순차적 배포(Rolling), 가용 인스턴스 유지 |
배포 실패 시 복구 어려움 | 트래픽 분리, 모니터링 후 롤백 가능 |
점진적 배포 불가 | 테스트 트래픽 기반 검증 도입 |
배포 프로세스 변화
항목 | 기존 방식 | CD 도입 후 변화 |
---|---|---|
배포 주기 | 주 1~2회 수동 배포 | 하루 수 회 자동화 가능 |
배포 대상 지정 | 직접 서버 명령어 입력 | 자동으로 환경 구분 및 경로 적용 |
롤백 | 수동 복원 / 명령어 입력 필요 | 자동 헬스체크 기반 롤백 |
커뮤니케이션 | 배포 후 수동 보고 | Discord Webhook 자동 전송 |
기대 효과
항목 | 기대 효과 |
---|---|
릴리즈 속도 | 기능 릴리즈 시간 단축 (배포 시간 수분 이내) |
장애 대응력 | 롤백 자동화로 장애 확산 최소화 |
운영 안정성 | 배포 → 검증 → 전파의 일관된 흐름 확보 |
협업 효율성 | 배포 책임의 공유 → 커밋 기반 추적 가능 |
사용자 피드백 수렴 속도 | 개발 후 배포 시간 단축으로 피드백 수렴 빠르게 가능 |
향후 확장 계획
- GitHub Actions의 한계를 느낄 경우, Argo CD 또는 Jenkins + Spinnaker 등으로 이관 검토
- EKS 기반 Version 3 환경에서는 Helm + Argo CD 기반의 GitOps로 전환 계획
- 테스트 자동화 커버리지 확보 후, 전체 파이프라인의 안정성 향상 목표
3. 설정 및 스크립트 명세 (Spring 서버 기반)
이 문서는 마니또 기반 SNS 서비스의 지속적 배포(CD) 를 구현하기 위해 사용된 GitHub Actions 설정 및 배포 스크립트의 주요 구조와 역할, 검증/모니터링 방식, 롤백 조건과 방법 등을 설명합니다.
GitHub Actions 설정
.github/workflows/cd.yml
📄 name: CD Pipeline
on:
push:
branches:
- dev
workflow_dispatch:
inputs:
environment:
description: '배포할 브랜치 선택'
required: true
default: 'prod'
jobs:
deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/dev' || github.event.inputs.environment == 'prod'
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Upload to FTP Server
uses: SamKirkland/[email protected]
with:
server: ${{ secrets.FTP_SERVER }}
username: ${{ secrets.FTP_USERNAME }}
password: ${{ secrets.FTP_PASSWORD }}
local-dir: "./"
server-dir: "/myapp/"
dangerous-clean-slate: false
- name: Notify Discord
if: always()
run: |
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"✅ FTP를 통한 배포 파일 업로드가 완료되었습니다. 서버에서 자동 또는 수동으로 deploy.sh를 실행하십시오.\"}" \
${{ secrets.DISCORD_WEBHOOK_URL }}
서버 배포 디렉토리 구조
/home/deploy/myapp/
├── src/
├── build/libs/
├── gradlew
├── healthcheck.sh
├── rollback.sh
└── ...
원격 서버 스크립트
🩺 healthcheck.sh
#!/bin/bash
URL="http://localhost:8080/health"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $URL)
if [ "$STATUS" != "200" ]; then
echo "Healthcheck failed with status $STATUS"
exit 1
else
echo "Healthcheck passed"
exit 0
fi
- 목적: 애플리케이션 정상 구동 여부 확인
- 실패 시: exit 1 반환 → GitHub Actions가 롤백 실행
🔁 rollback.sh
#!/bin/bash
cd /home/deploy/myapp/
git reset --hard HEAD~1
./gradlew build
pkill -f 'java -jar'
nohup java -jar build/libs/*.jar > app.log 2>&1 &
curl -H "Content-Type: application/json" \
-X POST \
-d "{\"content\": \"❌ 롤백 수행 완료. 이전 커밋으로 되돌렸습니다.\"}" \
$DISCORD_WEBHOOK_URL
- 목적: 마지막 커밋 이전 상태로 복원 및 서버 재실행
- 알림: Discord Webhook으로 롤백 감지 시 실시간 전송
4. 보안 설정 및 제한사항
GitHub Secrets (보안 설정)
이름 | 설명 |
---|---|
PROD_HOST | 운영 서버의 IP 주소 |
FTP_USERNAME | FTP 접속 유저명 (deploy 등) |
FTP_SERVER | FTP 서버 url |
FTP_PASSWORD | FTP 서버 password |
DISCORD_WEBHOOK_URL | Discord 알림용 Webhook 주소 |
보안 및 제한사항
- Docker 미사용: EC2에서 직접 Java JAR 실행
- VPN 기반 Shared 환경에서만 접근 가능 (Dev 제외)
- 시크릿은 GitHub Secrets에서 안전하게 관리
- 로그는 app.log로 출력 → 추후 Loki로 확장 예정
📌 향후 계획
- 프로세스 헬스 체크 강화 (응답 외 메모리/CPU 임계값 조건 추가)
- 배포 전 스냅샷 자동 백업 및 롤백 버전 별도 보관