Skip to content

Commit a80e5c9

Browse files
committed
crone: 배포 파이프라인 구성
1 parent bd2036f commit a80e5c9

File tree

14 files changed

+758
-62
lines changed

14 files changed

+758
-62
lines changed

.env.example

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# ===========================================
2+
# ProjectVG API Server - Environment Variables Template
3+
# ===========================================
4+
# Copy this file to .env and fill in your actual values
5+
6+
# Database Configuration
7+
DB_CONNECTION_STRING=Server=host.docker.internal,1433;Database=ProjectVG;User Id=sa;Password=YOUR_DB_PASSWORD;TrustServerCertificate=true;MultipleActiveResultSets=true
8+
DB_PASSWORD=YOUR_DB_PASSWORD
9+
10+
# Redis Configuration
11+
REDIS_CONNECTION_STRING=host.docker.internal:6380
12+
13+
# External Services
14+
LLM_BASE_URL=http://host.docker.internal:7908
15+
MEMORY_BASE_URL=http://host.docker.internal:7912
16+
TTS_BASE_URL=https://supertoneapi.com
17+
TTS_API_KEY=YOUR_TTS_API_KEY
18+
19+
# JWT Configuration (IMPORTANT: Use a secure random key in production)
20+
JWT_SECRET_KEY=YOUR_JWT_SECRET_KEY_MINIMUM_32_CHARACTERS
21+
JWT_ACCESS_TOKEN_LIFETIME_MINUTES=15
22+
JWT_REFRESH_TOKEN_LIFETIME_DAYS=30
23+
24+
# OAuth2 Configuration
25+
OAUTH2_ENABLED=true
26+
GOOGLE_OAUTH_ENABLED=true
27+
GOOGLE_OAUTH_CLIENT_ID=YOUR_GOOGLE_CLIENT_ID
28+
GOOGLE_OAUTH_CLIENT_SECRET=YOUR_GOOGLE_CLIENT_SECRET
29+
GOOGLE_OAUTH_REDIRECT_URI=http://localhost:7900/auth/oauth2/callback
30+
GOOGLE_OAUTH_AUTO_CREATE_USER=true
31+
GOOGLE_OAUTH_DEFAULT_ROLE=User
32+
33+
# Application Configuration
34+
ASPNETCORE_ENVIRONMENT=Production
35+
36+
# Container Resource Limits
37+
API_CPU_LIMIT=1.0
38+
API_MEMORY_LIMIT=1g
39+
API_PORT=7910

.gitattributes

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Set default behavior to automatically normalize line endings.
2+
* text=auto
3+
4+
# Set file types that should always have CRLF line endings on checkout.
5+
*.sln text eol=crlf
6+
*.csproj text eol=crlf
7+
*.config text eol=crlf
8+
9+
# Set file types that should always have LF line endings on checkout.
10+
*.sh text eol=lf
11+
*.bash text eol=lf
12+
*.yml text eol=lf
13+
*.yaml text eol=lf
14+
15+
# Ensure that shell scripts are executable
16+
*.sh text eol=lf
17+
deploy.sh text eol=lf
18+
deploy-dev.sh text eol=lf
19+
20+
# PowerShell scripts
21+
*.ps1 text eol=crlf
22+
23+
# Docker files
24+
Dockerfile text eol=lf
25+
*.dockerfile text eol=lf
26+
docker-compose*.yml text eol=lf
27+
28+
# Markdown files
29+
*.md text eol=lf
30+
31+
# JSON files
32+
*.json text eol=lf
Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: 개발 환경 CI
1+
name: Develop
22

33
on:
44
pull_request:
@@ -13,27 +13,27 @@ env:
1313

1414
jobs:
1515
build-and-test:
16-
name: 빌드 및 테스트
16+
name: Build & Test
1717
runs-on: ubuntu-latest
1818

1919
steps:
20-
- name: 소스 코드 체크아웃
20+
- name: Checkout
2121
uses: actions/checkout@v4
2222

23-
- name: .NET 환경 설정
23+
- name: Setup .NET
2424
uses: actions/setup-dotnet@v4
2525
with:
2626
dotnet-version: ${{ env.DOTNET_VERSION }}
2727

