Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 060921e756 | |||
| b198c46d06 | |||
| 003b3843cc | |||
| 8323b795df | |||
| ce3e01008a | |||
| ea807cf33e | |||
| 394c7a0029 | |||
| e70f121db5 | |||
| 6465719b2c |
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-actions-cicd-guide-back"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'백엔드GitHubActions파이프라인작성가이드'에 따라 GitHub Actions를 이용한 CI/CD 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-actions-cicd-guide-front"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'프론트엔드GitHubActions파이프라인작성가이드'에 따라 GitHub Actions를 이용한 CI/CD 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,2 +1,6 @@
|
||||
---
|
||||
command: "/deploy-build-image-back"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'백엔드컨테이너이미지작성가이드'에 따라 컨테이너 이미지를 작성해 주세요.
|
||||
@@ -1,2 +1,6 @@
|
||||
---
|
||||
command: "/deploy-build-image-front"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'프론트엔드컨테이너이미지작성가이드'에 따라 컨테이너 이미지를 작성해 주세요.
|
||||
@@ -1,55 +1,81 @@
|
||||
배포 작업 순서
|
||||
---
|
||||
command: "/deploy-help"
|
||||
---
|
||||
|
||||
# 배포 작업 순서
|
||||
|
||||
## 1단계: 컨테이너 이미지 작성
|
||||
### 백엔드
|
||||
```
|
||||
/deploy-build-image-back
|
||||
- 백엔드컨테이너이미지작성가이드에 따라 컨테이너 이미지를 작성합니다
|
||||
```
|
||||
- 백엔드컨테이너이미지작성가이드를 참고하여 컨테이너 이미지를 빌드합니다
|
||||
|
||||
### 프론트엔드
|
||||
```
|
||||
/deploy-build-image-front
|
||||
- 프론트엔드컨테이너이미지작성가이드에 따라 컨테이너 이미지를 작성합니다
|
||||
```
|
||||
- 프론트엔드컨테이너이미지작성가이드를 참고하여 컨테이너 이미지를 빌드합니다
|
||||
|
||||
## 2단계: 컨테이너 실행 가이드 작성
|
||||
### 백엔드
|
||||
```
|
||||
/deploy-run-container-guide-back
|
||||
- 백엔드컨테이너실행방법가이드에 따라 실행 가이드를 작성합니다
|
||||
- [실행정보] 섹션에 ACR명, VM 정보를 제공해야 합니다
|
||||
```
|
||||
- 백엔드컨테이너실행방법가이드를 참고하여 컨테이너 실행 방법을 작성합니다
|
||||
- 실행정보(ACR명, VM정보)가 필요합니다
|
||||
|
||||
### 프론트엔드
|
||||
```
|
||||
/deploy-run-container-guide-front
|
||||
- 프론트엔드컨테이너실행방법가이드에 따라 실행 가이드를 작성합니다
|
||||
- [실행정보] 섹션에 시스템명, ACR명, VM 정보를 제공해야 합니다
|
||||
```
|
||||
- 프론트엔드컨테이너실행방법가이드를 참고하여 컨테이너 실행 방법을 작성합니다
|
||||
- 실행정보(시스템명, ACR명, VM정보)가 필요합니다
|
||||
|
||||
## 3단계: 쿠버네티스 배포 가이드 작성
|
||||
## 3단계: Kubernetes 배포 가이드 작성
|
||||
### 백엔드
|
||||
```
|
||||
/deploy-k8s-guide-back
|
||||
- 백엔드배포가이드에 따라 K8s 배포 가이드를 작성합니다
|
||||
- [실행정보] 섹션에 ACR명, k8s명, 네임스페이스, 리소스 정보를 제공해야 합니다
|
||||
```
|
||||
- 백엔드배포가이드를 참고하여 쿠버네티스 배포 방법을 작성합니다
|
||||
- 실행정보(ACR명, k8s명, 네임스페이스, 리소스 설정)가 필요합니다
|
||||
|
||||
### 프론트엔드
|
||||
```
|
||||
/deploy-k8s-guide-front
|
||||
- 프론트엔드배포가이드에 따라 K8s 배포 가이드를 작성합니다
|
||||
- [실행정보] 섹션에 시스템명, ACR명, k8s명, 네임스페이스, 리소스, Gateway Host 정보를 제공해야 합니다
|
||||
```
|
||||
- 프론트엔드배포가이드를 참고하여 쿠버네티스 배포 방법을 작성합니다
|
||||
- 실행정보(시스템명, ACR명, k8s명, 네임스페이스, Gateway Host, 리소스 설정)가 필요합니다
|
||||
|
||||
## 4단계: CI/CD 파이프라인 작성
|
||||
### Jenkins CI/CD
|
||||
## 4단계: CI/CD 파이프라인 구성
|
||||
|
||||
### Jenkins 사용 시
|
||||
#### 백엔드
|
||||
```
|
||||
/deploy-jenkins-cicd-guide-back
|
||||
- 백엔드Jenkins파이프라인작성가이드에 따라 작성합니다
|
||||
- [실행정보] 섹션에 ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다
|
||||
```
|
||||
- 백엔드Jenkins파이프라인작성가이드를 참고하여 Jenkins CI/CD 파이프라인을 구성합니다
|
||||
|
||||
#### 프론트엔드
|
||||
```
|
||||
/deploy-jenkins-cicd-guide-front
|
||||
- 프론트엔드Jenkins파이프라인작성가이드에 따라 작성합니다
|
||||
- [실행정보] 섹션에 SYSTEM_NAME, ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다
|
||||
```
|
||||
- 프론트엔드Jenkins파이프라인작성가이드를 참고하여 Jenkins CI/CD 파이프라인을 구성합니다
|
||||
|
||||
### GitHub Actions CI/CD
|
||||
### GitHub Actions 사용 시
|
||||
#### 백엔드
|
||||
```
|
||||
/deploy-actions-cicd-guide-back
|
||||
- 백엔드GitHubActions파이프라인작성가이드에 따라 작성합니다
|
||||
- [실행정보] 섹션에 ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다
|
||||
```
|
||||
- 백엔드GitHubActions파이프라인작성가이드를 참고하여 GitHub Actions CI/CD 파이프라인을 구성합니다
|
||||
|
||||
#### 프론트엔드
|
||||
```
|
||||
/deploy-actions-cicd-guide-front
|
||||
- 프론트엔드GitHubActions파이프라인작성가이드에 따라 작성합니다
|
||||
- [실행정보] 섹션에 SYSTEM_NAME, ACR_NAME, RESOURCE_GROUP, AKS_CLUSTER, NAMESPACE 정보를 제공해야 합니다
|
||||
```
|
||||
- 프론트엔드GitHubActions파이프라인작성가이드를 참고하여 GitHub Actions CI/CD 파이프라인을 구성합니다
|
||||
|
||||
## 참고사항
|
||||
- 각 명령 실행 전 필요한 실행정보를 프롬프트에 포함해야 합니다
|
||||
- 실행정보가 없으면 안내 메시지가 표시되며 작업이 중단됩니다
|
||||
- CI/CD 도구는 Jenkins 또는 GitHub Actions 중 선택하여 사용합니다
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-jenkins-cicd-guide-back"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'백엔드Jenkins파이프라인작성가이드'에 따라 Jenkins를 이용한 CI/CD 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-jenkins-cicd-guide-front"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'프론트엔드Jenkins파이프라인작성가이드'에 따라 Jenkins를 이용한 CI/CD 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-k8s-guide-back"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'백엔드배포가이드'에 따라 백엔드 서비스 배포 방법을 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-k8s-guide-front"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'프론트엔드배포가이드'에 따라 프론트엔드 서비스 배포 방법을 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-run-container-guide-back"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'백엔드컨테이너실행방법가이드'에 따라 컨테이너 실행 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
@@ -6,6 +10,6 @@
|
||||
[실행정보]
|
||||
- ACR명: acrdigitalgarage01
|
||||
- VM
|
||||
- KEY파일: ~/home/bastion-dg0502
|
||||
- KEY파일: ~/home/bastion-dg0500
|
||||
- USERID: azureuser
|
||||
- IP: 4.218.10.89
|
||||
- IP: 4.230.5.6
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/deploy-run-container-guide-front"
|
||||
---
|
||||
|
||||
@cicd
|
||||
'프론트엔드컨테이너실행방법가이드'에 따라 컨테이너 실행 가이드를 작성해 주세요.
|
||||
프롬프트에 '[실행정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-api"
|
||||
---
|
||||
@architecture
|
||||
API를 설계해 주세요:
|
||||
- '공통설계원칙'과 'API설계가이드'를 준용하여 설계
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-class"
|
||||
---
|
||||
@architecture
|
||||
'공통설계원칙'과 '클래스설계가이드'를 준용하여 클래스를 설계해 주세요.
|
||||
프롬프트에 '[클래스설계 정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-data"
|
||||
---
|
||||
@architecture
|
||||
데이터 설계를 해주세요:
|
||||
- '공통설계원칙'과 '데이터설계가이드'를 준용하여 설계
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-fix-prototype"
|
||||
---
|
||||
@fix as @front
|
||||
'[오류내용]'섹션에 제공된 오류를 해결해 주세요.
|
||||
프롬프트에 '[오류내용]'섹션이 없으면 수행 중단하고 안내 메시지 표시
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-front"
|
||||
---
|
||||
@plan as @front
|
||||
'프론트엔드설계가이드'를 준용하여 **프론트엔드설계서**를 작성해 주세요.
|
||||
프롬프트에 '[백엔드시스템]'항목이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-high-level"
|
||||
---
|
||||
@architecture
|
||||
'HighLevel아키텍처정의가이드'를 준용하여 High Level 아키텍처 정의서를 작성해 주세요.
|
||||
'CLOUD' 정보가 없으면 수행을 중단하고 안내메시지를 표시하세요.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-improve-prototype"
|
||||
---
|
||||
@improve as @front
|
||||
'[개선내용]'섹션에 있는 내용을 개선해 주세요.
|
||||
프롬프트에 '[개선내용]'항목이 없으면 수행을 중단하고 안내 메시지 표시
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
---
|
||||
command: "/design-improve-userstory"
|
||||
---
|
||||
@analyze as @front 프로토타입을 웹브라우저에서 분석한 후,
|
||||
@document as @scribe 수정된 프로토타입에 따라 유저스토리를 업데이트 해주십시오.
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-logical"
|
||||
---
|
||||
@architecture
|
||||
논리 아키텍처를 설계해 주세요:
|
||||
- '공통설계원칙'과 '논리아키텍처 설계 가이드'를 준용하여 설계
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-pattern"
|
||||
---
|
||||
@design-pattern
|
||||
클라우드 아키텍처 패턴 적용 방안을 작성해 주세요:
|
||||
- '클라우드아키텍처패턴선정가이드'를 준용하여 작성
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-physical"
|
||||
---
|
||||
@architecture
|
||||
'물리아키텍처설계가이드'를 준용하여 물리아키텍처를 설계해 주세요.
|
||||
'CLOUD' 정보가 없으면 수행을 중단하고 안내메시지를 표시하세요.
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-prototype"
|
||||
---
|
||||
@prototype
|
||||
프로토타입을 작성해 주세요:
|
||||
- '프로토타입작성가이드'를 준용하여 작성
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-seq-inner"
|
||||
---
|
||||
@architecture
|
||||
내부 시퀀스 설계를 해 주세요:
|
||||
- '공통설계원칙'과 '내부시퀀스설계 가이드'를 준용하여 설계
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-seq-outer"
|
||||
---
|
||||
@architecture
|
||||
외부 시퀀스 설계를 해 주세요:
|
||||
- '공통설계원칙'과 '외부시퀀스설계가이드'를 준용하여 설계
|
||||
@@ -1,2 +1,5 @@
|
||||
---
|
||||
command: "/design-test-prototype"
|
||||
---
|
||||
@test-front
|
||||
프로토타입을 테스트 해 주세요.
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/design-uiux"
|
||||
---
|
||||
@uiux
|
||||
UI/UX 설계를 해주세요:
|
||||
- 'UI/UX설계가이드'를 준용하여 작성
|
||||
@@ -1,2 +1,5 @@
|
||||
---
|
||||
command: "/design-update-uiux"
|
||||
---
|
||||
@document @front
|
||||
현재 프로토타입과 유저스토리를 기준으로 UI/UX설계서와 스타일가이드를 수정해 주세요.
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/think-help"
|
||||
---
|
||||
기획 작업 순서
|
||||
|
||||
1단계: 서비스 기획
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
---
|
||||
command: "/think-planning"
|
||||
---
|
||||
아래 내용을 터미널에 표시만 하고 수행을 하지는 않습니다.
|
||||
```
|
||||
아래 가이드를 참고하여 서비스 기획을 수행합니다.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
---
|
||||
command: "/think-userstory"
|
||||
---
|
||||
```
|
||||
@document
|
||||
유저스토리를 작성하세요.
|
||||
프롬프트에 '[요구사항]'섹션이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
@@ -16,3 +20,5 @@ Case 2) 다른 방법으로 이벤트스토밍을 한 경우는 요구사항을
|
||||
2. 유저스토리 작성
|
||||
- '유저스토리작성방법'과 '유저스토리예제'를 참고하여 유저스토리를 작성
|
||||
- 결과파일은 'design/userstory.md'에 생성
|
||||
|
||||
```
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="EventServiceApplication" type="SpringBootApplicationConfigurationType" factoryName="Spring Boot" folderName="Event Service">
|
||||
<option name="ACTIVE_PROFILES" />
|
||||
<option name="ENABLE_LAUNCH_OPTIMIZATION" value="true" />
|
||||
<envs>
|
||||
<env name="DB_HOST" value="20.249.177.232" />
|
||||
<env name="DB_PORT" value="5432" />
|
||||
<env name="DB_NAME" value="eventdb" />
|
||||
<env name="DB_USERNAME" value="eventuser" />
|
||||
<env name="DB_PASSWORD" value="Hi5Jessica!" />
|
||||
<env name="REDIS_HOST" value="localhost" />
|
||||
<env name="REDIS_PORT" value="6379" />
|
||||
<env name="REDIS_PASSWORD" value="" />
|
||||
<env name="KAFKA_BOOTSTRAP_SERVERS" value="localhost:9092" />
|
||||
<env name="SERVER_PORT" value="8081" />
|
||||
<env name="DDL_AUTO" value="update" />
|
||||
<env name="LOG_LEVEL" value="DEBUG" />
|
||||
<env name="SQL_LOG_LEVEL" value="DEBUG" />
|
||||
<env name="DISTRIBUTION_SERVICE_URL" value="http://localhost:8084" />
|
||||
</envs>
|
||||
<module name="kt-event-marketing.event-service.main" />
|
||||
<option name="SPRING_BOOT_MAIN_CLASS" value="com.kt.event.eventservice.EventServiceApplication" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -1,89 +0,0 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="analytics-service" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<ExternalSystemSettings>
|
||||
<option name="env">
|
||||
<map>
|
||||
<!-- Database Settings -->
|
||||
<entry key="DB_KIND" value="postgresql" />
|
||||
<entry key="DB_HOST" value="4.230.49.9" />
|
||||
<entry key="DB_PORT" value="5432" />
|
||||
<entry key="DB_NAME" value="analyticdb" />
|
||||
<entry key="DB_USERNAME" value="eventuser" />
|
||||
<entry key="DB_PASSWORD" value="Hi5Jessica!" />
|
||||
|
||||
<!-- Redis Settings -->
|
||||
<entry key="REDIS_HOST" value="20.214.210.71" />
|
||||
<entry key="REDIS_PORT" value="6379" />
|
||||
<entry key="REDIS_PASSWORD" value="Hi5Jessica!" />
|
||||
<entry key="REDIS_DATABASE" value="5" />
|
||||
|
||||
<!-- Kafka Settings -->
|
||||
<entry key="KAFKA_ENABLED" value="true" />
|
||||
<entry key="KAFKA_BOOTSTRAP_SERVERS" value="4.230.50.63:9092" />
|
||||
<entry key="KAFKA_CONSUMER_GROUP_ID" value="analytics-service" />
|
||||
|
||||
<!-- Sample Data Settings (MVP Only) -->
|
||||
<!-- ⚠️ 실제 운영 환경에서는 false로 설정 (다른 서비스들이 이벤트 발행) -->
|
||||
<entry key="SAMPLE_DATA_ENABLED" value="true" />
|
||||
|
||||
<!-- JPA Settings -->
|
||||
<entry key="SHOW_SQL" value="true" />
|
||||
<entry key="DDL_AUTO" value="update" />
|
||||
|
||||
<!-- Server Settings -->
|
||||
<entry key="SERVER_PORT" value="8086" />
|
||||
|
||||
<!-- JWT Settings -->
|
||||
<entry key="JWT_SECRET" value="dev-jwt-secret-key-for-development-only-analytics-service-2024" />
|
||||
<entry key="JWT_ACCESS_TOKEN_VALIDITY" value="1800" />
|
||||
<entry key="JWT_REFRESH_TOKEN_VALIDITY" value="86400" />
|
||||
|
||||
<!-- CORS Settings -->
|
||||
<entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*" />
|
||||
|
||||
<!-- Logging Settings -->
|
||||
<entry key="LOG_LEVEL_APP" value="DEBUG" />
|
||||
<entry key="LOG_LEVEL_WEB" value="INFO" />
|
||||
<entry key="LOG_LEVEL_SQL" value="DEBUG" />
|
||||
<entry key="LOG_LEVEL_SQL_TYPE" value="TRACE" />
|
||||
<entry key="LOG_FILE" value="logs/analytics-service.log" />
|
||||
|
||||
<!-- Batch Settings -->
|
||||
<entry key="BATCH_ENABLED" value="true" />
|
||||
<entry key="BATCH_REFRESH_INTERVAL" value="300000" />
|
||||
<entry key="BATCH_INITIAL_DELAY" value="30000" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="executionName" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="externalSystemIdString" value="GRADLE" />
|
||||
<option name="scriptParameters" value="" />
|
||||
<option name="taskDescriptions">
|
||||
<list />
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="analytics-service:bootRun" />
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" />
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<EXTENSION ID="com.intellij.execution.ExternalSystemRunConfigurationJavaExtension">
|
||||
<extension name="net.ashald.envfile">
|
||||
<option name="IS_ENABLED" value="false" />
|
||||
<option name="IS_SUBST" value="false" />
|
||||
<option name="IS_PATH_MACRO_SUPPORTED" value="false" />
|
||||
<option name="IS_IGNORE_MISSING_FILES" value="false" />
|
||||
<option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
|
||||
<ENTRIES>
|
||||
<ENTRY IS_ENABLED="true" PARSER="runconfig" IS_EXECUTABLE="false" />
|
||||
</ENTRIES>
|
||||
</extension>
|
||||
</EXTENSION>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<RunAsTest>false</RunAsTest>
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,82 @@
|
||||
# 백엔드 컨테이너이미지 작성가이드
|
||||
|
||||
[요청사항]
|
||||
- 백엔드 각 서비스를의 컨테이너 이미지 생성
|
||||
- 실제 빌드 수행 및 검증까지 완료
|
||||
- '[결과파일]'에 수행한 명령어를 포함하여 컨테이너 이미지 작성 과정 생성
|
||||
|
||||
[작업순서]
|
||||
- 서비스명 확인
|
||||
서비스명은 settings.gradle에서 확인
|
||||
|
||||
예시) include 'common'하위의 4개가 서비스명임.
|
||||
```
|
||||
rootProject.name = 'tripgen'
|
||||
|
||||
include 'common'
|
||||
include 'user-service'
|
||||
include 'location-service'
|
||||
include 'ai-service'
|
||||
include 'trip-service'
|
||||
```
|
||||
|
||||
- 실행Jar 파일 설정
|
||||
실행Jar 파일명을 서비스명과 일치하도록 build.gradle에 설정 합니다.
|
||||
```
|
||||
bootJar {
|
||||
archiveFileName = '{서비스명}.jar'
|
||||
}
|
||||
```
|
||||
|
||||
- Dockerfile 생성
|
||||
아래 내용으로 deployment/container/Dockerfile-backend 생성
|
||||
```
|
||||
# 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"]
|
||||
```
|
||||
|
||||
- 컨테이너 이미지 생성
|
||||
아래 명령으로 각 서비스 빌드. shell 파일을 생성하지 말고 command로 수행.
|
||||
서브에이젼트를 생성하여 병렬로 수행.
|
||||
```
|
||||
DOCKER_FILE=deployment/container/Dockerfile-backend
|
||||
service={서비스명}
|
||||
|
||||
docker build \
|
||||
--platform linux/amd64 \
|
||||
--build-arg BUILD_LIB_DIR="${서비스명}/build/libs" \
|
||||
--build-arg ARTIFACTORY_FILE="${서비스명}.jar" \
|
||||
-f ${DOCKER_FILE} \
|
||||
-t ${서비스명}:latest .
|
||||
```
|
||||
- 생성된 이미지 확인
|
||||
아래 명령으로 모든 서비스의 이미지가 빌드되었는지 확인
|
||||
```
|
||||
docker images | grep {서비스명}
|
||||
```
|
||||
|
||||
[결과파일]
|
||||
deployment/container/build-image.md
|
||||
@@ -0,0 +1,220 @@
|
||||
# 설계 프롬프트
|
||||
아래 순서대로 설계합니다.
|
||||
|
||||
## UI/UX 설계
|
||||
command: "/design-uiux"
|
||||
prompt:
|
||||
```
|
||||
@uiux
|
||||
UI/UX 설계를 해주세요:
|
||||
- 'UI/UX설계가이드'를 준용하여 작성
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
# 프로토타입 작성
|
||||
command: "/design-prototype"
|
||||
prompt:
|
||||
**1.작성**
|
||||
```
|
||||
@prototype
|
||||
프로토타입을 작성해 주세요:
|
||||
- '프로토타입작성가이드'를 준용하여 작성
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**2.검증**
|
||||
command: "/design-test-prototype"
|
||||
prompt:
|
||||
```
|
||||
@test-front
|
||||
프로토타입을 테스트 해 주세요.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**3.오류수정**
|
||||
command: "/design-fix-prototype"
|
||||
prompt:
|
||||
```
|
||||
@fix as @front
|
||||
'[오류내용]'섹션에 제공된 오류를 해결해 주세요.
|
||||
프롬프트에 '[오류내용]'섹션이 없으면 수행 중단하고 안내 메시지 표시
|
||||
{안내메시지}
|
||||
'[오류내용]'섹션 하위에 오류 내용을 제공
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**4.개선**
|
||||
command: "/design-improve-prototype"
|
||||
prompt:
|
||||
```
|
||||
@improve as @front
|
||||
'[개선내용]'섹션에 있는 내용을 개선해 주세요.
|
||||
프롬프트에 '[개선내용]'항목이 없으면 수행을 중단하고 안내 메시지 표시
|
||||
{안내메시지}
|
||||
'[개선내용]'섹션 하위에 개선할 내용을 제공
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**5.유저스토리 품질 높이기**
|
||||
command: "/design-improve-userstory"
|
||||
prompt:
|
||||
```
|
||||
@analyze as @front 프로토타입을 웹브라우저에서 분석한 후,
|
||||
@document as @scribe 수정된 프로토타입에 따라 유저스토리를 업데이트 해주십시오.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**6.설계서 다시 업데이트**
|
||||
command: "/design-update-uiux"
|
||||
prompt:
|
||||
```
|
||||
@document @front
|
||||
현재 프로토타입과 유저스토리를 기준으로 UI/UX설계서와 스타일가이드를 수정해 주세요.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 클라우드 아키텍처 패턴 선정
|
||||
command: "/design-pattern"
|
||||
prompt:
|
||||
```
|
||||
@design-pattern
|
||||
클라우드 아키텍처 패턴 적용 방안을 작성해 주세요:
|
||||
- '클라우드아키텍처패턴선정가이드'를 준용하여 작성
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 논리아키텍처 설계
|
||||
command: "/design-logical"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
논리 아키텍처를 설계해 주세요:
|
||||
- '공통설계원칙'과 '논리아키텍처 설계 가이드'를 준용하여 설계
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 외부 시퀀스 설계
|
||||
command: "/design-seq-outer"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
외부 시퀀스 설계를 해 주세요:
|
||||
- '공통설계원칙'과 '외부시퀀스설계가이드'를 준용하여 설계
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 내부 시퀀스 설계
|
||||
command: "/design-seq-inner"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
내부 시퀀스 설계를 해 주세요:
|
||||
- '공통설계원칙'과 '내부시퀀스설계 가이드'를 준용하여 설계
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 설계
|
||||
command: "/design-api"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
API를 설계해 주세요:
|
||||
- '공통설계원칙'과 'API설계가이드'를 준용하여 설계
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 클래스 설계
|
||||
command: "/design-class"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
'공통설계원칙'과 '클래스설계가이드'를 준용하여 클래스를 설계해 주세요.
|
||||
프롬프트에 '[클래스설계 정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
{안내메시지}
|
||||
'[클래스설계 정보]' 섹션에 아래 예와 같은 정보를 제공해 주십시오.
|
||||
[클래스설계 정보]
|
||||
- 패키지 그룹: com.unicorn.tripgen
|
||||
- 설계 아키텍처 패턴
|
||||
- User: Layered
|
||||
- Trip: Clean
|
||||
- Location: Layered
|
||||
- AI: Layered
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 데이터 설계
|
||||
command: "/design-data"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
데이터 설계를 해주세요:
|
||||
- '공통설계원칙'과 '데이터설계가이드'를 준용하여 설계
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## High Level 아키텍처 정의서 작성
|
||||
command: "/design-high-level"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
'HighLevel아키텍처정의가이드'를 준용하여 High Level 아키텍처 정의서를 작성해 주세요.
|
||||
'CLOUD' 정보가 없으면 수행을 중단하고 안내메시지를 표시하세요.
|
||||
{안내메시지}
|
||||
아래 예와 같이 CLOUD 제공자를 Azure, AWS, Google과 같이 제공하세요.
|
||||
- CLOUD: Azure
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 물리 아키텍처 설계
|
||||
command: "/design-physical"
|
||||
prompt:
|
||||
```
|
||||
@architecture
|
||||
'물리아키텍처설계가이드'를 준용하여 물리아키텍처를 설계해 주세요.
|
||||
'CLOUD' 정보가 없으면 수행을 중단하고 안내메시지를 표시하세요.
|
||||
{안내메시지}
|
||||
아래 예와 같이 CLOUD 제공자를 Azure, AWS, Google과 같이 제공하세요.
|
||||
- CLOUD: Azure
|
||||
```
|
||||
|
||||
## 프론트엔드 설계
|
||||
command: "/design-front"
|
||||
prompt:
|
||||
```
|
||||
@plan as @front
|
||||
'프론트엔드설계가이드'를 준용하여 **프론트엔드설계서**를 작성해 주세요.
|
||||
프롬프트에 '[백엔드시스템]'항목이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
{안내메시지}
|
||||
'[백엔드시스템]' 섹션에 아래 예와 같은 정보를 제공해 주십시오.
|
||||
[백엔드시스템]
|
||||
- 시스템: tripgen
|
||||
- 마이크로서비스: user-service, location-service, trip-service, ai-service
|
||||
- API문서
|
||||
- user service: http://localhost:8081/v3/api-docs
|
||||
- location service: http://localhost:8082/v3/api-docs
|
||||
- trip service: http://localhost:8083/v3/api-docs
|
||||
- ai service: http://localhost:8084/v3/api-docs
|
||||
[요구사항]
|
||||
- 각 화면에 Back 아이콘 버튼과 화면 타이틀 표시
|
||||
- 하단 네비게이션 바 아이콘화: 홈, 새여행, 주변장소검색, 여행보기
|
||||
```
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
# 개발 프롬프트
|
||||
|
||||
## 데이터베이스 설치계획서 작성 요청
|
||||
command: "/develop-db-guide"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
"데이터베이스설치계획서가이드"에 따라 데이터베이스 설치계획서를 작성해 주십시오.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 데이터베이스 설치 수행 요청
|
||||
command: "/develop-db-install"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
[요구사항]
|
||||
'데이터베이스설치가이드'에 따라 설치해 주세요.
|
||||
'[설치정보]'섹션이 없으면 수행을 중단하고 안내 메시지를 표시하세요.
|
||||
{안내메시지}
|
||||
'[설치정보]'섹션 하위에 아래 예와 같이 설치에 필요한 정보를 추가해 주세요.
|
||||
- 설치대상환경: 개발환경
|
||||
- AKS Resource Group: rg-digitalgarage-01
|
||||
- AKS Name: aks-digitalgarage-01
|
||||
- Namespace: tripgen-dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 데이터베이스 설치 제거 요청 (필요시)
|
||||
command: "/develop-db-remove"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
[요구사항]
|
||||
- "데이터베이스설치결과서"를 보고 관련된 모든 리소스를 삭제
|
||||
- "캐시설치결과서"를 보고 관련된 모든 리소스를 삭제
|
||||
- 현재 OS에 맞게 수행
|
||||
- 서브 에이젼트를 병렬로 수행하여 삭제
|
||||
- 결과파일은 생성할 필요 없고 화면에만 결과 표시
|
||||
[참고자료]
|
||||
- 데이터베이스설치결과서
|
||||
- 캐시설치결과서
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Message Queue 설치 계획서 작성 요청
|
||||
command: "/develop-mq-guide"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
"MQ설치게획서가이드"에 따라 Message Queue 설치계획서를 작성해 주세요.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Message Queue 설치 수행 요청(필요시)
|
||||
command: "/develop-mq-install"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
[요구사항]
|
||||
'MQ설치가이드'에 따라 설치해 주세요.
|
||||
'[설치정보]'섹션이 없으면 수행을 중단하고 안내 메시지를 표시하세요.
|
||||
{안내메시지}
|
||||
'[설치정보]'섹션 하위에 아래 예와 같이 설치에 필요한 정보를 추가해 주세요.
|
||||
- 설치대상환경: 개발환경
|
||||
- Resource Group: rg-digitalgarage-01
|
||||
- Namespace: tripgen-dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Message Queue 설치 제거 요청
|
||||
command: "/develop-mq-remove"
|
||||
prompt:
|
||||
```
|
||||
@backing-service
|
||||
[요구사항]
|
||||
- "MQ설치결과서"를 보고 관련된 모든 리소스를 삭제
|
||||
- 현재 OS에 맞게 수행
|
||||
- 서브 에이젼트를 병렬로 수행하여 삭제
|
||||
- 결과파일은 생성할 필요 없고 화면에만 결과 표시
|
||||
[참고자료]
|
||||
- MQ설치결과서
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 백엔드 개발 요청
|
||||
command: "/develop-dev-backend"
|
||||
prompt:
|
||||
```
|
||||
@dev-backend
|
||||
"백엔드개발가이드"에 따라 개발해 주세요.
|
||||
프롬프트에 '[개발정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
{안내메시지}
|
||||
[개발정보]
|
||||
- 개발 아키텍처패턴
|
||||
- auth: Layered
|
||||
- bill-inquiry: Clean
|
||||
- product-change: Layered
|
||||
- kos-mock: Layered
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 백엔드 오류 해결 요청
|
||||
command: "/develop-fix-backend"
|
||||
prompt:
|
||||
```
|
||||
@fix as @back
|
||||
개발된 각 서비스와 common 모듈을 컴파일하고 에러를 해결해 주세요.
|
||||
- common 모듈 우선 수행
|
||||
- 각 서비스별로 서브 에이젠트를 병렬로 수행
|
||||
- 컴파일이 모두 성공할때까지 계속 수행
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 서비스 실행파일 작성 요청
|
||||
command: "/develop-make-run-profile"
|
||||
prompt:
|
||||
```
|
||||
@test-backend
|
||||
'서비스실행파일작성가이드'에 따라 테스트를 해 주세요.
|
||||
프롬프트에 '[작성정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
DB나 Redis의 접근 정보는 지정할 필요 없습니다. 특별히 없으면 '[작성정보]'섹션에 '없음'이라고 하세요.
|
||||
{안내메시지}
|
||||
[작성정보]
|
||||
- API Key
|
||||
- Claude: sk-ant-ap...
|
||||
- OpenAI: sk-proj-An4Q...
|
||||
- Open Weather Map: 1aa5b...
|
||||
- Kakao API Key: 5cdc24....
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 백엔드 테스트 요청
|
||||
command: "/develop-test-backend"
|
||||
prompt:
|
||||
```
|
||||
@test-backend
|
||||
'백엔드테스트가이드'에 따라 테스트를 해 주세요.
|
||||
프롬프트에 '[테스트정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
테스트 대상 서비스를 지정안하면 모든 서비스를 테스트 합니다.
|
||||
{안내메시지}
|
||||
'[테스트정보]'섹션 하위에 아래 예와 같이 테스트에 필요한 정보를 제시해 주세요.
|
||||
테스트 대상 서비스를 콤마로 구분하여 입력할 수 있으며 전체를 테스트 할 때는 '전체'라고 입력하세요.
|
||||
- 서비스: user-service
|
||||
- API Key
|
||||
- Claude: sk-ant-ap...
|
||||
- OpenAI: sk-proj-An4Q...
|
||||
- Open Weather Map: 1aa5b...
|
||||
- Kakao API Key: 5cdc24....
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 프론트엔드 개발 요청
|
||||
command: "/develop-dev-front"
|
||||
prompt:
|
||||
```
|
||||
@dev-front
|
||||
"프론트엔드개발가이드"에 따라 개발해 주세요.
|
||||
프롬프트에 '[개발정보]'항목이 없으면 수행을 중단하고 안내 메시지를 표시해 주세요.
|
||||
{안내메시지}
|
||||
'[개발정보]'섹션 하위에 아래 예와 같이 개발에 필요한 정보를 제시해 주세요.
|
||||
[개발정보]
|
||||
- 개발프레임워크: Typescript + React 18
|
||||
- UI프레임워크: MUI v5
|
||||
- 상태관리: Redux Toolkit
|
||||
- 라우팅: React Router v6
|
||||
- API통신: Axios
|
||||
- 스타일링: MUI + styled-components
|
||||
- 빌드도구: Vite
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
# 서비스 기획 프롬프트
|
||||
|
||||
## 서비스 기획
|
||||
command: "/think-planning"
|
||||
prompt:
|
||||
아래 내용을 터미널에 표시만 하고 수행을 하지는 않습니다.
|
||||
```
|
||||
아래 가이드를 참고하여 서비스 기획을 수행합니다.
|
||||
|
||||
https://github.com/cna-bootcamp/aiguide/blob/main/AI%ED%99%9C%EC%9A%A9%20%EC%84%9C%EB%B9%84%EC%8A%A4%20%EA%B8%B0%ED%9A%8D%20%EA%B0%80%EC%9D%B4%EB%93%9C.md
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 유저스토리 작성
|
||||
command: "/think-userstory"
|
||||
prompt:
|
||||
|
||||
```
|
||||
@document
|
||||
유저스토리를 작성하세요.
|
||||
프롬프트에 '[요구사항]'섹션이 없으면 수행을 중단하고 안내 메시지를 표시합니다.
|
||||
{안내메시지}
|
||||
'[요구사항]' 섹션에 아래 예와 같은 정보를 제공해 주십시오.
|
||||
[요구사항]
|
||||
Case 1) 이벤트스토밍을 피그마로 수행한 경우는 피그마 채널ID를 제공
|
||||
예) 피그마 채널ID 'abcde'에 접속하여 분석
|
||||
Case 2) 다른 방법으로 이벤트스토밍을 한 경우는 요구사항을 정리한 파일 경로를 제공
|
||||
예) 요구사항문서 'design/requirement.md'를 읽어 분석
|
||||
|
||||
프롬프트에 '[요구사항]'섹션이 있으면 아래와 같이 수행합니다.
|
||||
1. 요구사항 분석
|
||||
- 피그마 채널ID가 제공된 경우 figma MCP를 이용하여 해당 채널에 접속하여 분석
|
||||
- 요구사항문서 경로가 제공된 경우 해당 문서를 읽어 요구사항을 분석
|
||||
2. 유저스토리 작성
|
||||
- '유저스토리작성방법'과 '유저스토리예제'를 참고하여 유저스토리를 작성
|
||||
- 결과파일은 'design/userstory.md'에 생성
|
||||
|
||||
```
|
||||
|
||||
@@ -56,13 +56,14 @@ public class JwtTokenProvider {
|
||||
* @param roles 역할 목록
|
||||
* @return Access Token
|
||||
*/
|
||||
public String createAccessToken(UUID userId, UUID storeId, String email, String name, List<String> roles) {
|
||||
|
||||
public String createAccessToken(Long userId, Long storeId, String email, String name, List<String> roles) {
|
||||
Date now = new Date();
|
||||
Date expiryDate = new Date(now.getTime() + accessTokenValidityMs);
|
||||
|
||||
return Jwts.builder()
|
||||
.subject(userId.toString())
|
||||
.claim("storeId", storeId.toString())
|
||||
.claim("storeId", storeId != null ? storeId.toString() : null)
|
||||
.claim("email", email)
|
||||
.claim("name", name)
|
||||
.claim("roles", roles)
|
||||
@@ -112,8 +113,9 @@ public class JwtTokenProvider {
|
||||
public UserPrincipal getUserPrincipalFromToken(String token) {
|
||||
Claims claims = parseToken(token);
|
||||
|
||||
UUID userId = UUID.fromString(claims.getSubject());
|
||||
UUID storeId = UUID.fromString(claims.get("storeId", String.class));
|
||||
Long userId = Long.parseLong(claims.getSubject());
|
||||
String storeIdStr = claims.get("storeId", String.class);
|
||||
Long storeId = storeIdStr != null ? Long.parseLong(storeIdStr) : null;
|
||||
String email = claims.get("email", String.class);
|
||||
String name = claims.get("name", String.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
|
||||
@@ -31,6 +31,11 @@ public class UserPrincipal implements UserDetails {
|
||||
*/
|
||||
private final UUID storeId;
|
||||
|
||||
/**
|
||||
* 매장 ID
|
||||
*/
|
||||
private final Long storeId;
|
||||
|
||||
/**
|
||||
* 사용자 이메일
|
||||
*/
|
||||
|
||||
+155
-304
@@ -1,118 +1,40 @@
|
||||
# 백엔드 컨테이너 이미지 작성 결과
|
||||
# 백엔드 컨테이너 이미지 빌드 결과
|
||||
|
||||
작성일: 2025-10-27
|
||||
작성자: DevOps Engineer
|
||||
## 프로젝트 정보
|
||||
- **프로젝트명**: kt-event-marketing
|
||||
- **빌드 일시**: 2025-10-27
|
||||
- **빌드 대상**: 3개 마이크로서비스 (content-service, participation-service, user-service)
|
||||
|
||||
## 1. 개요
|
||||
## 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`에 이미 설정되어 있음:
|
||||
### 1.1 서비스 확인
|
||||
settings.gradle에서 확인된 구현 완료 서비스:
|
||||
- ✅ content-service
|
||||
- ✅ participation-service
|
||||
- ✅ user-service
|
||||
- ⏳ ai-service (미구현)
|
||||
- ⏳ analytics-service (미구현)
|
||||
- ⏳ distribution-service (미구현)
|
||||
- ⏳ event-service (미구현)
|
||||
|
||||
### 1.2 bootJar 설정 확인
|
||||
build.gradle에 이미 설정되어 있음 (line 101-103):
|
||||
```gradle
|
||||
// Configure bootJar task for each service
|
||||
bootJar {
|
||||
archiveFileName = "${project.name}.jar"
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 JAR 빌드 실행
|
||||
|
||||
#### gradlew 실행 권한 설정 (최초 1회)
|
||||
|
||||
VM 환경에서 실행 시 권한 오류가 발생할 수 있으므로 먼저 실행 권한을 부여합니다:
|
||||
## 2. Dockerfile 생성
|
||||
|
||||
### 2.1 디렉토리 생성
|
||||
```bash
|
||||
chmod +x gradlew
|
||||
mkdir -p deployment/container
|
||||
```
|
||||
|
||||
#### 빌드 명령어 실행
|
||||
### 2.2 Dockerfile-backend 작성
|
||||
파일 위치: `deployment/container/Dockerfile-backend`
|
||||
|
||||
**명령어**:
|
||||
```bash
|
||||
./gradlew :analytics-service:bootJar :content-service:bootJar :event-service:bootJar :participation-service:bootJar :user-service:bootJar --no-daemon
|
||||
```
|
||||
|
||||
**권한 오류 발생 시 대체 방법**:
|
||||
```bash
|
||||
# gradlew에 실행 권한이 없는 경우
|
||||
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<String>
|
||||
found: Long,String,String,List<String>
|
||||
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
|
||||
@@ -141,241 +63,170 @@ ENTRYPOINT [ "sh", "-c" ]
|
||||
CMD ["java ${JAVA_OPTS} -jar app.jar"]
|
||||
```
|
||||
|
||||
**특징**:
|
||||
- Multi-stage build (빌드 단계와 실행 단계 분리)
|
||||
- OpenJDK 23 사용
|
||||
- 비root 사용자(k8s)로 실행하여 보안 강화
|
||||
- JAVA_OPTS 환경변수로 JVM 옵션 커스터마이징 가능
|
||||
- linux/amd64 플랫폼 지원
|
||||
**주요 특징**:
|
||||
- Multi-stage build로 이미지 크기 최적화
|
||||
- Non-root user(k8s) 생성으로 보안 강화
|
||||
- JAVA_OPTS 환경 변수로 JVM 옵션 설정 가능
|
||||
|
||||
## 5. 컨테이너 이미지 빌드
|
||||
## 3. JAR 파일 빌드
|
||||
|
||||
### 5.1 사전 조건
|
||||
|
||||
⚠️ **Docker Desktop 실행 필요**
|
||||
|
||||
이미지 빌드 전에 Docker Desktop이 실행되어 있어야 합니다:
|
||||
|
||||
1. Windows에서 Docker Desktop 실행
|
||||
2. 시스템 트레이에서 "Docker Desktop is running" 확인
|
||||
3. 확인 명령어: `docker ps`
|
||||
|
||||
### 5.2 빌드 명령어
|
||||
|
||||
#### analytics-service
|
||||
### 3.1 빌드 명령어
|
||||
```bash
|
||||
./gradlew :content-service:bootJar :participation-service:bootJar :user-service:bootJar
|
||||
```
|
||||
|
||||
### 3.2 빌드 결과
|
||||
```
|
||||
BUILD SUCCESSFUL in 15s
|
||||
18 actionable tasks: 5 executed, 13 up-to-date
|
||||
```
|
||||
|
||||
### 3.3 생성된 JAR 파일
|
||||
```bash
|
||||
$ ls -lh */build/libs/*.jar
|
||||
|
||||
-rw-r--r-- 1 KTDS 197121 78M content-service/build/libs/content-service.jar
|
||||
-rw-r--r-- 1 KTDS 197121 85M participation-service/build/libs/participation-service.jar
|
||||
-rw-r--r-- 1 KTDS 197121 96M user-service/build/libs/user-service.jar
|
||||
```
|
||||
|
||||
## 4. Docker 이미지 빌드
|
||||
|
||||
### 4.1 content-service 이미지 빌드
|
||||
```bash
|
||||
DOCKER_FILE=deployment/container/Dockerfile-backend
|
||||
service=content-service
|
||||
|
||||
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 \
|
||||
-f ${DOCKER_FILE} \
|
||||
-t ${service}:latest .
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✅ $service build completed"
|
||||
else
|
||||
echo "❌ $service build failed"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
## 6. 이미지 확인
|
||||
|
||||
### 6.1 빌드된 이미지 목록 확인
|
||||
**빌드 결과**:
|
||||
- Image ID: 06af046cbebe
|
||||
- Size: 1.01GB
|
||||
- Platform: linux/amd64
|
||||
- Status: ✅ SUCCESS
|
||||
|
||||
### 4.2 participation-service 이미지 빌드
|
||||
```bash
|
||||
docker images | grep -E "analytics-service|content-service|event-service|participation-service"
|
||||
DOCKER_FILE=deployment/container/Dockerfile-backend
|
||||
service=participation-service
|
||||
|
||||
docker build \
|
||||
--platform linux/amd64 \
|
||||
--build-arg BUILD_LIB_DIR="${service}/build/libs" \
|
||||
--build-arg ARTIFACTORY_FILE="${service}.jar" \
|
||||
-f ${DOCKER_FILE} \
|
||||
-t ${service}:latest .
|
||||
```
|
||||
|
||||
**예상 출력**:
|
||||
```
|
||||
analytics-service latest <IMAGE_ID> <TIME> <SIZE>
|
||||
content-service latest <IMAGE_ID> <TIME> <SIZE>
|
||||
event-service latest <IMAGE_ID> <TIME> <SIZE>
|
||||
participation-service latest <IMAGE_ID> <TIME> <SIZE>
|
||||
```
|
||||
|
||||
### 6.2 개별 서비스 이미지 확인
|
||||
**빌드 결과**:
|
||||
- Image ID: 486f2c00811e
|
||||
- Size: 1.04GB
|
||||
- Platform: linux/amd64
|
||||
- Status: ✅ SUCCESS
|
||||
|
||||
### 4.3 user-service 이미지 빌드
|
||||
```bash
|
||||
# analytics-service
|
||||
docker images analytics-service:latest
|
||||
DOCKER_FILE=deployment/container/Dockerfile-backend
|
||||
service=user-service
|
||||
|
||||
# content-service
|
||||
docker images content-service:latest
|
||||
|
||||
# event-service
|
||||
docker images event-service:latest
|
||||
|
||||
# participation-service
|
||||
docker images participation-service:latest
|
||||
docker build \
|
||||
--platform linux/amd64 \
|
||||
--build-arg BUILD_LIB_DIR="${service}/build/libs" \
|
||||
--build-arg ARTIFACTORY_FILE="${service}.jar" \
|
||||
-f ${DOCKER_FILE} \
|
||||
-t ${service}:latest .
|
||||
```
|
||||
|
||||
### 6.3 이미지 상세 정보 확인
|
||||
**빌드 결과**:
|
||||
- Image ID: 7ef657c343dd
|
||||
- Size: 1.09GB
|
||||
- Platform: linux/amd64
|
||||
- Status: ✅ SUCCESS
|
||||
|
||||
## 5. 빌드 결과 확인
|
||||
|
||||
### 5.1 이미지 목록 조회
|
||||
```bash
|
||||
# 이미지 레이어 확인
|
||||
docker history <service-name>:latest
|
||||
$ docker images | grep -E "(content-service|participation-service|user-service)"
|
||||
|
||||
# 이미지 메타데이터 확인
|
||||
docker inspect <service-name>:latest
|
||||
participation-service latest 486f2c00811e 48 seconds ago 1.04GB
|
||||
user-service latest 7ef657c343dd 48 seconds ago 1.09GB
|
||||
content-service latest 06af046cbebe 48 seconds ago 1.01GB
|
||||
```
|
||||
|
||||
## 7. 테스트 실행
|
||||
### 5.2 빌드 요약
|
||||
| 서비스명 | Image ID | 크기 | 상태 |
|
||||
|---------|----------|------|------|
|
||||
| content-service | 06af046cbebe | 1.01GB | ✅ |
|
||||
| participation-service | 486f2c00811e | 1.04GB | ✅ |
|
||||
| user-service | 7ef657c343dd | 1.09GB | ✅ |
|
||||
|
||||
### 7.1 로컬에서 컨테이너 실행 테스트
|
||||
## 6. 다음 단계
|
||||
|
||||
### 6.1 컨테이너 실행 테스트
|
||||
각 서비스의 Docker 이미지를 컨테이너로 실행하여 동작 확인:
|
||||
```bash
|
||||
# analytics-service 실행 예시
|
||||
docker run -d \
|
||||
--name analytics-service-test \
|
||||
-p 8080:8080 \
|
||||
-e JAVA_OPTS="-Xms256m -Xmx512m" \
|
||||
-e SPRING_PROFILES_ACTIVE=dev \
|
||||
analytics-service:latest
|
||||
|
||||
# 로그 확인
|
||||
docker logs -f analytics-service-test
|
||||
|
||||
# 헬스체크
|
||||
curl http://localhost:8080/actuator/health
|
||||
|
||||
# 컨테이너 정리
|
||||
docker stop analytics-service-test
|
||||
docker rm analytics-service-test
|
||||
docker run -d -p 8080:8080 --name content-service content-service:latest
|
||||
docker run -d -p 8081:8081 --name participation-service participation-service:latest
|
||||
docker run -d -p 8082:8082 --name user-service user-service:latest
|
||||
```
|
||||
|
||||
### 6.2 컨테이너 레지스트리 푸시
|
||||
이미지를 Docker Hub 또는 프라이빗 레지스트리에 푸시:
|
||||
```bash
|
||||
# 이미지 태깅
|
||||
docker tag content-service:latest [registry]/content-service:1.0.0
|
||||
docker tag participation-service:latest [registry]/participation-service:1.0.0
|
||||
docker tag user-service:latest [registry]/user-service:1.0.0
|
||||
|
||||
# 레지스트리 푸시
|
||||
docker push [registry]/content-service:1.0.0
|
||||
docker push [registry]/participation-service:1.0.0
|
||||
docker push [registry]/user-service:1.0.0
|
||||
```
|
||||
|
||||
### 6.3 Kubernetes 배포
|
||||
Kubernetes 클러스터에 배포하기 위한 매니페스트 작성 및 적용
|
||||
|
||||
## 7. 참고 사항
|
||||
|
||||
### 7.1 보안 고려사항
|
||||
- ✅ Non-root user(k8s) 사용으로 보안 강화
|
||||
- ✅ Multi-stage build로 빌드 도구 제외
|
||||
- ⚠️ 프로덕션 환경에서는 이미지 스캔 권장
|
||||
|
||||
### 7.2 이미지 최적화
|
||||
- 현재 이미지 크기: ~1GB
|
||||
- JVM 튜닝 옵션 활용 가능: `JAVA_OPTS` 환경 변수
|
||||
- 추후 경량화 검토: Alpine 기반 이미지, jlink 활용
|
||||
|
||||
### 7.3 빌드 자동화
|
||||
향후 CI/CD 파이프라인에서 자동 빌드 통합 가능:
|
||||
- GitHub Actions
|
||||
- Jenkins
|
||||
- GitLab CI/CD
|
||||
- ArgoCD
|
||||
|
||||
## 8. 문제 해결
|
||||
|
||||
### 8.1 user-service 컴파일 에러
|
||||
### 8.1 빌드 실패 시
|
||||
- Gradle clean 실행 후 재빌드
|
||||
- Docker daemon 상태 확인
|
||||
- 디스크 공간 확인
|
||||
|
||||
**문제**: UUID와 Long 타입 불일치
|
||||
### 8.2 이미지 크기 문제
|
||||
- Multi-stage build 활용 (현재 적용됨)
|
||||
- .dockerignore 파일 활용
|
||||
- 불필요한 의존성 제거
|
||||
|
||||
**해결 방법**:
|
||||
1. `UserController.java`에서 `Long userId` → `UUID userId` 변경
|
||||
2. `AuthenticationServiceImpl.java`와 `UserServiceImpl.java`에서 `createAccessToken` 메서드 호출 시 첫 번째 파라미터로 `sessionId` 추가
|
||||
3. 변경 후 재빌드:
|
||||
```bash
|
||||
./gradlew :user-service:bootJar --no-daemon
|
||||
```
|
||||
---
|
||||
|
||||
### 8.2 ai-service 및 distribution-service
|
||||
|
||||
**문제**: 소스 코드 미구현
|
||||
|
||||
**조치**: 해당 서비스의 구현이 완료된 후 컨테이너 이미지 빌드 진행
|
||||
|
||||
### 8.3 Docker Desktop 연결 실패
|
||||
|
||||
**에러 메시지**:
|
||||
```
|
||||
error during connect: open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.
|
||||
```
|
||||
|
||||
**해결 방법**:
|
||||
1. Docker Desktop 실행
|
||||
2. 완전히 시작될 때까지 대기 (트레이 아이콘 확인)
|
||||
3. `docker ps` 명령으로 정상 동작 확인
|
||||
4. 빌드 명령 재실행
|
||||
|
||||
## 9. 다음 단계
|
||||
|
||||
1. ✅ **완료**: Dockerfile 작성 및 JAR 빌드
|
||||
2. ⏸️ **대기 중**: Docker Desktop 실행 후 이미지 빌드
|
||||
3. 📋 **예정**:
|
||||
- user-service 컴파일 에러 수정
|
||||
- ai-service 및 distribution-service 구현 완료 후 빌드
|
||||
- 이미지 레지스트리에 푸시 (ACR 등)
|
||||
- Kubernetes 배포 매니페스트 작성
|
||||
|
||||
## 10. 참고 자료
|
||||
|
||||
- Dockerfile: `deployment/container/Dockerfile-backend`
|
||||
- JAR 위치: `<service-name>/build/libs/<service-name>.jar`
|
||||
- 빌드 스크립트: 본 문서의 5.3 섹션 참조
|
||||
- OpenJDK 23 Documentation: https://openjdk.org/projects/jdk/23/
|
||||
**작성자**: DevOps Engineer (송근정)
|
||||
**작성일**: 2025-10-27
|
||||
**버전**: 1.0.0
|
||||
|
||||
@@ -0,0 +1,502 @@
|
||||
# 백엔드 컨테이너 실행 가이드
|
||||
|
||||
백엔드 서비스를 Azure VM에서 Docker 컨테이너로 실행하는 가이드를 제공합니다.
|
||||
|
||||
## 📋 목차
|
||||
|
||||
1. [사전 준비](#사전-준비)
|
||||
2. [컨테이너 이미지 확인](#컨테이너-이미지-확인)
|
||||
3. [컨테이너 실행](#컨테이너-실행)
|
||||
4. [컨테이너 관리](#컨테이너-관리)
|
||||
5. [문제 해결](#문제-해결)
|
||||
|
||||
---
|
||||
|
||||
## 사전 준비
|
||||
|
||||
### 1. VM 접속 정보
|
||||
```yaml
|
||||
ACR: acrdigitalgarage01
|
||||
VM:
|
||||
KEY파일: ~/home/bastion-dg0505
|
||||
사용자: azureuser
|
||||
IP: 20.196.65.160
|
||||
```
|
||||
|
||||
### 2. VM 접속
|
||||
```bash
|
||||
# SSH 접속
|
||||
ssh -i ~/home/bastion-dg0505 azureuser@20.196.65.160
|
||||
```
|
||||
|
||||
### 3. Docker 및 ACR 로그인 확인
|
||||
```bash
|
||||
# Docker 실행 확인
|
||||
docker --version
|
||||
|
||||
# ACR 로그인 (필요시)
|
||||
az acr login --name acrdigitalgarage01
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 컨테이너 이미지 확인
|
||||
|
||||
### 1. ACR에서 이미지 목록 조회
|
||||
```bash
|
||||
# 이미지 목록 확인
|
||||
az acr repository list --name acrdigitalgarage01 --output table
|
||||
|
||||
# 특정 이미지의 태그 확인
|
||||
az acr repository show-tags --name acrdigitalgarage01 \
|
||||
--repository {service-name} --output table
|
||||
```
|
||||
|
||||
### 2. 실행할 이미지 Pull
|
||||
```bash
|
||||
# 이미지 다운로드
|
||||
docker pull acrdigitalgarage01.azurecr.io/{service-name}:{tag}
|
||||
|
||||
# 예: participation-service
|
||||
docker pull acrdigitalgarage01.azurecr.io/participation-service:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 컨테이너 실행
|
||||
|
||||
### 1. 환경 변수 준비
|
||||
|
||||
각 서비스별 환경 변수를 확인하고 준비합니다.
|
||||
|
||||
```bash
|
||||
# .env 파일 생성 (예시)
|
||||
cat > ~/event-marketing.env << EOF
|
||||
# Database
|
||||
DB_HOST=your-db-host
|
||||
DB_PORT=5432
|
||||
DB_NAME=event_marketing
|
||||
DB_USERNAME=your-username
|
||||
DB_PASSWORD=your-password
|
||||
|
||||
# Redis
|
||||
REDIS_HOST=your-redis-host
|
||||
REDIS_PORT=6379
|
||||
|
||||
# Kafka
|
||||
KAFKA_BOOTSTRAP_SERVERS=your-kafka:9092
|
||||
|
||||
# Application
|
||||
SERVER_PORT=8080
|
||||
SPRING_PROFILES_ACTIVE=prod
|
||||
EOF
|
||||
```
|
||||
|
||||
### 2. 네트워크 생성 (선택사항)
|
||||
|
||||
여러 컨테이너를 함께 실행할 경우 네트워크를 생성합니다.
|
||||
|
||||
```bash
|
||||
# Docker 네트워크 생성
|
||||
docker network create event-marketing-network
|
||||
```
|
||||
|
||||
### 3. 컨테이너 실행
|
||||
|
||||
#### 기본 실행
|
||||
```bash
|
||||
docker run -d \
|
||||
--name {service-name} \
|
||||
--env-file ~/event-marketing.env \
|
||||
-p 8080:8080 \
|
||||
acrdigitalgarage01.azurecr.io/{service-name}:latest
|
||||
```
|
||||
|
||||
#### 네트워크 포함 실행
|
||||
```bash
|
||||
docker run -d \
|
||||
--name {service-name} \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-p 8080:8080 \
|
||||
acrdigitalgarage01.azurecr.io/{service-name}:latest
|
||||
```
|
||||
|
||||
#### 볼륨 마운트 포함 실행
|
||||
```bash
|
||||
docker run -d \
|
||||
--name {service-name} \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-p 8080:8080 \
|
||||
-v ~/logs/{service-name}:/app/logs \
|
||||
acrdigitalgarage01.azurecr.io/{service-name}:latest
|
||||
```
|
||||
|
||||
### 4. 여러 서비스 실행 (docker-compose 사용)
|
||||
|
||||
`docker-compose.yml` 파일 생성:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
participation-service:
|
||||
image: acrdigitalgarage01.azurecr.io/participation-service:latest
|
||||
container_name: participation-service
|
||||
env_file:
|
||||
- ./event-marketing.env
|
||||
ports:
|
||||
- "8080:8080"
|
||||
networks:
|
||||
- event-marketing-network
|
||||
volumes:
|
||||
- ./logs/participation:/app/logs
|
||||
restart: unless-stopped
|
||||
|
||||
# 다른 서비스 추가...
|
||||
|
||||
networks:
|
||||
event-marketing-network:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
logs:
|
||||
```
|
||||
|
||||
실행:
|
||||
```bash
|
||||
# docker-compose로 모든 서비스 시작
|
||||
docker-compose up -d
|
||||
|
||||
# 특정 서비스만 시작
|
||||
docker-compose up -d participation-service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 컨테이너 관리
|
||||
|
||||
### 1. 컨테이너 상태 확인
|
||||
```bash
|
||||
# 실행 중인 컨테이너 확인
|
||||
docker ps
|
||||
|
||||
# 모든 컨테이너 확인 (중지된 것 포함)
|
||||
docker ps -a
|
||||
|
||||
# 특정 컨테이너 상세 정보
|
||||
docker inspect {container-name}
|
||||
```
|
||||
|
||||
### 2. 로그 확인
|
||||
```bash
|
||||
# 실시간 로그 확인
|
||||
docker logs -f {container-name}
|
||||
|
||||
# 최근 100줄 로그 확인
|
||||
docker logs --tail 100 {container-name}
|
||||
|
||||
# 타임스탬프 포함 로그 확인
|
||||
docker logs -t {container-name}
|
||||
```
|
||||
|
||||
### 3. 컨테이너 중지/시작/재시작
|
||||
```bash
|
||||
# 중지
|
||||
docker stop {container-name}
|
||||
|
||||
# 시작
|
||||
docker start {container-name}
|
||||
|
||||
# 재시작
|
||||
docker restart {container-name}
|
||||
|
||||
# 강제 중지
|
||||
docker kill {container-name}
|
||||
```
|
||||
|
||||
### 4. 컨테이너 삭제
|
||||
```bash
|
||||
# 중지된 컨테이너 삭제
|
||||
docker rm {container-name}
|
||||
|
||||
# 실행 중인 컨테이너 강제 삭제
|
||||
docker rm -f {container-name}
|
||||
|
||||
# 중지된 모든 컨테이너 삭제
|
||||
docker container prune
|
||||
```
|
||||
|
||||
### 5. 컨테이너 내부 접속
|
||||
```bash
|
||||
# bash 쉘로 접속
|
||||
docker exec -it {container-name} bash
|
||||
|
||||
# 특정 명령 실행
|
||||
docker exec {container-name} ls -la /app
|
||||
```
|
||||
|
||||
### 6. 리소스 사용량 확인
|
||||
```bash
|
||||
# 실시간 리소스 사용량
|
||||
docker stats
|
||||
|
||||
# 특정 컨테이너의 리소스 사용량
|
||||
docker stats {container-name}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 1. 컨테이너가 시작되지 않는 경우
|
||||
|
||||
```bash
|
||||
# 로그 확인
|
||||
docker logs {container-name}
|
||||
|
||||
# 컨테이너 상태 확인
|
||||
docker inspect {container-name}
|
||||
|
||||
# 환경 변수 확인
|
||||
docker exec {container-name} env
|
||||
```
|
||||
|
||||
### 2. 포트 충돌
|
||||
|
||||
```bash
|
||||
# 포트 사용 확인
|
||||
netstat -tuln | grep {port}
|
||||
|
||||
# 다른 포트로 매핑
|
||||
docker run -d -p 8081:8080 ...
|
||||
```
|
||||
|
||||
### 3. 네트워크 연결 문제
|
||||
|
||||
```bash
|
||||
# 네트워크 목록 확인
|
||||
docker network ls
|
||||
|
||||
# 네트워크 상세 정보
|
||||
docker network inspect {network-name}
|
||||
|
||||
# 컨테이너를 네트워크에 연결
|
||||
docker network connect {network-name} {container-name}
|
||||
```
|
||||
|
||||
### 4. 이미지 Pull 실패
|
||||
|
||||
```bash
|
||||
# ACR 로그인 재시도
|
||||
az acr login --name acrdigitalgarage01
|
||||
|
||||
# 수동으로 Pull
|
||||
docker pull acrdigitalgarage01.azurecr.io/{service-name}:{tag}
|
||||
```
|
||||
|
||||
### 5. 디스크 공간 부족
|
||||
|
||||
```bash
|
||||
# 사용하지 않는 이미지 삭제
|
||||
docker image prune -a
|
||||
|
||||
# 사용하지 않는 볼륨 삭제
|
||||
docker volume prune
|
||||
|
||||
# 전체 정리 (주의!)
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 헬스체크 및 모니터링
|
||||
|
||||
### 1. 헬스체크 엔드포인트 확인
|
||||
```bash
|
||||
# Spring Boot Actuator health endpoint
|
||||
curl http://localhost:8080/actuator/health
|
||||
|
||||
# 상세 헬스 정보
|
||||
curl http://localhost:8080/actuator/health/readiness
|
||||
curl http://localhost:8080/actuator/health/liveness
|
||||
```
|
||||
|
||||
### 2. 메트릭 확인
|
||||
```bash
|
||||
# 메트릭 엔드포인트
|
||||
curl http://localhost:8080/actuator/metrics
|
||||
|
||||
# 특정 메트릭 확인
|
||||
curl http://localhost:8080/actuator/metrics/jvm.memory.used
|
||||
```
|
||||
|
||||
### 3. 로그 모니터링 스크립트
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# monitor-logs.sh
|
||||
|
||||
SERVICE_NAME=$1
|
||||
if [ -z "$SERVICE_NAME" ]; then
|
||||
echo "Usage: ./monitor-logs.sh {service-name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 에러 로그 모니터링
|
||||
docker logs -f $SERVICE_NAME 2>&1 | grep -i error
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 자동화 스크립트
|
||||
|
||||
### 1. 서비스 재배포 스크립트
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# redeploy.sh
|
||||
|
||||
SERVICE_NAME=$1
|
||||
IMAGE_TAG=${2:-latest}
|
||||
|
||||
if [ -z "$SERVICE_NAME" ]; then
|
||||
echo "Usage: ./redeploy.sh {service-name} [tag]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "📦 Pulling latest image..."
|
||||
docker pull acrdigitalgarage01.azurecr.io/$SERVICE_NAME:$IMAGE_TAG
|
||||
|
||||
echo "🛑 Stopping old container..."
|
||||
docker stop $SERVICE_NAME
|
||||
docker rm $SERVICE_NAME
|
||||
|
||||
echo "🚀 Starting new container..."
|
||||
docker run -d \
|
||||
--name $SERVICE_NAME \
|
||||
--env-file ~/event-marketing.env \
|
||||
-p 8080:8080 \
|
||||
acrdigitalgarage01.azurecr.io/$SERVICE_NAME:$IMAGE_TAG
|
||||
|
||||
echo "✅ Deployment complete!"
|
||||
docker logs -f $SERVICE_NAME
|
||||
```
|
||||
|
||||
### 2. 헬스체크 스크립트
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# healthcheck.sh
|
||||
|
||||
SERVICE_NAME=$1
|
||||
MAX_RETRIES=30
|
||||
RETRY_INTERVAL=2
|
||||
|
||||
if [ -z "$SERVICE_NAME" ]; then
|
||||
echo "Usage: ./healthcheck.sh {service-name}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⏳ Waiting for $SERVICE_NAME to be healthy..."
|
||||
|
||||
for i in $(seq 1 $MAX_RETRIES); do
|
||||
if curl -f http://localhost:8080/actuator/health > /dev/null 2>&1; then
|
||||
echo "✅ $SERVICE_NAME is healthy!"
|
||||
exit 0
|
||||
fi
|
||||
echo "Attempt $i/$MAX_RETRIES failed. Retrying in ${RETRY_INTERVAL}s..."
|
||||
sleep $RETRY_INTERVAL
|
||||
done
|
||||
|
||||
echo "❌ $SERVICE_NAME failed to become healthy"
|
||||
exit 1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 보안 고려사항
|
||||
|
||||
### 1. 환경 변수 보호
|
||||
```bash
|
||||
# .env 파일 권한 설정
|
||||
chmod 600 ~/event-marketing.env
|
||||
|
||||
# 민감 정보는 Azure Key Vault 사용 권장
|
||||
```
|
||||
|
||||
### 2. 컨테이너 보안
|
||||
```bash
|
||||
# 읽기 전용 파일시스템으로 실행
|
||||
docker run -d --read-only ...
|
||||
|
||||
# 리소스 제한
|
||||
docker run -d \
|
||||
--memory="512m" \
|
||||
--cpus="0.5" \
|
||||
...
|
||||
```
|
||||
|
||||
### 3. 네트워크 보안
|
||||
```bash
|
||||
# 필요한 포트만 노출
|
||||
# 내부 통신은 Docker 네트워크 사용
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 서비스별 실행 예시
|
||||
|
||||
### Participation Service
|
||||
```bash
|
||||
docker run -d \
|
||||
--name participation-service \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-e SERVER_PORT=8080 \
|
||||
-e SPRING_PROFILES_ACTIVE=prod \
|
||||
-p 8080:8080 \
|
||||
-v ~/logs/participation:/app/logs \
|
||||
acrdigitalgarage01.azurecr.io/participation-service:latest
|
||||
```
|
||||
|
||||
### Event Service
|
||||
```bash
|
||||
docker run -d \
|
||||
--name event-service \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-e SERVER_PORT=8081 \
|
||||
-e SPRING_PROFILES_ACTIVE=prod \
|
||||
-p 8081:8081 \
|
||||
-v ~/logs/event:/app/logs \
|
||||
acrdigitalgarage01.azurecr.io/event-service:latest
|
||||
```
|
||||
|
||||
### User Service
|
||||
```bash
|
||||
docker run -d \
|
||||
--name user-service \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-e SERVER_PORT=8082 \
|
||||
-e SPRING_PROFILES_ACTIVE=prod \
|
||||
-p 8082:8082 \
|
||||
-v ~/logs/user:/app/logs \
|
||||
acrdigitalgarage01.azurecr.io/user-service:latest
|
||||
```
|
||||
|
||||
### Analytics Service
|
||||
```bash
|
||||
docker run -d \
|
||||
--name analytics-service \
|
||||
--network event-marketing-network \
|
||||
--env-file ~/event-marketing.env \
|
||||
-e SERVER_PORT=8083 \
|
||||
-e SPRING_PROFILES_ACTIVE=prod \
|
||||
-p 8083:8083 \
|
||||
-v ~/logs/analytics:/app/logs \
|
||||
acrdigitalgarage01.azurecr.io/analytics-service:latest
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
이 가이드를 통해 백엔드 서비스를 안전하고 효율적으로 컨테이너로 실행할 수 있습니다. 추가 질문이나 문제가 있으면 언제든지 문의해 주세요! 🚀
|
||||
@@ -1,526 +0,0 @@
|
||||
# 백엔드 컨테이너 실행 가이드
|
||||
|
||||
작성일: 2025-10-27
|
||||
작성자: DevOps Engineer
|
||||
|
||||
## 1. 개요
|
||||
|
||||
KT 이벤트 마케팅 플랫폼의 백엔드 마이크로서비스들을 Docker 컨테이너로 실행하는 방법을 안내합니다.
|
||||
|
||||
## 2. 실행 환경 정보
|
||||
|
||||
| 항목 | 값 |
|
||||
|------|-----|
|
||||
| **Azure Container Registry** | acrdigitalgarage01 |
|
||||
| **VM IP** | 4.218.10.89 |
|
||||
| **VM User ID** | azureuser |
|
||||
| **SSH Private Key** | ~/home/bastion-dg0502 |
|
||||
| **시스템명** | kt-event-marketing |
|
||||
|
||||
## 3. 빌드 가능한 서비스 목록
|
||||
|
||||
| 서비스명 | 포트 | 상태 | 비고 |
|
||||
|---------|------|------|------|
|
||||
| analytics-service | 8086 | ✅ 빌드 완료 | 컨테이너 이미지 생성됨 |
|
||||
| participation-service | 8084 | ⏸️ JAR 빌드 완료 | 컨테이너 이미지 생성 필요 |
|
||||
| event-service | 8080 | ⏸️ JAR 빌드 완료 | 컨테이너 이미지 생성 필요 |
|
||||
| content-service | 8083 | ⏸️ JAR 빌드 완료 | 컨테이너 이미지 생성 필요 |
|
||||
|
||||
## 4. VM 접속 방법
|
||||
|
||||
### 4.1 터미널 실행
|
||||
|
||||
- **Linux/Mac**: 기본 터미널 실행
|
||||
- **Windows**: Windows Terminal 실행
|
||||
|
||||
### 4.2 SSH Private Key 권한 설정 (최초 1회)
|
||||
|
||||
```bash
|
||||
chmod 400 ~/home/bastion-dg0502
|
||||
```
|
||||
|
||||
### 4.3 VM 접속
|
||||
|
||||
```bash
|
||||
ssh -i ~/home/bastion-dg0502 azureuser@4.218.10.89
|
||||
```
|
||||
|
||||
## 5. 작업 환경 준비
|
||||
|
||||
### 5.1 Workspace 디렉토리 생성
|
||||
|
||||
```bash
|
||||
mkdir -p ~/home/workspace
|
||||
cd ~/home/workspace
|
||||
```
|
||||
|
||||
### 5.2 Git Repository 클론
|
||||
|
||||
```bash
|
||||
git clone https://github.com/ktds-dg0501/kt-event-marketing.git
|
||||
```
|
||||
|
||||
**참고**: 실제 Git Repository 주소로 변경해 주세요.
|
||||
|
||||
### 5.3 프로젝트 디렉토리 이동
|
||||
|
||||
```bash
|
||||
cd kt-event-marketing
|
||||
```
|
||||
|
||||
## 6. 애플리케이션 빌드 및 컨테이너 이미지 생성
|
||||
|
||||
### 6.1 gradlew 실행 권한 설정 (최초 1회)
|
||||
|
||||
VM 환경에서는 gradlew 파일에 실행 권한이 없을 수 있습니다:
|
||||
|
||||
```bash
|
||||
chmod +x gradlew
|
||||
```
|
||||
|
||||
### 6.2 JAR 파일 빌드
|
||||
|
||||
```bash
|
||||
./gradlew :analytics-service:bootJar :content-service:bootJar :event-service:bootJar :participation-service:bootJar --no-daemon
|
||||
```
|
||||
|
||||
**권한 오류 발생 시**:
|
||||
```bash
|
||||
bash gradlew :analytics-service:bootJar :content-service:bootJar :event-service:bootJar :participation-service:bootJar --no-daemon
|
||||
```
|
||||
|
||||
### 6.3 Docker 이미지 생성
|
||||
|
||||
상세한 가이드는 `deployment/container/build-image.md` 파일을 참조하세요.
|
||||
|
||||
## 7. Azure Container Registry (ACR) 작업
|
||||
|
||||
### 7.1 ACR 인증 정보 확인
|
||||
|
||||
```bash
|
||||
az acr credential show --name acrdigitalgarage01
|
||||
```
|
||||
|
||||
**출력 예시**:
|
||||
```json
|
||||
{
|
||||
"passwords": [
|
||||
{
|
||||
"name": "password",
|
||||
"value": "<PASSWORD>"
|
||||
},
|
||||
{
|
||||
"name": "password2",
|
||||
"value": "<PASSWORD2>"
|
||||
}
|
||||
],
|
||||
"username": "acrdigitalgarage01"
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 ACR 로그인
|
||||
|
||||
위에서 확인한 `username`과 `passwords[0].value`를 사용하여 로그인합니다:
|
||||
|
||||
```bash
|
||||
docker login acrdigitalgarage01.azurecr.io -u acrdigitalgarage01 -p <PASSWORD>
|
||||
```
|
||||
|
||||
## 8. 컨테이너 이미지 푸시
|
||||
|
||||
### 8.1 analytics-service
|
||||
|
||||
```bash
|
||||
# 이미지 태그
|
||||
docker tag analytics-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
|
||||
# ACR로 푸시
|
||||
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
```
|
||||
|
||||
### 8.2 participation-service
|
||||
|
||||
```bash
|
||||
# 이미지 태그
|
||||
docker tag participation-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
|
||||
|
||||
# ACR로 푸시
|
||||
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
|
||||
```
|
||||
|
||||
### 8.3 event-service
|
||||
|
||||
```bash
|
||||
# 이미지 태그
|
||||
docker tag event-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
|
||||
|
||||
# ACR로 푸시
|
||||
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
|
||||
```
|
||||
|
||||
### 8.4 content-service
|
||||
|
||||
```bash
|
||||
# 이미지 태그
|
||||
docker tag content-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:latest
|
||||
|
||||
# ACR로 푸시
|
||||
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:latest
|
||||
```
|
||||
|
||||
## 9. 컨테이너 실행
|
||||
|
||||
### 9.1 analytics-service
|
||||
|
||||
```bash
|
||||
SERVER_PORT=8086
|
||||
|
||||
docker run -d --name analytics-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e DB_KIND=postgresql \
|
||||
-e DB_HOST=4.230.49.9 \
|
||||
-e DB_PORT=5432 \
|
||||
-e DB_NAME=analyticdb \
|
||||
-e DB_USERNAME=eventuser \
|
||||
-e DB_PASSWORD=Hi5Jessica! \
|
||||
-e DDL_AUTO=update \
|
||||
-e SHOW_SQL=true \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e REDIS_DATABASE=5 \
|
||||
-e KAFKA_ENABLED=true \
|
||||
-e KAFKA_BOOTSTRAP_SERVERS=20.249.182.13:9095,4.217.131.59:9095 \
|
||||
-e KAFKA_CONSUMER_GROUP_ID=analytics-service-consumers \
|
||||
-e SAMPLE_DATA_ENABLED=true \
|
||||
-e SERVER_PORT=8086 \
|
||||
-e JWT_SECRET=dev-jwt-secret-key-for-development-only-kt-event-marketing \
|
||||
-e JWT_ACCESS_TOKEN_VALIDITY=1800 \
|
||||
-e JWT_REFRESH_TOKEN_VALIDITY=86400 \
|
||||
-e CORS_ALLOWED_ORIGINS="http://localhost:*,http://4.218.10.89:3000" \
|
||||
-e LOG_FILE=logs/analytics-service.log \
|
||||
-e LOG_LEVEL_APP=DEBUG \
|
||||
-e LOG_LEVEL_WEB=INFO \
|
||||
-e LOG_LEVEL_SQL=DEBUG \
|
||||
-e LOG_LEVEL_SQL_TYPE=TRACE \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
```
|
||||
|
||||
### 9.2 participation-service
|
||||
|
||||
```bash
|
||||
SERVER_PORT=8084
|
||||
|
||||
docker run -d --name participation-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e DB_HOST=4.230.72.147 \
|
||||
-e DB_NAME=participationdb \
|
||||
-e DB_PASSWORD=Hi5Jessica! \
|
||||
-e DB_PORT=5432 \
|
||||
-e DB_USERNAME=eventuser \
|
||||
-e DDL_AUTO=validate \
|
||||
-e JWT_EXPIRATION=86400000 \
|
||||
-e JWT_SECRET=kt-event-marketing-secret-key-for-development-only-change-in-production \
|
||||
-e KAFKA_BOOTSTRAP_SERVERS=20.249.182.13:9095,4.217.131.59:9095 \
|
||||
-e LOG_FILE=logs/participation-service.log \
|
||||
-e LOG_LEVEL=INFO \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e SERVER_PORT=8084 \
|
||||
-e SHOW_SQL=true \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
|
||||
```
|
||||
|
||||
### 9.3 event-service
|
||||
|
||||
**참고**: event-service는 `.run.xml` 파일이 없어 환경변수 설정이 필요합니다.
|
||||
아래는 `application.yml`을 기반으로 추정한 환경변수입니다.
|
||||
|
||||
```bash
|
||||
SERVER_PORT=8080
|
||||
|
||||
docker run -d --name event-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e DB_HOST=<DB_HOST> \
|
||||
-e DB_PORT=5432 \
|
||||
-e DB_NAME=eventdb \
|
||||
-e DB_USERNAME=eventuser \
|
||||
-e DB_PASSWORD=<DB_PASSWORD> \
|
||||
-e DDL_AUTO=update \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e KAFKA_BOOTSTRAP_SERVERS=20.249.182.13:9095,4.217.131.59:9095 \
|
||||
-e SERVER_PORT=8080 \
|
||||
-e LOG_LEVEL=DEBUG \
|
||||
-e SQL_LOG_LEVEL=DEBUG \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
|
||||
```
|
||||
|
||||
⚠️ **필수**: `<DB_HOST>`와 `<DB_PASSWORD>`를 실제 값으로 변경해 주세요.
|
||||
|
||||
### 9.4 content-service
|
||||
|
||||
**참고**: content-service는 `.run.xml` 파일이 없어 환경변수 설정이 필요합니다.
|
||||
아래는 `application.yml`을 기반으로 추정한 환경변수입니다.
|
||||
|
||||
```bash
|
||||
SERVER_PORT=8083
|
||||
|
||||
docker run -d --name content-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e SERVER_PORT=8083 \
|
||||
-e JWT_SECRET=dev-jwt-secret-key \
|
||||
-e JWT_ACCESS_TOKEN_VALIDITY=3600000 \
|
||||
-e JWT_REFRESH_TOKEN_VALIDITY=604800000 \
|
||||
-e AZURE_STORAGE_CONNECTION_STRING=<AZURE_STORAGE_CONNECTION_STRING> \
|
||||
-e AZURE_CONTAINER_NAME=event-images \
|
||||
-e LOG_LEVEL_APP=DEBUG \
|
||||
-e LOG_LEVEL_ROOT=INFO \
|
||||
-e LOG_FILE=logs/content-service.log \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:latest
|
||||
```
|
||||
|
||||
⚠️ **필수**: `<AZURE_STORAGE_CONNECTION_STRING>`을 실제 값으로 변경해 주세요.
|
||||
|
||||
## 10. 실행 확인
|
||||
|
||||
### 10.1 컨테이너 실행 상태 확인
|
||||
|
||||
```bash
|
||||
# 전체 컨테이너 확인
|
||||
docker ps
|
||||
|
||||
# 특정 서비스 확인
|
||||
docker ps | grep analytics-service
|
||||
docker ps | grep participation-service
|
||||
docker ps | grep event-service
|
||||
docker ps | grep content-service
|
||||
```
|
||||
|
||||
### 10.2 컨테이너 로그 확인
|
||||
|
||||
```bash
|
||||
# 실시간 로그 확인
|
||||
docker logs -f analytics-service
|
||||
docker logs -f participation-service
|
||||
docker logs -f event-service
|
||||
docker logs -f content-service
|
||||
|
||||
# 최근 100줄 로그 확인
|
||||
docker logs --tail 100 analytics-service
|
||||
```
|
||||
|
||||
### 10.3 헬스체크
|
||||
|
||||
```bash
|
||||
# analytics-service
|
||||
curl http://4.218.10.89:8086/actuator/health
|
||||
|
||||
# participation-service
|
||||
curl http://4.218.10.89:8084/actuator/health
|
||||
|
||||
# event-service
|
||||
curl http://4.218.10.89:8080/actuator/health
|
||||
|
||||
# content-service
|
||||
curl http://4.218.10.89:8083/actuator/health
|
||||
```
|
||||
|
||||
## 11. 재배포 방법
|
||||
|
||||
### 11.1 로컬에서 수정된 소스 푸시
|
||||
|
||||
로컬 개발 환경에서 코드 수정 후:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "변경 사항"
|
||||
git push
|
||||
```
|
||||
|
||||
### 11.2 VM 접속
|
||||
|
||||
```bash
|
||||
ssh -i ~/home/bastion-dg0502 azureuser@4.218.10.89
|
||||
```
|
||||
|
||||
### 11.3 디렉토리 이동 및 소스 내려받기
|
||||
|
||||
```bash
|
||||
cd ~/home/workspace/kt-event-marketing
|
||||
git pull
|
||||
```
|
||||
|
||||
### 11.4 컨테이너 이미지 재생성
|
||||
|
||||
**JAR 파일 빌드**:
|
||||
```bash
|
||||
./gradlew :analytics-service:bootJar :content-service:bootJar :event-service:bootJar :participation-service:bootJar --no-daemon
|
||||
```
|
||||
|
||||
**Docker 이미지 빌드** (예: 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 .
|
||||
```
|
||||
|
||||
상세한 가이드는 `deployment/container/build-image.md` 파일을 참조하세요.
|
||||
|
||||
### 11.5 컨테이너 이미지 푸시
|
||||
|
||||
**analytics-service 예시**:
|
||||
```bash
|
||||
docker tag analytics-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
```
|
||||
|
||||
### 11.6 컨테이너 중지
|
||||
|
||||
```bash
|
||||
docker stop analytics-service
|
||||
docker stop participation-service
|
||||
docker stop event-service
|
||||
docker stop content-service
|
||||
```
|
||||
|
||||
### 11.7 컨테이너 이미지 삭제 (선택사항)
|
||||
|
||||
```bash
|
||||
docker rmi acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
docker rmi acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
|
||||
docker rmi acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
|
||||
docker rmi acrdigitalgarage01.azurecr.io/kt-event-marketing/content-service:latest
|
||||
```
|
||||
|
||||
### 11.8 컨테이너 재실행
|
||||
|
||||
위의 [9. 컨테이너 실행](#9-컨테이너-실행) 섹션의 명령어를 다시 실행합니다.
|
||||
|
||||
## 12. 일괄 실행 스크립트
|
||||
|
||||
### 12.1 전체 서비스 중지
|
||||
|
||||
```bash
|
||||
docker stop analytics-service participation-service event-service content-service
|
||||
```
|
||||
|
||||
### 12.2 전체 서비스 시작 (Bash 스크립트)
|
||||
|
||||
**실행 전 주의사항**:
|
||||
- event-service와 content-service의 환경변수 값을 실제 값으로 변경해야 합니다.
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# analytics-service 실행
|
||||
SERVER_PORT=8086
|
||||
docker run -d --name analytics-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e DB_KIND=postgresql \
|
||||
-e DB_HOST=4.230.49.9 \
|
||||
-e DB_PORT=5432 \
|
||||
-e DB_NAME=analyticdb \
|
||||
-e DB_USERNAME=eventuser \
|
||||
-e DB_PASSWORD=Hi5Jessica! \
|
||||
-e DDL_AUTO=update \
|
||||
-e SHOW_SQL=true \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e REDIS_DATABASE=5 \
|
||||
-e KAFKA_ENABLED=true \
|
||||
-e KAFKA_BOOTSTRAP_SERVERS=20.249.182.13:9095,4.217.131.59:9095 \
|
||||
-e KAFKA_CONSUMER_GROUP_ID=analytics-service-consumers \
|
||||
-e SAMPLE_DATA_ENABLED=true \
|
||||
-e SERVER_PORT=8086 \
|
||||
-e JWT_SECRET=dev-jwt-secret-key-for-development-only-kt-event-marketing \
|
||||
-e JWT_ACCESS_TOKEN_VALIDITY=1800 \
|
||||
-e JWT_REFRESH_TOKEN_VALIDITY=86400 \
|
||||
-e CORS_ALLOWED_ORIGINS="http://localhost:*,http://4.218.10.89:3000" \
|
||||
-e LOG_FILE=logs/analytics-service.log \
|
||||
-e LOG_LEVEL_APP=DEBUG \
|
||||
-e LOG_LEVEL_WEB=INFO \
|
||||
-e LOG_LEVEL_SQL=DEBUG \
|
||||
-e LOG_LEVEL_SQL_TYPE=TRACE \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/analytics-service:latest
|
||||
|
||||
echo "✅ analytics-service started on port 8086"
|
||||
|
||||
# participation-service 실행
|
||||
SERVER_PORT=8084
|
||||
docker run -d --name participation-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||
-e DB_HOST=4.230.72.147 \
|
||||
-e DB_NAME=participationdb \
|
||||
-e DB_PASSWORD=Hi5Jessica! \
|
||||
-e DB_PORT=5432 \
|
||||
-e DB_USERNAME=eventuser \
|
||||
-e DDL_AUTO=validate \
|
||||
-e JWT_EXPIRATION=86400000 \
|
||||
-e JWT_SECRET=kt-event-marketing-secret-key-for-development-only-change-in-production \
|
||||
-e KAFKA_BOOTSTRAP_SERVERS=20.249.182.13:9095,4.217.131.59:9095 \
|
||||
-e LOG_FILE=logs/participation-service.log \
|
||||
-e LOG_LEVEL=INFO \
|
||||
-e REDIS_HOST=20.214.210.71 \
|
||||
-e REDIS_PASSWORD=Hi5Jessica! \
|
||||
-e REDIS_PORT=6379 \
|
||||
-e SERVER_PORT=8084 \
|
||||
-e SHOW_SQL=true \
|
||||
acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
|
||||
|
||||
echo "✅ participation-service started on port 8084"
|
||||
|
||||
# 실행 확인
|
||||
echo ""
|
||||
echo "🔍 Running containers:"
|
||||
docker ps | grep -E "analytics-service|participation-service"
|
||||
```
|
||||
|
||||
## 13. 문제 해결
|
||||
|
||||
### 13.1 컨테이너가 즉시 종료되는 경우
|
||||
|
||||
**로그 확인**:
|
||||
```bash
|
||||
docker logs <container-name>
|
||||
```
|
||||
|
||||
**일반적인 원인**:
|
||||
- 환경변수 누락 또는 잘못된 값
|
||||
- 데이터베이스/Redis/Kafka 연결 실패
|
||||
- 포트 충돌
|
||||
|
||||
### 13.2 ACR 로그인 실패
|
||||
|
||||
**인증 정보 재확인**:
|
||||
```bash
|
||||
az acr credential show --name acrdigitalgarage01
|
||||
```
|
||||
|
||||
**다시 로그인**:
|
||||
```bash
|
||||
docker logout acrdigitalgarage01.azurecr.io
|
||||
docker login acrdigitalgarage01.azurecr.io -u <username> -p <password>
|
||||
```
|
||||
|
||||
### 13.3 포트 충돌
|
||||
|
||||
**포트 사용 확인**:
|
||||
```bash
|
||||
netstat -tuln | grep <PORT>
|
||||
```
|
||||
|
||||
**다른 포트로 변경**:
|
||||
```bash
|
||||
SERVER_PORT=<NEW_PORT>
|
||||
docker run -d -p ${SERVER_PORT}:${SERVER_PORT} ...
|
||||
```
|
||||
|
||||
## 14. 참고 자료
|
||||
|
||||
- 컨테이너 이미지 빌드 가이드: `deployment/container/build-image.md`
|
||||
- Docker 공식 문서: https://docs.docker.com/
|
||||
- Azure Container Registry 문서: https://docs.microsoft.com/azure/container-registry/
|
||||
+1
-1
@@ -14,7 +14,7 @@ import lombok.*;
|
||||
@Entity
|
||||
@Table(name = "draw_logs",
|
||||
indexes = {
|
||||
@Index(name = "idx_event_id", columnList = "event_id")
|
||||
@Index(name = "idx_draw_log_event_id", columnList = "event_id")
|
||||
}
|
||||
)
|
||||
@Getter
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ import lombok.*;
|
||||
@Entity
|
||||
@Table(name = "participants",
|
||||
indexes = {
|
||||
@Index(name = "idx_event_id", columnList = "event_id"),
|
||||
@Index(name = "idx_participant_event_id", columnList = "event_id"),
|
||||
@Index(name = "idx_event_phone", columnList = "event_id, phone_number")
|
||||
},
|
||||
uniqueConstraints = {
|
||||
|
||||
+2
@@ -24,6 +24,8 @@ public class SecurityConfig {
|
||||
.csrf(csrf -> csrf.disable())
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
// Actuator endpoints
|
||||
.requestMatchers("/actuator/**").permitAll()
|
||||
.anyRequest().permitAll()
|
||||
);
|
||||
|
||||
|
||||
@@ -73,3 +73,19 @@ logging:
|
||||
max-file-size: 10MB
|
||||
max-history: 7
|
||||
total-size-cap: 100MB
|
||||
# Actuator
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
base-path: /actuator
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
show-components: always
|
||||
health:
|
||||
livenessState:
|
||||
enabled: true
|
||||
readinessState:
|
||||
enabled: true
|
||||
+14
-4
@@ -5,8 +5,10 @@ import com.kt.event.common.security.JwtTokenProvider;
|
||||
import com.kt.event.user.dto.request.LoginRequest;
|
||||
import com.kt.event.user.dto.response.LoginResponse;
|
||||
import com.kt.event.user.dto.response.LogoutResponse;
|
||||
import com.kt.event.user.entity.Store;
|
||||
import com.kt.event.user.entity.User;
|
||||
import com.kt.event.user.exception.UserErrorCode;
|
||||
import com.kt.event.user.repository.StoreRepository;
|
||||
import com.kt.event.user.repository.UserRepository;
|
||||
import com.kt.event.user.service.AuthenticationService;
|
||||
import com.kt.event.user.service.UserService;
|
||||
@@ -34,6 +36,7 @@ import java.util.concurrent.TimeUnit;
|
||||
public class AuthenticationServiceImpl implements AuthenticationService {
|
||||
|
||||
private final UserRepository userRepository;
|
||||
private final StoreRepository storeRepository;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
private final JwtTokenProvider jwtTokenProvider;
|
||||
private final UserService userService;
|
||||
@@ -42,10 +45,12 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
public AuthenticationServiceImpl(UserRepository userRepository,
|
||||
StoreRepository storeRepository,
|
||||
PasswordEncoder passwordEncoder,
|
||||
JwtTokenProvider jwtTokenProvider,
|
||||
UserService userService) {
|
||||
this.userRepository = userRepository;
|
||||
this.storeRepository = storeRepository;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
this.jwtTokenProvider = jwtTokenProvider;
|
||||
this.userService = userService;
|
||||
@@ -68,21 +73,26 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
||||
throw new BusinessException(UserErrorCode.AUTH_FAILED.getErrorCode());
|
||||
}
|
||||
|
||||
// 3. JWT 토큰 생성
|
||||
// 3. 매장 정보 조회
|
||||
Store store = storeRepository.findByUserId(user.getId()).orElse(null);
|
||||
Long storeId = store != null ? store.getId() : null;
|
||||
|
||||
// 4. JWT 토큰 생성
|
||||
String token = jwtTokenProvider.createAccessToken(
|
||||
user.getId(),
|
||||
storeId,
|
||||
user.getEmail(),
|
||||
user.getName(),
|
||||
List.of(user.getRole().name())
|
||||
);
|
||||
|
||||
// 4. Redis 세션 저장 (TTL 7일)
|
||||
// 5. Redis 세션 저장 (TTL 7일)
|
||||
saveSession(token, user.getId(), user.getRole().name());
|
||||
|
||||
// 5. 최종 로그인 시각 업데이트 (비동기)
|
||||
// 6. 최종 로그인 시각 업데이트 (비동기)
|
||||
userService.updateLastLoginAt(user.getId());
|
||||
|
||||
// 6. 응답 반환
|
||||
// 7. 응답 반환
|
||||
return LoginResponse.builder()
|
||||
.token(token)
|
||||
.userId(user.getId())
|
||||
|
||||
@@ -103,6 +103,7 @@ public class UserServiceImpl implements UserService {
|
||||
// 6. JWT 토큰 생성
|
||||
String token = jwtTokenProvider.createAccessToken(
|
||||
savedUser.getId(),
|
||||
savedStore.getId(),
|
||||
savedUser.getEmail(),
|
||||
savedUser.getName(),
|
||||
List.of(savedUser.getRole().name())
|
||||
|
||||
Reference in New Issue
Block a user