diff --git a/.claude/commands/deploy-actions-cicd-guide-back.md b/.claude/commands/deploy-actions-cicd-guide-back.md new file mode 100644 index 0000000..794d662 --- /dev/null +++ b/.claude/commands/deploy-actions-cicd-guide-back.md @@ -0,0 +1,10 @@ +@cicd +'백엔드GitHubActions파이프라인작성가이드'에 따라 GitHub Actions를 이용한 CI/CD 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- ACR_NAME: acrdigitalgarage01 +- RESOURCE_GROUP: rg-digitalgarage-01 +- AKS_CLUSTER: aks-digitalgarage-01 +- NAMESPACE: phonebill-dg0500 \ No newline at end of file diff --git a/.claude/commands/deploy-actions-cicd-guide-front.md b/.claude/commands/deploy-actions-cicd-guide-front.md new file mode 100644 index 0000000..184aaa0 --- /dev/null +++ b/.claude/commands/deploy-actions-cicd-guide-front.md @@ -0,0 +1,11 @@ +@cicd +'프론트엔드GitHubActions파이프라인작성가이드'에 따라 GitHub Actions를 이용한 CI/CD 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- SYSTEM_NAME: phonebill +- ACR_NAME: acrdigitalgarage01 +- RESOURCE_GROUP: rg-digitalgarage-01 +- AKS_CLUSTER: aks-digitalgarage-01 +- NAMESPACE: phonebill-dg0500 \ No newline at end of file diff --git a/.claude/commands/deploy-build-image-back.md b/.claude/commands/deploy-build-image-back.md new file mode 100644 index 0000000..9893547 --- /dev/null +++ b/.claude/commands/deploy-build-image-back.md @@ -0,0 +1,2 @@ +@cicd +'백엔드컨테이너이미지작성가이드'에 따라 컨테이너 이미지를 작성해 주세요. \ No newline at end of file diff --git a/.claude/commands/deploy-build-image-front.md b/.claude/commands/deploy-build-image-front.md new file mode 100644 index 0000000..4c81118 --- /dev/null +++ b/.claude/commands/deploy-build-image-front.md @@ -0,0 +1,2 @@ +@cicd +'프론트엔드컨테이너이미지작성가이드'에 따라 컨테이너 이미지를 작성해 주세요. \ No newline at end of file diff --git a/.claude/commands/deploy-help.md b/.claude/commands/deploy-help.md new file mode 100644 index 0000000..cc52548 --- /dev/null +++ b/.claude/commands/deploy-help.md @@ -0,0 +1,55 @@ +배포 작업 순서 + +## 1단계: 컨테이너 이미지 작성 +### 백엔드 +/deploy-build-image-back +- 백엔드컨테이너이미지작성가이드에 따라 컨테이너 이미지를 작성합니다 + +### 프론트엔드 +/deploy-build-image-front +- 프론트엔드컨테이너이미지작성가이드에 따라 컨테이너 이미지를 작성합니다 + +## 2단계: 컨테이너 실행 가이드 작성 +### 백엔드 +/deploy-run-container-guide-back +- 백엔드컨테이너실행방법가이드에 따라 실행 가이드를 작성합니다 +- [실행정보] 섹션에 ACR명, VM 정보를 제공해야 합니다 + +### 프론트엔드 +/deploy-run-container-guide-front +- 프론트엔드컨테이너실행방법가이드에 따라 실행 가이드를 작성합니다 +- [실행정보] 섹션에 시스템명, ACR명, VM 정보를 제공해야 합니다 + +## 3단계: 쿠버네티스 배포 가이드 작성 +### 백엔드 +/deploy-k8s-guide-back +- 백엔드배포가이드에 따라 K8s 배포 가이드를 작성합니다 +- [실행정보] 섹션에 ACR명, k8s명, 네임스페이스, 리소스 정보를 제공해야 합니다 + +### 프론트엔드 +/deploy-k8s-guide-front +- 프론트엔드배포가이드에 따라 K8s 배포 가이드를 작성합니다 +- [실행정보] 섹션에 시스템명, ACR명, k8s명, 네임스페이스, 리소스, Gateway Host 정보를 제공해야 합니다 + +## 4단계: CI/CD 파이프라인 작성 +### Jenkins CI/CD +#### 백엔드 +/deploy-jenkins-cicd-guide-back +- 백엔드Jenkins파이프라인작성가이드에 따라 작성합니다 +- [실행정보] 섹션에 ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다 + +#### 프론트엔드 +/deploy-jenkins-cicd-guide-front +- 프론트엔드Jenkins파이프라인작성가이드에 따라 작성합니다 +- [실행정보] 섹션에 SYSTEM_NAME, ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다 + +### GitHub Actions CI/CD +#### 백엔드 +/deploy-actions-cicd-guide-back +- 백엔드GitHubActions파이프라인작성가이드에 따라 작성합니다 +- [실행정보] 섹션에 ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다 + +#### 프론트엔드 +/deploy-actions-cicd-guide-front +- 프론트엔드GitHubActions파이프라인작성가이드에 따라 작성합니다 +- [실행정보] 섹션에 SYSTEM_NAME, ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다 \ No newline at end of file diff --git a/.claude/commands/deploy-jenkins-cicd-guide-back.md b/.claude/commands/deploy-jenkins-cicd-guide-back.md new file mode 100644 index 0000000..d14ddc4 --- /dev/null +++ b/.claude/commands/deploy-jenkins-cicd-guide-back.md @@ -0,0 +1,10 @@ +@cicd +'백엔드Jenkins파이프라인작성가이드'에 따라 Jenkins를 이용한 CI/CD 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- ACR_NAME: acrdigitalgarage01 +- RESOURCE_GROUP: rg-digitalgarage-01 +- AKS_CLUSTER: aks-digitalgarage-01 +- NAMESPACE: phonebill-dg0500 \ No newline at end of file diff --git a/.claude/commands/deploy-jenkins-cicd-guide-front.md b/.claude/commands/deploy-jenkins-cicd-guide-front.md new file mode 100644 index 0000000..4c7dc11 --- /dev/null +++ b/.claude/commands/deploy-jenkins-cicd-guide-front.md @@ -0,0 +1,11 @@ +@cicd +'프론트엔드Jenkins파이프라인작성가이드'에 따라 Jenkins를 이용한 CI/CD 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- SYSTEM_NAME: phonebill +- ACR_NAME: acrdigitalgarage01 +- RESOURCE_GROUP: rg-digitalgarage-01 +- AKS_CLUSTER: aks-digitalgarage-01 +- NAMESPACE: phonebill-dg0500 \ No newline at end of file diff --git a/.claude/commands/deploy-k8s-guide-back.md b/.claude/commands/deploy-k8s-guide-back.md new file mode 100644 index 0000000..e6f23bb --- /dev/null +++ b/.claude/commands/deploy-k8s-guide-back.md @@ -0,0 +1,12 @@ +@cicd +'백엔드배포가이드'에 따라 백엔드 서비스 배포 방법을 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- ACR명: acrdigitalgarage01 +- k8s명: aks-digitalgarage-01 +- 네임스페이스: tripgen +- 파드수: 2 +- 리소스(CPU): 256m/1024m +- 리소스(메모리): 256Mi/1024Mi \ No newline at end of file diff --git a/.claude/commands/deploy-k8s-guide-front.md b/.claude/commands/deploy-k8s-guide-front.md new file mode 100644 index 0000000..8773bd4 --- /dev/null +++ b/.claude/commands/deploy-k8s-guide-front.md @@ -0,0 +1,14 @@ +@cicd +'프론트엔드배포가이드'에 따라 프론트엔드 서비스 배포 방법을 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- 시스템명: tripgen +- ACR명: acrdigitalgarage01 +- k8s명: aks-digitalgarage-01 +- 네임스페이스: tripgen +- 파드수: 2 +- 리소스(CPU): 256m/1024m +- 리소스(메모리): 256Mi/1024Mi +- Gateway Host: http://tripgen-api.20.214.196.128.nip.io \ No newline at end of file diff --git a/.claude/commands/deploy-run-container-guide-back.md b/.claude/commands/deploy-run-container-guide-back.md new file mode 100644 index 0000000..e18d86c --- /dev/null +++ b/.claude/commands/deploy-run-container-guide-back.md @@ -0,0 +1,11 @@ +@cicd +'백엔드컨테이너실행방법가이드'에 따라 컨테이너 실행 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- ACR명: acrdigitalgarage01 +- VM + - KEY파일: ~/home/bastion-dg0502 + - USERID: azureuser + - IP: 4.218.10.89 \ No newline at end of file diff --git a/.claude/commands/deploy-run-container-guide-front.md b/.claude/commands/deploy-run-container-guide-front.md new file mode 100644 index 0000000..faca872 --- /dev/null +++ b/.claude/commands/deploy-run-container-guide-front.md @@ -0,0 +1,12 @@ +@cicd +'프론트엔드컨테이너실행방법가이드'에 따라 컨테이너 실행 가이드를 작성해 주세요. +프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요. +{안내메시지} +'[실행정보]'섹션 하위에 아래 예와 같이 필요한 정보를 제시해 주세요. +[실행정보] +- 시스템명: tripgen +- ACR명: acrdigitalgarage01 +- VM + - KEY파일: ~/home/bastion-dg0500 + - USERID: azureuser + - IP: 4.230.5.6 \ No newline at end of file diff --git a/deployment/container/Dockerfile-backend b/deployment/container/Dockerfile-backend new file mode 100644 index 0000000..37da239 --- /dev/null +++ b/deployment/container/Dockerfile-backend @@ -0,0 +1,25 @@ +# Build stage +FROM openjdk:23-oraclelinux8 AS builder +ARG BUILD_LIB_DIR +ARG ARTIFACTORY_FILE +COPY ${BUILD_LIB_DIR}/${ARTIFACTORY_FILE} app.jar + +# Run stage +FROM openjdk:23-slim +ENV USERNAME=k8s +ENV ARTIFACTORY_HOME=/home/${USERNAME} +ENV JAVA_OPTS="" + +# Add a non-root user +RUN adduser --system --group ${USERNAME} && \ + mkdir -p ${ARTIFACTORY_HOME} && \ + chown ${USERNAME}:${USERNAME} ${ARTIFACTORY_HOME} + +WORKDIR ${ARTIFACTORY_HOME} +COPY --from=builder app.jar app.jar +RUN chown ${USERNAME}:${USERNAME} app.jar + +USER ${USERNAME} + +ENTRYPOINT [ "sh", "-c" ] +CMD ["java ${JAVA_OPTS} -jar app.jar"] diff --git a/deployment/container/build-image.md b/deployment/container/build-image.md new file mode 100644 index 0000000..d861c9e --- /dev/null +++ b/deployment/container/build-image.md @@ -0,0 +1,365 @@ +# 백엔드 컨테이너 이미지 작성 결과 + +작성일: 2025-10-27 +작성자: DevOps Engineer + +## 1. 개요 + +KT 이벤트 마케팅 플랫폼의 백엔드 마이크로서비스들을 컨테이너 이미지로 빌드하는 과정을 문서화합니다. + +## 2. 서비스 현황 + +### 2.1 전체 서비스 목록 (settings.gradle 기준) + +``` +rootProject.name = 'kt-event-marketing' + +// Common module +include 'common' + +// Microservices +include 'user-service' +include 'event-service' +include 'ai-service' +include 'content-service' +include 'distribution-service' +include 'participation-service' +include 'analytics-service' +``` + +### 2.2 구현 상태 + +| 서비스명 | 구현 상태 | JAR 빌드 | 컨테이너 이미지 | 비고 | +|---------|----------|---------|---------------|------| +| common | ✅ | N/A | N/A | 공통 라이브러리 | +| user-service | ⚠️ | ❌ | ⏸️ | 컴파일 에러 (타입 불일치) | +| event-service | ✅ | ✅ | ⏸️ | Docker Desktop 필요 | +| ai-service | ❌ | ❌ | ❌ | 미구현 | +| content-service | ✅ | ✅ | ⏸️ | Docker Desktop 필요 | +| distribution-service | ❌ | ❌ | ❌ | 미구현 | +| participation-service | ✅ | ✅ | ⏸️ | Docker Desktop 필요 | +| analytics-service | ✅ | ✅ | ⏸️ | Docker Desktop 필요 | + +**빌드 가능 서비스**: 4개 (event-service, content-service, participation-service, analytics-service) + +## 3. JAR 파일 빌드 + +### 3.1 bootJar 설정 확인 + +root `build.gradle`에 이미 설정되어 있음: + +```gradle +// Configure bootJar task for each service +bootJar { + archiveFileName = "${project.name}.jar" +} +``` + +### 3.2 JAR 빌드 실행 + +**명령어**: +```bash +./gradlew :analytics-service:bootJar :content-service:bootJar :event-service:bootJar :participation-service:bootJar :user-service:bootJar --no-daemon +``` + +**빌드 결과**: + +✅ **성공한 서비스 (4개)**: +- `analytics-service/build/libs/analytics-service.jar` +- `content-service/build/libs/content-service.jar` +- `event-service/build/libs/event-service.jar` +- `participation-service/build/libs/participation-service.jar` + +❌ **실패한 서비스 (1개)**: +- `user-service`: 컴파일 에러 발생 + +**user-service 컴파일 에러 상세**: +``` +UserController.java:93: error: incompatible types: UUID cannot be converted to Long + Long userId = principal.getUserId(); + ^ +UserController.java:109: error: incompatible types: UUID cannot be converted to Long + Long userId = principal.getUserId(); + ^ +UserController.java:126: error: incompatible types: UUID cannot be converted to Long + Long userId = principal.getUserId(); + ^ +AuthenticationServiceImpl.java:72: error: method createAccessToken in class JwtTokenProvider cannot be applied to given types; + required: UUID,UUID,String,String,List + found: Long,String,String,List + reason: actual and formal argument lists differ in length +``` + +**조치 필요**: user-service의 User ID 타입을 Long에서 UUID로 변경 필요 + +## 4. Dockerfile 작성 + +**파일 위치**: `deployment/container/Dockerfile-backend` + +**내용**: +```dockerfile +# Build stage +FROM openjdk:23-oraclelinux8 AS builder +ARG BUILD_LIB_DIR +ARG ARTIFACTORY_FILE +COPY ${BUILD_LIB_DIR}/${ARTIFACTORY_FILE} app.jar + +# Run stage +FROM openjdk:23-slim +ENV USERNAME=k8s +ENV ARTIFACTORY_HOME=/home/${USERNAME} +ENV JAVA_OPTS="" + +# Add a non-root user +RUN adduser --system --group ${USERNAME} && \ + mkdir -p ${ARTIFACTORY_HOME} && \ + chown ${USERNAME}:${USERNAME} ${ARTIFACTORY_HOME} + +WORKDIR ${ARTIFACTORY_HOME} +COPY --from=builder app.jar app.jar +RUN chown ${USERNAME}:${USERNAME} app.jar + +USER ${USERNAME} + +ENTRYPOINT [ "sh", "-c" ] +CMD ["java ${JAVA_OPTS} -jar app.jar"] +``` + +**특징**: +- Multi-stage build (빌드 단계와 실행 단계 분리) +- OpenJDK 23 사용 +- 비root 사용자(k8s)로 실행하여 보안 강화 +- JAVA_OPTS 환경변수로 JVM 옵션 커스터마이징 가능 +- linux/amd64 플랫폼 지원 + +## 5. 컨테이너 이미지 빌드 + +### 5.1 사전 조건 + +⚠️ **Docker Desktop 실행 필요** + +이미지 빌드 전에 Docker Desktop이 실행되어 있어야 합니다: + +1. Windows에서 Docker Desktop 실행 +2. 시스템 트레이에서 "Docker Desktop is running" 확인 +3. 확인 명령어: `docker ps` + +### 5.2 빌드 명령어 + +#### analytics-service +```bash +docker build \ + --platform linux/amd64 \ + --build-arg BUILD_LIB_DIR="analytics-service/build/libs" \ + --build-arg ARTIFACTORY_FILE="analytics-service.jar" \ + -f deployment/container/Dockerfile-backend \ + -t analytics-service:latest . +``` + +#### content-service +```bash +docker build \ + --platform linux/amd64 \ + --build-arg BUILD_LIB_DIR="content-service/build/libs" \ + --build-arg ARTIFACTORY_FILE="content-service.jar" \ + -f deployment/container/Dockerfile-backend \ + -t content-service:latest . +``` + +#### event-service +```bash +docker build \ + --platform linux/amd64 \ + --build-arg BUILD_LIB_DIR="event-service/build/libs" \ + --build-arg ARTIFACTORY_FILE="event-service.jar" \ + -f deployment/container/Dockerfile-backend \ + -t event-service:latest . +``` + +#### participation-service +```bash +docker build \ + --platform linux/amd64 \ + --build-arg BUILD_LIB_DIR="participation-service/build/libs" \ + --build-arg ARTIFACTORY_FILE="participation-service.jar" \ + -f deployment/container/Dockerfile-backend \ + -t participation-service:latest . +``` + +### 5.3 일괄 빌드 스크립트 + +모든 서비스를 한 번에 빌드하려면 다음 스크립트를 사용하세요: + +**Windows (PowerShell)**: +```powershell +# 빌드 가능한 서비스 목록 +$services = @( + "analytics-service", + "content-service", + "event-service", + "participation-service" +) + +# 각 서비스 빌드 +foreach ($service in $services) { + Write-Host "Building $service..." -ForegroundColor Green + docker build ` + --platform linux/amd64 ` + --build-arg BUILD_LIB_DIR="$service/build/libs" ` + --build-arg ARTIFACTORY_FILE="$service.jar" ` + -f deployment/container/Dockerfile-backend ` + -t ${service}:latest . + + if ($LASTEXITCODE -eq 0) { + Write-Host "✅ $service build completed" -ForegroundColor Green + } else { + Write-Host "❌ $service build failed" -ForegroundColor Red + } +} +``` + +**Linux/Mac (Bash)**: +```bash +#!/bin/bash + +# 빌드 가능한 서비스 목록 +services=( + "analytics-service" + "content-service" + "event-service" + "participation-service" +) + +# 각 서비스 빌드 +for service in "${services[@]}"; do + echo "Building $service..." + docker build \ + --platform linux/amd64 \ + --build-arg BUILD_LIB_DIR="${service}/build/libs" \ + --build-arg ARTIFACTORY_FILE="${service}.jar" \ + -f deployment/container/Dockerfile-backend \ + -t ${service}:latest . + + if [ $? -eq 0 ]; then + echo "✅ $service build completed" + else + echo "❌ $service build failed" + fi +done +``` + +## 6. 이미지 확인 + +### 6.1 빌드된 이미지 목록 확인 + +```bash +docker images | grep -E "analytics-service|content-service|event-service|participation-service" +``` + +**예상 출력**: +``` +analytics-service latest