Skip to content

Commit 2cb8122

Browse files
committed
Merge branch 'crone/ci-cd-pipline' of https://github.com/ProjectVG/ProjectVG-API-Server into crone/ci-cd-pipline
2 parents a0be4df + a80e5c9 commit 2cb8122

File tree

5 files changed

+69
-88
lines changed

5 files changed

+69
-88
lines changed

.github/workflows/develop.yml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,11 @@ jobs:
5555
run: |
5656
echo "테스트 중..."
5757
start_time=$(date +%s)
58-
dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
58+
dotnet test --no-build --configuration Release --verbosity normal
5959
end_time=$(date +%s)
6060
duration=$((end_time - start_time))
6161
echo "테스트 완료 (${duration}초)"
6262
63-
- name: Publish Test Results
64-
uses: dorny/test-reporter@v1
65-
if: success() || failure()
66-
with:
67-
name: Test Results
68-
path: coverage/*.trx
69-
reporter: dotnet-trx
70-
7163
- name: Success Status
7264
if: success()
7365
run: |

.github/workflows/release.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ jobs:
105105

106106
- name: Cleanup
107107
run: |
108-
docker system prune -af --volumes
108+
docker image prune -f
109+
docker builder prune -f
109110
110111
- name: Deploy Success Status
111112
if: success()

deploy/DEPLOYMENT.md

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,17 @@ git push origin release
5050
# 1. 최신 코드 가져오기
5151
git pull origin release
5252

53-
# 2. 환경 설정 파일 준비
54-
cp env.prod.example .env
55-
cp docker-compose.prod.yml docker-compose.yml
53+
# 2. DB/Redis 서비스 시작 (최초 1회만 실행)
54+
docker-compose -f docker-compose.db.yml up -d
5655

56+
# 3. 환경 설정 파일 준비
57+
cp env.prod.example .env
5758
# 실제 환경변수 값으로 수정
5859
vi .env
5960

60-
# 3. 배포 스크립트 실행
61-
chmod +x deploy.sh
62-
./deploy.sh
61+
# 4. API 서비스 배포
62+
chmod +x deploy/deploy.sh
63+
./deploy/deploy.sh
6364
```
6465

6566
### 개발 환경 배포
@@ -73,8 +74,9 @@ chmod +x deploy-dev.sh
7374
## 📋 배포 스크립트 상세
7475

7576
### `deploy.sh` (프로덕션)
76-
- **용도**: 프로덕션 환경 배포
77+
- **용도**: API 서비스만 배포 (DB/Redis는 별도 관리)
7778
- **이미지**: GHCR에서 최신 이미지 풀
79+
- **네트워크**: `projectvg-external-db` 네트워크로 DB/Redis 연결
7880
- **헬스체크**: 30회 재시도 (최대 2.5분)
7981
- **로그**: 배포 후 최근 로그 20줄 출력
8082

@@ -140,6 +142,11 @@ docker-compose up -d
140142
- 민감한 정보는 평문으로 저장하지 않음
141143
- 프로덕션과 개발 환경 분리
142144

145+
### 인프라 분리
146+
- **DB/Redis**: `docker-compose.db.yml`로 별도 관리 (영구 실행)
147+
- **API 서비스**: `docker-compose.prod.yml`로 배포시에만 재시작
148+
- **외부 DB/Cache**: AWS RDS, ElastiCache 등으로 쉽게 대체 가능
149+
143150
### Docker 이미지
144151
- GHCR을 통한 이미지 배포
145152
- 정기적인 base 이미지 업데이트

deploy/deploy.sh

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,47 @@ if [ ! -f "deploy/docker-compose.prod.yml" ]; then
2020
exit 1
2121
fi
2222

23-
# 현재 실행 중인 컨테이너 중지 및 제거
24-
echo "기존 컨테이너 중지 중..."
25-
docker-compose -f deploy/docker-compose.prod.yml down --remove-orphans || true
26-
27-
# GitHub Container Registry에서 최신 이미지 풀
23+
# GitHub Container Registry에서 최신 이미지 풀 (Zero-downtime을 위해 먼저 실행)
2824
echo "최신 이미지 다운로드 중..."
29-
echo "GHCR 이미진 Pull: ghcr.io/projectvg/projectvgapi:latest"
30-
docker-compose -f deploy/docker-compose.prod.yml pull
25+
echo "GHCR 이미지 Pull: ghcr.io/projectvg/projectvgapi:latest"
26+
docker-compose -f deploy/docker-compose.prod.yml pull projectvg-api
3127

3228
# 이미지 풀 후 확인
3329
if ! docker images ghcr.io/projectvg/projectvgapi:latest | grep -q latest; then
3430
echo "ERROR: 이미지 풀에 실패했습니다. GitHub Container Registry 인증을 확인하세요."
3531
exit 1
3632
fi
3733

38-
# 서비스 시작
39-
echo "서비스 시작 중..."
40-
docker-compose -f deploy/docker-compose.prod.yml up -d
34+
# 기존 API 컨테이너만 중지 및 제거 (Zero-downtime strategy)
35+
echo "기존 API 컨테이너 교체 중..."
36+
echo "현재 실행중인 컨테이너 확인:"
37+
docker ps -f "name=projectvg-api"
38+
39+
docker-compose -f deploy/docker-compose.prod.yml stop projectvg-api || true
40+
docker-compose -f deploy/docker-compose.prod.yml rm -f projectvg-api || true
41+
42+
# 새 이미지로 API 서비스만 시작
43+
echo "새 이미지로 API 서비스 시작 중..."
44+
docker-compose -f deploy/docker-compose.prod.yml up -d projectvg-api
4145

4246
# 서비스 상태 확인
43-
echo "서비스 상태 확인 중..."
44-
sleep 10
47+
# 빌드 후 불필요한 이미지 정리
48+
echo "이전 이미지 정리 중..."
49+
old_images=$(docker images ghcr.io/projectvg/projectvgapi -f "dangling=true" -q)
50+
if [ ! -z "$old_images" ]; then
51+
docker rmi $old_images -f 2>/dev/null || true
52+
echo "이전 이미지 정리 완료"
53+
else
54+
echo "정리할 이전 이미지 없음"
55+
fi
56+
57+
# 컨테이너 상태 확인
58+
echo "API 컨테이너 상태 확인 중..."
59+
sleep 3
4560

46-
# 컨테이너 상태 출력
47-
docker-compose -f deploy/docker-compose.prod.yml ps
61+
# API 컨테이너 상태만 출력
62+
echo "API 컨테이너 상태:"
63+
docker ps -f "name=projectvg-api"
4864

4965
# 헬스체크 (API가 응답하는지 확인)
5066
echo "헬스체크 수행 중..."
@@ -70,11 +86,12 @@ done
7086

7187
if [ $retry_count -eq $max_retries ]; then
7288
echo "ERROR: API 서버가 시작되지 않았습니다. 로그를 확인하세요."
73-
echo "API 컨테이너 로그:"
74-
echo "Docker 컨테이너 상태:"
89+
echo "API 컨테이너 상태:"
7590
docker ps -a --filter name=projectvg-api
76-
echo ""
91+
echo "API 컨테이너 로그 (최근 50줄):"
7792
docker-compose -f deploy/docker-compose.prod.yml logs --tail=50 projectvg-api
93+
94+
echo "롤백을 수행하시겠습니까? 이전 이미지로 복구할 수 있습니다."
7895
exit 1
7996
fi
8097

@@ -83,6 +100,14 @@ echo "배포가 성공적으로 완료되었습니다!"
83100
echo "API 엔드포인트: http://localhost:7910"
84101
echo "헬스체크: http://localhost:7910/health"
85102

86-
# 로그 출력 (선택적)
87-
echo "최근 로그:"
88-
docker-compose -f deploy/docker-compose.prod.yml logs --tail=20
103+
# 최근 API 로그 출력
104+
echo "최근 API 로그 (20줄):"
105+
docker-compose -f deploy/docker-compose.prod.yml logs --tail=20 projectvg-api
106+
107+
# 배포 완료 상태 요약
108+
echo ""
109+
echo "=== 배포 완료 상태 요약 ==="
110+
echo "API 컨테이너:"
111+
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" -f "name=projectvg-api"
112+
echo "이미지 정보:"
113+
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.CreatedAt}}\t{{.Size}}" ghcr.io/projectvg/projectvgapi:latest

deploy/docker-compose.prod.yml

Lines changed: 7 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,15 @@ services:
55
image: ghcr.io/projectvg/projectvgapi:latest
66
container_name: projectvg-api
77
ports:
8-
- "7910:8080"
8+
- "${API_PORT:-7910}:8080"
99
environment:
10-
- ASPNETCORE_ENVIRONMENT=Production
10+
- ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT:-Production}
1111
- ASPNETCORE_URLS=http://+:8080
1212
env_file:
1313
- .env
14-
depends_on:
15-
- projectvg-db
16-
- projectvg-redis
1714
networks:
1815
- projectvg-network
16+
- projectvg-external-db
1917
restart: unless-stopped
2018
healthcheck:
2119
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
@@ -29,51 +27,9 @@ services:
2927
max-size: "100m"
3028
max-file: "3"
3129

32-
projectvg-db:
33-
image: mcr.microsoft.com/mssql/server:2022-latest
34-
container_name: projectvg-db
35-
ports:
36-
- "1433:1433"
37-
environment:
38-
- ACCEPT_EULA=Y
39-
- MSSQL_SA_PASSWORD=${DB_SA_PASSWORD}
40-
- MSSQL_PID=Developer
41-
volumes:
42-
- projectvg_db_data:/var/opt/mssql
43-
networks:
44-
- projectvg-network
45-
restart: unless-stopped
46-
healthcheck:
47-
test: ["CMD-SHELL", "/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P ${DB_SA_PASSWORD} -Q 'SELECT 1' || exit 1"]
48-
interval: 30s
49-
timeout: 10s
50-
retries: 3
51-
start_period: 60s
52-
53-
projectvg-redis:
54-
image: redis:7-alpine
55-
container_name: projectvg-redis
56-
ports:
57-
- "6380:6379"
58-
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
59-
volumes:
60-
- projectvg_redis_data:/data
61-
networks:
62-
- projectvg-network
63-
restart: unless-stopped
64-
healthcheck:
65-
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
66-
interval: 30s
67-
timeout: 10s
68-
retries: 3
69-
start_period: 30s
70-
71-
volumes:
72-
projectvg_db_data:
73-
driver: local
74-
projectvg_redis_data:
75-
driver: local
76-
7730
networks:
7831
projectvg-network:
79-
driver: bridge
32+
driver: bridge
33+
projectvg-external-db:
34+
external: true
35+
name: projectvg-external-db

0 commit comments

Comments
 (0)