로컬에서 STG 환경까지 - Git 멀티 Remote와 CI/CD 파이프라인
고민: 이 코드를 회사 서버에 올려도 될까?
로컬에서는 잘 작동하는 코드지만, 회사 서버에 배포하려니 여러 걱정이 들었습니다:
먼저 코드 상태를 점검했습니다:
하지만 배포를 미룰 수는 없었습니다. "일단 작동하는 코드를 배포하고, 리팩토링은 나중에 하자"고 결정했습니다.
실제로 사용하는 파일과 사용하지 않는 파일을 구분했습니다:
| 파일 | 상태 | 조치 |
|---|---|---|
| kakaotalk_service.py | 완전 미사용 | 삭제 가능 (나중에) |
| database.py | 레거시 테이블 존재 | 데이터 마이그레이션 필요 |
| gift_models.py | 현재 사용 중 | 유지 |
가장 중요한 부분이었습니다. 민감 정보가 포함되어 있는지 꼼꼼히 확인했습니다:
로컬과 서버 환경이 제대로 분리되어 있는지 확인했습니다:
# 로컬 개발 환경 (.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
환경 변수로 잘 분리되어 있어서 안심했습니다.
개념: 하나의 코드를 두 곳에 보관하기
처음에는 이해가 안 됐습니다. GitHub에 이미 코드가 있는데 왜 Azure DevOps에도 올려야 하나?
| 항목 | GitHub | Azure DevOps |
|---|---|---|
| 용도 | 개발/백업 | 운영/배포 |
| 푸시 빈도 | 자주 (개발 중) | 배포 시만 |
| 자동 배포 | ❌ | ✅ CI/CD |
| 보안 | 개인 | 회사 정책 |
| 접근 | 본인만 | 팀 전체 |
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에 올릴 수 있습니다.
작업 시간: 2026년 1월 21일 13:30 ~ 14:46 (1시간 16분)
먼저 giftcall 폴더를 독립적인 Git 저장소로 만들어야 했습니다:
cd /Users/emart/Documents/PromptLibrary/giftcall
git init
git add .
git commit -m "Initial commit: GiftCall project"
이제 giftcall 폴더는 자체 Git 저장소가 되었습니다.
Azure DevOps에 접근하려면 인증이 필요합니다. PAT를 생성했습니다:
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)
드디어 푸시를 시도했습니다:
git push azure main
error: RPC failed; HTTP 413 curl 22 The requested URL returned error: 413
fatal: the remote end hung up unexpectedly
에러 메시지를 검색해보니 파일 크기가 너무 커서 발생하는 문제였습니다. Git 버퍼 크기를 늘려야 했습니다:
# 버퍼 크기를 500MB로 증가
git config http.postBuffer 524288000
# 다시 푸시
git push azure main
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줄의 코드가 성공적으로 업로드되었습니다!
자동화: 코드 푸시 → 자동 빌드 → 자동 배포
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'
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으로 관리됩니다.
결과: 실제 접속 가능한 웹 애플리케이션
ArgoCD는 Kubernetes 배포를 관리하는 도구입니다. 웹 UI에서 실시간으로 배포 상태를 확인할 수 있습니다:
드디어 실제 URL로 접속해봤습니다:
# Frontend 접속
https://stg-copilotmcp.emart.com/giftcall-ai
# 로그인 화면 표시 ✅
# 계정: admin / admin123!
# 로그인 성공 ✅
# 주문 목록 조회 ✅
# 메시지 발송 테스트 ✅
로컬에서 작동하던 모든 기능이 STG 환경에서도 정상적으로 작동했습니다.
대용량 파일을 푸시할 때는 Git 버퍼 크기를 늘려야 합니다:
git config http.postBuffer 524288000
이 설정은 한 번만 하면 됩니다.
로컬과 서버 환경을 명확히 분리해야 합니다:
한 번 설정해두면 이후에는 코드만 푸시하면 자동으로 배포됩니다:
git push azure main # 이것만 하면 끝!
웹 UI에서 실시간으로 배포 상태를 확인할 수 있어서 편리합니다. 문제가 생기면 즉시 이전 버전으로 롤백할 수도 있습니다.
코드가 완벽하지 않아도 일단 배포하고 점진적으로 개선할 수 있습니다. 리팩토링은 나중에 해도 됩니다.