28-
- name: NuGet 패키지 캐싱
28+
- name: Cache NuGet
2929
uses: actions/cache@v4
3030
with:
3131
path: ~/.nuget/packages
3232
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
3333
restore-keys: |
3434
${{ runner.os }}-nuget-
3535
36-
- name: 종속성 복원
36+
- name: Restore
3737
run: |
3838
echo "복원 중..."
3939
start_time=$(date +%s)
@@ -42,7 +42,7 @@ jobs:
4242
duration=$((end_time - start_time))
4343
echo "복원 완료 (${duration}초)"
4444
45-
- name: 솔루션 빌드
45+
- name: Build
4646
run: |
4747
echo "🔨 빌드 중..."
4848
start_time=$(date +%s)
@@ -51,46 +51,30 @@ jobs:
5151
duration=$((end_time - start_time))
5252
echo "빌드 완료 (${duration}초)"
5353
54-
- name: 단위 테스트 실행
54+
- name: Test
5555
run: |
5656
echo "테스트 중..."
5757
start_time=$(date +%s)
5858
dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
5959
end_time=$(date +%s)
6060
duration=$((end_time - start_time))
6161
echo "테스트 완료 (${duration}초)"
62-
63-
- name: 코드 커버리지 리포트 생성
64-
uses: irongut/[email protected]
65-
with:
66-
filename: coverage/**/coverage.cobertura.xml
67-
badge: true
68-
fail_below_min: false
69-
format: markdown
70-
hide_branch_rate: false
71-
hide_complexity: true
72-
indicators: true
73-
output: both
74-
thresholds: '60 80'
75-
76-
- name: PR에 커버리지 결과 댓글 추가
77-
uses: marocchino/sticky-pull-request-comment@v2
78-
if: github.event_name == 'pull_request'
79-
with:
80-
recreate: true
81-
path: code-coverage-results.md
8262
83-
- name: 테스트 결과 발행
63+
- name: Publish Test Results
8464
uses: dorny/test-reporter@v1
8565
if: success() || failure()
8666
with:
87-
name: 테스트 결과
67+
name: Test Results
8868
path: coverage/*.trx
8969
reporter: dotnet-trx
9070

91-
- name: 빌드 상태 확인
71+
- name: Success Status
72+
if: success()
73+
run: |
74+
echo "✅ 빌드 및 테스트 성공"
75+
76+
- name: Build Status
9277
if: failure()
9378
run: |
9479
echo "❌ 빌드 실패"
95-
echo "단계를 확인하세요."
9680
exit 1
Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Release CI/CD
1+
name: Release
22

33
on:
44
push:
@@ -12,79 +12,110 @@ env:
1212
DOTNET_VERSION: '8.0.x'
1313
DOCKER_IMAGE_NAME: ghcr.io/projectvg/projectvgapi
1414
ACTOR: projectvg
15+
16+
permissions:
17+
contents: read
18+
packages: write
1519

1620
jobs:
1721
build:
22+
name: Build & Push
1823
runs-on: ubuntu-latest
1924

2025
steps:
21-
- name: Checkout Repository
26+
- name: Checkout
2227
uses: actions/checkout@v4
2328

2429
- name: Setup .NET
2530
uses: actions/setup-dotnet@v4
2631
with:
2732
dotnet-version: ${{ env.DOTNET_VERSION }}
2833

29-
- name: Cache NuGet packages
34+
- name: Cache NuGet
3035
uses: actions/cache@v4
3136
with:
3237
path: ~/.nuget/packages
3338
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
3439
restore-keys: |
3540
${{ runner.os }}-nuget-
3641
37-
- name: 종속성 복원
42+
- name: Restore
3843
run: |
3944
echo "복원 중..."
4045
dotnet restore ProjectVG.sln
4146
echo "복원 완료"
4247
43-
- name: 솔루션 빌드
48+
- name: Build
4449
run: |
4550
echo "🔨 빌드 중..."
4651
dotnet build ProjectVG.sln --no-restore --configuration Release
4752
echo "빌드 완료"
4853
49-
- name: 단위 테스트 실행
54+
- name: Test
5055
run: |
5156
echo "테스트 중..."
52-
dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage
57+
dotnet test --no-build --configuration Release --verbosity normal
5358
echo "테스트 완료"
5459
55-
- name: Login to GitHub Container Registry
60+
- name: Login GHCR
5661
uses: docker/login-action@v3
5762
with:
5863
registry: ghcr.io
5964
username: ${{ env.ACTOR }}
6065
password: ${{ secrets.GHCR_TOKEN }}
6166

62-
- name: Build and Push Docker Image
67+
- name: Build & Push Image
6368
run: |
6469
docker build -t ${{ env.DOCKER_IMAGE_NAME }}:latest -f ProjectVG.Api/Dockerfile .
6570
docker push ${{ env.DOCKER_IMAGE_NAME }}:latest
71+
72+
- name: Build Success Status
73+
if: success()
74+
run: |
75+
echo "✅ 빌드 및 이미지 푸시 완료"
76+
echo "이미지: ${{ env.DOCKER_IMAGE_NAME }}:latest"
77+
78+
- name: Build Failure Status
79+
if: failure()
80+
run: |
81+
echo "❌ 빌드 또는 이미지 푸시 실패"
82+
exit 1
6683
6784
deploy:
85+
name: Deploy
6886
needs: build
6987
runs-on: [self-hosted, deploy-runner]
7088

7189
steps:
72-
- name: Login to GitHub Container Registry
90+
- name: Checkout
91+
uses: actions/checkout@v4
92+
93+
- name: Login GHCR
7394
run: echo "${{ secrets.GHCR_TOKEN }}" | docker login ghcr.io -u ${{ env.ACTOR }} --password-stdin
7495

75-
- name: Add Private Files
96+
- name: Add Config Files
7697
run: |
7798
echo "${{ secrets.PROD_APPLICATION_ENV }}" | base64 --decode > .env
78-
echo "${{ secrets.PROD_DOCKER_COMPOSE }}" | base64 --decode > docker-compose.yml
99+
echo "${{ secrets.PROD_DOCKER_COMPOSE }}" | base64 --decode > deploy/docker-compose.yml
100+
101+
- name: Make Script Executable
102+
run: chmod +x deploy/deploy.sh
79103

80-
- name: Run Deployment Script
81-
run: ./deploy.sh
104+
- name: Deploy
105+
run: ./deploy/deploy.sh
82106

83-
- name: Cleanup Docker and Cache
107+
- name: Cleanup
84108
run: |
85109
docker system prune -af --volumes
86110
87-
- name: Deployment Status
111+
- name: Deploy Success Status
112+
if: success()
113+
run: |
114+
echo "✅ 배포 완료"
115+
echo "이미지: ${{ env.DOCKER_IMAGE_NAME }}:latest"
116+
117+
- name: Deploy Failure Status
118+
if: failure()
88119
run: |
89-
echo "🚀 배포 완료"
90-
echo "📦 이미지: ${{ env.DOCKER_IMAGE_NAME }}:latest"
120+
echo " 배포 실패"
121+
exit 1

.gitignore

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@ _ReSharper*/
100100

