← 메인으로 돌아가기

🚀 GiftCall Azure DevOps 배포

로컬에서 STG 환경까지 - Git 멀티 Remote와 CI/CD 파이프라인

✅ 배포 성공
• 일시: 2026년 1월 21일
• 소요 시간: 약 1시간 16분
• 업로드: 295개 파일, 62,847줄
• STG URL: https://stg-copilotmcp.emart.com/giftcall-ai

📚 목차

🔍 배포 전 준비 (2026년 1월 21일 오전)

고민: 이 코드를 회사 서버에 올려도 될까?

배포 전 불안감

로컬에서는 잘 작동하는 코드지만, 회사 서버에 배포하려니 여러 걱정이 들었습니다:

1. 리팩토링 분석

먼저 코드 상태를 점검했습니다:

⚠️ 발견된 문제들
  • 모델 파일 3중 중복: gift_models.py, models.py, database.py
  • 카카오톡 서비스 3중 중복: messaging.py, kakaotalk_service.py, kakaotalk.py
  • GiftCall.vue 5,318줄: 권장 1,000줄의 5배 초과

하지만 배포를 미룰 수는 없었습니다. "일단 작동하는 코드를 배포하고, 리팩토링은 나중에 하자"고 결정했습니다.

2. Import 의존성 분석

실제로 사용하는 파일과 사용하지 않는 파일을 구분했습니다:

파일 상태 조치
kakaotalk_service.py 완전 미사용 삭제 가능 (나중에)
database.py 레거시 테이블 존재 데이터 마이그레이션 필요
gift_models.py 현재 사용 중 유지

3. 보안 분석

가장 중요한 부분이었습니다. 민감 정보가 포함되어 있는지 꼼꼼히 확인했습니다:

✅ 보안 검토 결과
  • 암호화 키 파일: .gitignore로 보호 확인
  • 환경 설정: 개발용 더미 값만 포함
  • boto3: 이미 설치됨 (AWS KMS 준비 완료)
  • 데이터베이스 비밀번호: 환경 변수로 분리

4. 환경 분리 분석

로컬과 서버 환경이 제대로 분리되어 있는지 확인했습니다:

# 로컬 개발 환경 (.env.dev)
DATABASE_URL=postgresql://giftcall_dev:dev_password_123@localhost:5433/giftcall_dev
REDIS_HOST=localhost
REDIS_PORT=6380

# 운영 환경 (환경 변수)
DATABASE_URL=postgresql://giftcall_prod:STRONG_PASSWORD@postgres:5432/giftcall_prod
REDIS_HOST=redis
REDIS_PORT=6379

환경 변수로 잘 분리되어 있어서 안심했습니다.

📦 Git 멀티 Remote 이해하기

개념: 하나의 코드를 두 곳에 보관하기

왜 두 개의 저장소가 필요한가?

처음에는 이해가 안 됐습니다. GitHub에 이미 코드가 있는데 왜 Azure DevOps에도 올려야 하나?

📋 비유로 이해하기
  • GitHub = 개인 클라우드 (Google Drive)
  • Azure DevOps = 회사 클라우드 (회사 SharePoint)
  • 같은 문서를 두 곳에 보관하는 것과 같음

각 저장소의 역할

항목 GitHub Azure DevOps
용도 개발/백업 운영/배포
푸시 빈도 자주 (개발 중) 배포 시만
자동 배포 ✅ CI/CD
보안 개인 회사 정책
접근 본인만 팀 전체

Git 구조 이해

giftcall 프로젝트는 특이하게 두 개의 Git 저장소에 속합니다:

/Users/emart/Documents/PromptLibrary/
├── .git/                    ← GitHub (전체 프로젝트)
│   └── remote: origin → https://github.com/eunbongc/PromptLibrary
├── giftcall/
│   └── .git/               ← Azure DevOps (giftcall만)
│       └── remote: azure → https://dev.azure.com/.../emart-giftcall-ai

이렇게 하면 PromptLibrary 전체는 GitHub에, giftcall만 Azure DevOps에 올릴 수 있습니다.

⚙️ Azure DevOps 설정

작업 시간: 2026년 1월 21일 13:30 ~ 14:46 (1시간 16분)

1. giftcall을 독립 Git 저장소로 분리

먼저 giftcall 폴더를 독립적인 Git 저장소로 만들어야 했습니다:

cd /Users/emart/Documents/PromptLibrary/giftcall
git init
git add .
git commit -m "Initial commit: GiftCall project"

이제 giftcall 폴더는 자체 Git 저장소가 되었습니다.

2. Personal Access Token (PAT) 생성

Azure DevOps에 접근하려면 인증이 필요합니다. PAT를 생성했습니다:

  1. Azure DevOps → User Settings → Personal Access Tokens
  2. New Token 클릭
  3. 권한: Code (Read & Write) 선택
  4. 만료 기간: 90일 설정
  5. 생성된 토큰 복사 (다시 볼 수 없으니 주의!)

3. Azure DevOps Remote 추가

PAT를 사용해서 Azure DevOps 저장소를 연결했습니다:

git remote add azure https://[PAT]@dev.azure.com/emartdevops/emart-dvcs-mcp/_git/emart-giftcall-ai

# 확인
git remote -v
# origin  https://github.com/eunbongc/PromptLibrary (fetch)
# origin  https://github.com/eunbongc/PromptLibrary (push)
# azure   https://dev.azure.com/emartdevops/... (fetch)
# azure   https://dev.azure.com/emartdevops/... (push)