101101
# Docker
102102
**/Dockerfile.*
103-
docker-compose*
103+
docker-compose.override.yml
104+
105+
# Keep template files but ignore runtime files
106+
!docker-compose.prod.yml
107+
!env.prod.example
104108

105109
# Logs
106110
*.log
@@ -175,5 +179,5 @@ secrets.json
175179
*.xlsx
176180

177181
# Demo files
178-
web_chat_demo.html
179-
time_travel_commit.exe
182+
*.exe
183+
*.ini

ProjectVG.Api/Dockerfile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ EXPOSE 7900
2929
# 빌드 결과 복사
3030
COPY --from=build /app/publish .
3131

32-
# 헬스체크 추가
33-
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
34-
CMD curl -f http://localhost:7900/health || exit 1
32+
# 헬스체크 추가 - wget 사용
33+
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
34+
CMD wget --no-verbose --tries=1 --spider http://localhost:7900/health || exit 1
3535

3636
ENTRYPOINT ["dotnet", "ProjectVG.Api.dll"]

ProjectVG.sln

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectVG.Common", "Project
1515
EndProject
1616
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectVG.Tests", "ProjectVG.Tests\ProjectVG.Tests.csproj", "{9A8B7C6D-5E4F-3210-9876-543210987654}"
1717
EndProject
18-
Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{81DDED9D-158B-E303-5F62-77A2896D2A5A}"
19-
EndProject
2018
Global
2119
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2220
Debug|Any CPU = Debug|Any CPU
@@ -47,10 +45,6 @@ Global
4745
{9A8B7C6D-5E4F-3210-9876-543210987654}.Debug|Any CPU.Build.0 = Debug|Any CPU
4846
{9A8B7C6D-5E4F-3210-9876-543210987654}.Release|Any CPU.ActiveCfg = Release|Any CPU
4947
{9A8B7C6D-5E4F-3210-9876-543210987654}.Release|Any CPU.Build.0 = Release|Any CPU
50-
{81DDED9D-158B-E303-5F62-77A2896D2A5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
51-
{81DDED9D-158B-E303-5F62-77A2896D2A5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
52-
{81DDED9D-158B-E303-5F62-77A2896D2A5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
53-
{81DDED9D-158B-E303-5F62-77A2896D2A5A}.Release|Any CPU.Build.0 = Release|Any CPU
5448
EndGlobalSection
5549
GlobalSection(SolutionProperties) = preSolution
5650
HideSolutionNode = FALSE

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,26 @@ dotnet test ProjectVG.Tests/ProjectVG.Tests.csproj
115115
- `POST /api/auth/logout` - 로그아웃
116116
- `GET /api/test/me` - 사용자 정보 (인증 필요)
117117

118+
## 🚀 배포
119+
120+
### 자동 배포 (CI/CD)
121+
`release` 브랜치에 푸시하면 자동 배포됩니다.
122+
123+
### 수동 배포
124+
```bash
125+
# 프로덕션 배포
126+
./deploy.sh
127+
128+
# 개발 환경 배포
129+
./deploy-dev.sh
130+
131+
# Windows 환경
132+
.\scripts\deploy.ps1 -Environment dev
133+
.\scripts\deploy.ps1 -Environment prod
134+
```
135+
136+
상세한 배포 가이드는 [DEPLOYMENT.md](DEPLOYMENT.md)를 참조하세요.
137+
118138
## 🧪 테스트
119139

120140
### 테스트 실행

0 commit comments

Comments
 (0)