4. 첫 푸시 시도 - 실패!

드디어 푸시를 시도했습니다:

git push azure main
❌ 에러 발생
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413
fatal: the remote end hung up unexpectedly

5. 문제 해결: Git 버퍼 크기 증가

에러 메시지를 검색해보니 파일 크기가 너무 커서 발생하는 문제였습니다. Git 버퍼 크기를 늘려야 했습니다:

# 버퍼 크기를 500MB로 증가
git config http.postBuffer 524288000

# 다시 푸시
git push azure main

6. 푸시 성공! ✅

✅ 배포 성공
Enumerating objects: 295, done.
Counting objects: 100% (295/295), done.
Delta compression using up to 8 threads
Compressing objects: 100% (287/287), done.
Writing objects: 100% (295/295), 62847 lines, done.
Total 295 (delta 156), reused 0 (delta 0)
remote: Analyzing objects... (295/295) (100%)
To https://dev.azure.com/emartdevops/emart-dvcs-mcp/_git/emart-giftcall-ai
 * [new branch]      main -> main

295개 파일, 62,847줄의 코드가 성공적으로 업로드되었습니다!

🔄 CI/CD 파이프라인

자동화: 코드 푸시 → 자동 빌드 → 자동 배포

Azure Pipelines 설정

Azure DevOps에 코드를 푸시하면 자동으로 파이프라인이 실행됩니다:

# azure-pipelines.yaml
trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

stages:
  - stage: Build
    jobs:
      - job: BuildDocker
        steps:
          - task: Docker@2
            inputs:
              command: 'build'
              Dockerfile: 'backend/Dockerfile.prd'
              tags: '$(Build.BuildId)'
          
          - task: Docker@2
            inputs:
              command: 'build'
              Dockerfile: 'frontend/Dockerfile'
              tags: '$(Build.BuildId)'
  
  - stage: Deploy
    jobs:
      - job: DeployToSTG
        steps:
          - task: KubernetesManifest@0
            inputs:
              action: 'deploy'
              manifests: 'pipelines/stg/*.yaml'

파이프라인 실행 과정

  1. Trigger: main 브랜치에 푸시
  2. Build: Docker 이미지 빌드
    • Backend 이미지 빌드
    • Frontend 이미지 빌드
  3. Test: 자동 테스트 실행 (예정)
  4. Deploy: Kubernetes에 배포
    • ArgoCD가 변경 감지
    • STG 환경에 자동 배포

환경 변수 설정

STG 환경의 환경 변수는 별도로 관리됩니다:

# pipelines/stg/env.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: giftcall-ai-config
data:
  DATABASE_URL: "postgresql://giftcall_stg:***@postgres:5432/giftcall_stg"
  REDIS_HOST: "redis"
  REDIS_PORT: "6379"
  ALIMTALK_PROVIDER: "megabird"
  MEGABIRD_API_KEY: "***"

민감 정보는 Kubernetes Secret으로 관리됩니다.

🌐 STG 환경 배포

결과: 실제 접속 가능한 웹 애플리케이션

배포된 URL

✅ STG 환경 접속 정보
  • Frontend: https://stg-copilotmcp.emart.com/giftcall-ai
  • Backend API: https://stg-copilotmcp.emart.com/giftcall-ai/api
  • API 문서: https://stg-copilotmcp.emart.com/giftcall-ai/api/docs
  • ArgoCD: https://stg-copilotmcp.emart.com/argocd/applications/argocd/giftcall-ai

ArgoCD로 배포 상태 확인

ArgoCD는 Kubernetes 배포를 관리하는 도구입니다. 웹 UI에서 실시간으로 배포 상태를 확인할 수 있습니다:

첫 접속 테스트

드디어 실제 URL로 접속해봤습니다:

# Frontend 접속
https://stg-copilotmcp.emart.com/giftcall-ai

# 로그인 화면 표시 ✅
# 계정: admin / admin123!
# 로그인 성공 ✅

# 주문 목록 조회 ✅
# 메시지 발송 테스트 ✅
✅ 모든 기능 정상 작동!

로컬에서 작동하던 모든 기능이 STG 환경에서도 정상적으로 작동했습니다.

💡 배운 점

1. Git 버퍼 크기 문제

대용량 파일을 푸시할 때는 Git 버퍼 크기를 늘려야 합니다:

git config http.postBuffer 524288000

이 설정은 한 번만 하면 됩니다.

2. 환경 분리의 중요성

로컬과 서버 환경을 명확히 분리해야 합니다:

3. CI/CD의 편리함

한 번 설정해두면 이후에는 코드만 푸시하면 자동으로 배포됩니다:

git push azure main  # 이것만 하면 끝!

4. ArgoCD의 강력함

웹 UI에서 실시간으로 배포 상태를 확인할 수 있어서 편리합니다. 문제가 생기면 즉시 이전 버전으로 롤백할 수도 있습니다.

5. 완벽하지 않아도 괜찮다

코드가 완벽하지 않아도 일단 배포하고 점진적으로 개선할 수 있습니다. 리팩토링은 나중에 해도 됩니다.

🎯 다음 단계

Phase 1: 코드 정리

Phase 2: 모니터링 강화

Phase 3: PRD 환경 배포

배포 전 준비
Git 멀티 Remote
Azure DevOps 설정
CI/CD 파이프라인
STG 환경 배포
배운 점