백엔드 서비스 설정 및 배포 구성 개선

- CORS 설정 업데이트 (모든 서비스)
- Swagger UI 경로 및 설정 수정
- Kubernetes 배포 설정 개선 (Ingress, Deployment)
- distribution-service SecurityConfig 및 Controller 개선
- IntelliJ 실행 프로파일 업데이트
- 컨테이너 이미지 빌드 문서화 (deployment/container/build-image.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
wonho 2025-10-29 15:55:30 +09:00
parent 3075a5d49f
commit 3da9303091
16 changed files with 235 additions and 292 deletions

View File

@ -41,21 +41,21 @@ spec:
memory: "1024Mi" memory: "1024Mi"
startupProbe: startupProbe:
httpGet: httpGet:
path: /actuator/health path: /api/v1/distribution/actuator/health
port: 8085 port: 8085
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
failureThreshold: 30 failureThreshold: 30
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /actuator/health/readiness path: /api/v1/distribution/actuator/health/readiness
port: 8085 port: 8085
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 5 periodSeconds: 5
failureThreshold: 3 failureThreshold: 3
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /actuator/health/liveness path: /api/v1/distribution/actuator/health/liveness
port: 8085 port: 8085
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10

View File

@ -39,7 +39,7 @@
<entry key="JWT_REFRESH_TOKEN_VALIDITY" value="86400" /> <entry key="JWT_REFRESH_TOKEN_VALIDITY" value="86400" />
<!-- CORS Configuration --> <!-- CORS Configuration -->
<entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*" /> <entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*,http://*.nip.io:*" />
<!-- Logging Configuration --> <!-- Logging Configuration -->
<entry key="LOG_FILE" value="logs/analytics-service.log" /> <entry key="LOG_FILE" value="logs/analytics-service.log" />

View File

@ -84,7 +84,11 @@ jwt:
# CORS Configuration # CORS Configuration
cors: cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:*} allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}
# Actuator # Actuator
management: management:

View File

@ -40,7 +40,11 @@ replicate:
# CORS Configuration # CORS Configuration
cors: cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:*} allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}
# Actuator # Actuator
management: management:

View File

@ -1,68 +1,57 @@
# 백엔드 컨테이너 이미지 작성 결과 # 백엔드 컨테이너 이미지 빌드 결과
## 작업 개요 ## 개요
- **작업일시**: 2025-10-29 KT 이벤트 마케팅 서비스의 백엔드 마이크로서비스들에 대한 컨테이너 이미지를 생성하였습니다.
- **작성자**: DevOps Engineer (송근정 "데브옵스 마스터")
- **대상 서비스**: 6개 백엔드 마이크로서비스
## 1. 서비스 확인 ## 작업 일시
- 날짜: 2025-10-29
- 빌드 환경: Windows (MINGW64_NT-10.0-19045)
### settings.gradle 분석 ## 서비스 목록 확인
```gradle
settings.gradle에서 확인한 서비스 목록:
```
rootProject.name = 'kt-event-marketing' rootProject.name = 'kt-event-marketing'
// Common module
include 'common' include 'common'
// Microservices
include 'user-service' include 'user-service'
include 'event-service' include 'event-service'
include 'ai-service' include 'ai-service'
include 'content-service'
include 'distribution-service' include 'distribution-service'
include 'participation-service' include 'participation-service'
include 'analytics-service' include 'analytics-service'
``` ```
### 빌드 가능한 서비스 (6개) **빌드 대상 서비스 (6개):**
Main Application 클래스가 존재하는 서비스: - user-service (Java/Spring Boot)
1. **user-service** - `UserServiceApplication.java` - event-service (Java/Spring Boot)
2. **event-service** - `EventServiceApplication.java` - ai-service (Java/Spring Boot)
3. **ai-service** - `AiServiceApplication.java` - distribution-service (Java/Spring Boot)
4. **content-service** - `ContentApplication.java` - participation-service (Java/Spring Boot)
5. **participation-service** - `ParticipationServiceApplication.java` - analytics-service (Java/Spring Boot)
6. **analytics-service** - `AnalyticsServiceApplication.java`
### 제외된 서비스 **제외 대상:**
- **distribution-service**: 소스 코드 미구현 상태 (src/main/java 디렉토리 없음) - common: 공통 라이브러리 모듈 (독립 실행 서비스 아님)
- content-service: Python 기반 서비스 (별도 빌드 필요)
## 2. bootJar 설정 ## bootJar 설정 확인
각 서비스의 `build.gradle`에 bootJar 설정 추가/수정: 모든 Java 서비스의 build.gradle에 bootJar 설정이 올바르게 구성되어 있음을 확인:
### 설정 추가된 서비스 (5개) | 서비스명 | JAR 파일명 | 경로 |
```gradle |---------|-----------|------|
bootJar { | user-service | user-service.jar | user-service/build/libs/user-service.jar |
archiveFileName = '{service-name}.jar' | event-service | event-service.jar | event-service/build/libs/event-service.jar |
} | ai-service | ai-service.jar | ai-service/build/libs/ai-service.jar |
``` | distribution-service | distribution-service.jar | distribution-service/build/libs/distribution-service.jar |
| participation-service | participation-service.jar | participation-service/build/libs/participation-service.jar |
| analytics-service | analytics-service.jar | analytics-service/build/libs/analytics-service.jar |
- user-service/build.gradle ## Dockerfile 생성
- ai-service/build.gradle
- distribution-service/build.gradle (향후 구현 대비)
- participation-service/build.gradle
- analytics-service/build.gradle
### 기존 설정 확인된 서비스 (2개) **파일 위치:** `deployment/container/Dockerfile-backend`
- event-service/build.gradle ✅
- content-service/build.gradle ✅
## 3. Dockerfile 생성 **Dockerfile 구성:**
### 파일 경로
`deployment/container/Dockerfile-backend`
### Dockerfile 내용
```dockerfile ```dockerfile
# Build stage # Build stage
FROM openjdk:23-oraclelinux8 AS builder FROM openjdk:23-oraclelinux8 AS builder
@ -91,58 +80,34 @@ ENTRYPOINT [ "sh", "-c" ]
CMD ["java ${JAVA_OPTS} -jar app.jar"] CMD ["java ${JAVA_OPTS} -jar app.jar"]
``` ```
### Dockerfile 특징 **주요 특징:**
- **Multi-stage build**: 빌드와 실행 스테이지 분리 - Multi-stage 빌드: 빌드 이미지와 런타임 이미지 분리
- **Non-root user**: 보안을 위한 k8s 사용자 실행 - Base Image: openjdk:23-slim (경량화)
- **플랫폼**: linux/amd64 (K8s 클러스터 호환) - 보안: 비root 사용자(k8s)로 실행
- **Java 버전**: OpenJDK 23 - 플랫폼: linux/amd64
## 4. JAR 파일 빌드 ## Gradle 빌드 실행
### 빌드 명령어 **실행 명령:**
```bash ```bash
./gradlew user-service:bootJar ai-service:bootJar event-service:bootJar \ ./gradlew clean build -x test
content-service:bootJar participation-service:bootJar analytics-service:bootJar
``` ```
### 빌드 결과 **빌드 결과:**
``` - 상태: ✅ BUILD SUCCESSFUL
BUILD SUCCESSFUL in 27s - 소요 시간: 33초
33 actionable tasks: 15 executed, 18 up-to-date - 실행된 태스크: 56개
```
### 생성된 JAR 파일 ## 컨테이너 이미지 빌드
```bash
$ ls -lh */build/libs/*.jar
-rw-r--r-- 1 KTDS 197121 94M 10월 29 09:49 ai-service/build/libs/ai-service.jar ### 병렬 빌드 전략
-rw-r--r-- 1 KTDS 197121 95M 10월 29 09:48 analytics-service/build/libs/analytics-service.jar 서브 에이전트를 활용하여 6개 서비스를 동시에 빌드하여 시간 단축
-rw-r--r-- 1 KTDS 197121 78M 10월 29 09:49 content-service/build/libs/content-service.jar
-rw-r--r-- 1 KTDS 197121 94M 10월 29 09:49 event-service/build/libs/event-service.jar
-rw-r--r-- 1 KTDS 197121 85M 10월 29 09:49 participation-service/build/libs/participation-service.jar
-rw-r--r-- 1 KTDS 197121 96M 10월 29 09:49 user-service/build/libs/user-service.jar
```
## 5. Docker 이미지 빌드 ### 1. user-service
### 사전 준비사항 **빌드 명령:**
⚠️ **Docker Desktop이 실행 중이어야 합니다**
Docker Desktop 시작 확인:
```bash
# Docker 상태 확인
docker version
docker ps
# Docker Desktop이 정상 실행되면 위 명령들이 정상 동작합니다
```
### 빌드 명령어
#### 5.1 user-service
```bash ```bash
DOCKER_FILE=deployment/container/Dockerfile-backend DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \ docker build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg BUILD_LIB_DIR="user-service/build/libs" \ --build-arg BUILD_LIB_DIR="user-service/build/libs" \
@ -151,22 +116,17 @@ docker build \
-t user-service:latest . -t user-service:latest .
``` ```
#### 5.2 ai-service **결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: fb07547604be
- 이미지 크기: 1.09GB
- Image SHA: sha256:fb07547604bee7e8ff69e56e8423299b7dec277e80d865ee5013ddd876a0b4c6
### 2. event-service
**빌드 명령:**
```bash ```bash
DOCKER_FILE=deployment/container/Dockerfile-backend DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \
--platform linux/amd64 \
--build-arg BUILD_LIB_DIR="ai-service/build/libs" \
--build-arg ARTIFACTORY_FILE="ai-service.jar" \
-f ${DOCKER_FILE} \
-t ai-service:latest .
```
#### 5.3 event-service
```bash
DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \ docker build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg BUILD_LIB_DIR="event-service/build/libs" \ --build-arg BUILD_LIB_DIR="event-service/build/libs" \
@ -175,22 +135,56 @@ docker build \
-t event-service:latest . -t event-service:latest .
``` ```
#### 5.4 content-service **결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: 191a9882a628
- 이미지 크기: 1.08GB
- 빌드 시간: ~20초
### 3. ai-service
**빌드 명령:**
```bash ```bash
DOCKER_FILE=deployment/container/Dockerfile-backend DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \ docker build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg BUILD_LIB_DIR="content-service/build/libs" \ --build-arg BUILD_LIB_DIR="ai-service/build/libs" \
--build-arg ARTIFACTORY_FILE="content-service.jar" \ --build-arg ARTIFACTORY_FILE="ai-service.jar" \
-f ${DOCKER_FILE} \ -f ${DOCKER_FILE} \
-t content-service:latest . -t ai-service:latest .
``` ```
#### 5.5 participation-service **결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: 498feb888dc5
- 이미지 크기: 1.08GB
- Image SHA: sha256:498feb888dc58a98715841c4e50f191bc8434eccd12baefa79e82b0e44a5bc40
### 4. distribution-service
**빌드 명령:**
```bash ```bash
DOCKER_FILE=deployment/container/Dockerfile-backend DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \
--platform linux/amd64 \
--build-arg BUILD_LIB_DIR="distribution-service/build/libs" \
--build-arg ARTIFACTORY_FILE="distribution-service.jar" \
-f ${DOCKER_FILE} \
-t distribution-service:latest .
```
**결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: e0ad31c51b63
- 이미지 크기: 1.08GB
- Image SHA: sha256:e0ad31c51b63b44d67f017cca8a729ae9cbb5e9e9503feddb308c09f19b70fba
- 빌드 시간: ~60초
### 5. participation-service
**빌드 명령:**
```bash
DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \ docker build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg BUILD_LIB_DIR="participation-service/build/libs" \ --build-arg BUILD_LIB_DIR="participation-service/build/libs" \
@ -199,10 +193,18 @@ docker build \
-t participation-service:latest . -t participation-service:latest .
``` ```
#### 5.6 analytics-service **결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: 9bd60358659b
- 이미지 크기: 1.04GB
- Image SHA: sha256:9bd60358659b528190edcab699152b5126dc906070e05d355310303ac292f02b
- 빌드 시간: ~37초
### 6. analytics-service
**빌드 명령:**
```bash ```bash
DOCKER_FILE=deployment/container/Dockerfile-backend DOCKER_FILE=deployment/container/Dockerfile-backend
docker build \ docker build \
--platform linux/amd64 \ --platform linux/amd64 \
--build-arg BUILD_LIB_DIR="analytics-service/build/libs" \ --build-arg BUILD_LIB_DIR="analytics-service/build/libs" \
@ -211,186 +213,55 @@ docker build \
-t analytics-service:latest . -t analytics-service:latest .
``` ```
### 빌드 스크립트 (일괄 실행) **결과:**
- 상태: ✅ SUCCESS
- 이미지 ID: 33b53299ec16
- 이미지 크기: 1.08GB
- Image SHA: sha256:33b53299ec16e0021a9adca4fb32535708021073df03c30b8a0ea335348547de
## 생성된 이미지 확인
**확인 명령:**
```bash ```bash
#!/bin/bash docker images | grep -E "(user-service|event-service|ai-service|distribution-service|participation-service|analytics-service)" | grep latest
# build-all-images.sh
DOCKER_FILE=deployment/container/Dockerfile-backend
services=(
"user-service"
"ai-service"
"event-service"
"content-service"
"participation-service"
"analytics-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 ${DOCKER_FILE} \
-t ${service}:latest .
if [ $? -eq 0 ]; then
echo "✅ ${service} build successful"
else
echo "❌ ${service} build failed"
exit 1
fi
done
echo "🎉 All images built successfully!"
``` ```
## 6. 이미지 확인 **확인 결과:**
```
### 생성된 이미지 확인 명령어 event-service latest 191a9882a628 39 seconds ago 1.08GB
```bash ai-service latest 498feb888dc5 46 seconds ago 1.08GB
# 모든 서비스 이미지 확인 analytics-service latest 33b53299ec16 46 seconds ago 1.08GB
docker images | grep -E "(user-service|ai-service|event-service|content-service|participation-service|analytics-service)" user-service latest fb07547604be 47 seconds ago 1.09GB
participation-service latest 9bd60358659b 48 seconds ago 1.04GB
# 개별 서비스 확인 distribution-service latest e0ad31c51b63 48 seconds ago 1.08GB
docker images user-service:latest
docker images ai-service:latest
docker images event-service:latest
docker images content-service:latest
docker images participation-service:latest
docker images analytics-service:latest
``` ```
### 빌드 결과 ✅ ## 빌드 결과 요약
```
REPOSITORY TAG IMAGE ID CREATED SIZE
user-service latest 91c511ef86bd About a minute ago 1.09GB
ai-service latest 9477022fa493 About a minute ago 1.08GB
event-service latest add81de69536 About a minute ago 1.08GB
content-service latest aa9cc16ad041 About a minute ago 1.01GB
participation-service latest 9b044a3854dd About a minute ago 1.04GB
analytics-service latest ac569de42545 About a minute ago 1.08GB
```
**빌드 일시**: 2025-10-29 09:50 KST | 서비스명 | 이미지 태그 | 이미지 ID | 크기 | 상태 |
**빌드 소요 시간**: 약 13초 (병렬 빌드) |---------|-----------|----------|------|------|
**총 이미지 크기**: 6.48GB | user-service | user-service:latest | fb07547604be | 1.09GB | ✅ |
| event-service | event-service:latest | 191a9882a628 | 1.08GB | ✅ |
| ai-service | ai-service:latest | 498feb888dc5 | 1.08GB | ✅ |
| distribution-service | distribution-service:latest | e0ad31c51b63 | 1.08GB | ✅ |
| participation-service | participation-service:latest | 9bd60358659b | 1.04GB | ✅ |
| analytics-service | analytics-service:latest | 33b53299ec16 | 1.08GB | ✅ |
## 7. 이미지 테스트 **총 6개 서비스 이미지 빌드 성공**
### 로컬 실행 테스트 (예시: user-service) ## 다음 단계
```bash
# 컨테이너 실행
docker run -d \
--name user-service-test \
-p 8080:8080 \
-e SPRING_PROFILES_ACTIVE=dev \
user-service:latest
# 로그 확인 생성된 이미지를 사용하여 다음 작업을 진행할 수 있습니다:
docker logs -f user-service-test
# 헬스체크 1. **로컬 테스트:** Docker Compose 또는 개별 컨테이너 실행
curl http://localhost:8080/actuator/health 2. **ACR 푸시:** Azure Container Registry에 이미지 업로드
3. **AKS 배포:** Kubernetes 클러스터에 배포
4. **CI/CD 통합:** GitHub Actions 또는 Jenkins 파이프라인 연동
# 정리 ## 참고사항
docker stop user-service-test
docker rm user-service-test
```
## 8. 다음 단계 - 모든 이미지는 linux/amd64 플랫폼용으로 빌드됨
- 보안을 위해 비root 사용자(k8s)로 실행 구성
### 8.1 컨테이너 레지스트리 푸시 - Multi-stage 빌드로 이미지 크기 최적화
```bash - Java 23 (OpenJDK) 기반 런타임 사용
# Docker Hub 예시 - content-service(Python)는 별도의 Dockerfile로 빌드 필요
docker tag user-service:latest <your-registry>/user-service:latest
docker push <your-registry>/user-service:latest
# Azure Container Registry 예시
docker tag user-service:latest <acr-name>.azurecr.io/user-service:latest
docker push <acr-name>.azurecr.io/user-service:latest
```
### 8.2 Kubernetes 배포
- Kubernetes Deployment 매니페스트 작성
- Service 리소스 정의
- ConfigMap/Secret 설정
- Ingress 구성
### 8.3 CI/CD 파이프라인 구성
- GitHub Actions 또는 Jenkins 파이프라인 작성
- 자동 빌드 및 배포 설정
- 이미지 태깅 전략 수립 (semantic versioning)
## 9. 트러블슈팅
### Issue 1: Docker Desktop 미실행
**증상**:
```
ERROR: error during connect: open //./pipe/dockerDesktopLinuxEngine:
The system cannot find the file specified.
```
**해결**:
1. Docker Desktop 애플리케이션 시작
2. 시스템 트레이의 Docker 아이콘이 안정화될 때까지 대기
3. `docker ps` 명령으로 정상 동작 확인
### Issue 2: JAR 파일 없음
**증상**:
```
COPY failed: file not found in build context
```
**해결**:
```bash
# JAR 파일 재빌드
./gradlew {service-name}:clean {service-name}:bootJar
# 생성 확인
ls -l {service-name}/build/libs/{service-name}.jar
```
### Issue 3: 플랫폼 불일치
**증상**: K8s 클러스터에서 실행 안됨
**해결**: `--platform linux/amd64` 옵션 사용 (이미 적용됨)
## 10. 요약
### ✅ 완료된 작업
1. ✅ 6개 서비스의 bootJar 설정 완료
2. ✅ Dockerfile-backend 생성 완료
3. ✅ 6개 서비스 JAR 파일 빌드 완료 (총 542MB)
4. ✅ 6개 서비스 Docker 이미지 빌드 완료 (총 6.48GB)
### 📊 최종 서비스 현황
| 서비스 | JAR 빌드 | Docker 이미지 | 이미지 크기 | Image ID | 상태 |
|--------|---------|--------------|-----------|----------|------|
| user-service | ✅ 96MB | ✅ | 1.09GB | 91c511ef86bd | ✅ Ready |
| ai-service | ✅ 94MB | ✅ | 1.08GB | 9477022fa493 | ✅ Ready |
| event-service | ✅ 94MB | ✅ | 1.08GB | add81de69536 | ✅ Ready |
| content-service | ✅ 78MB | ✅ | 1.01GB | aa9cc16ad041 | ✅ Ready |
| participation-service | ✅ 85MB | ✅ | 1.04GB | 9b044a3854dd | ✅ Ready |
| analytics-service | ✅ 95MB | ✅ | 1.08GB | ac569de42545 | ✅ Ready |
| distribution-service | ❌ | ❌ | - | - | 소스 미구현 |
### 🎯 빌드 성능 메트릭
- **JAR 빌드 시간**: 27초
- **Docker 이미지 빌드**: 병렬 실행으로 약 13초
- **총 소요 시간**: 약 40초
- **빌드 성공률**: 100% (6/6 서비스)
### 🚀 다음 단계 권장사항
1. **컨테이너 레지스트리 푸시** (예: Azure ACR, Docker Hub)
2. **Kubernetes 배포 매니페스트 작성**
3. **CI/CD 파이프라인 구성** (GitHub Actions 또는 Jenkins)
4. **모니터링 및 로깅 설정**
---
**작성일**: 2025-10-29 09:50 KST
**작성자**: DevOps Engineer (송근정 "데브옵스 마스터")
**빌드 완료**: ✅ 모든 서비스 이미지 빌드 성공

View File

@ -99,7 +99,7 @@ spec:
number: 80 number: 80
# Distribution Service # Distribution Service
- path: /distribution - path: /api/v1/distribution
pathType: Prefix pathType: Prefix
backend: backend:
service: service:

View File

@ -42,21 +42,21 @@ spec:
memory: "1024Mi" memory: "1024Mi"
startupProbe: startupProbe:
httpGet: httpGet:
path: /distribution/actuator/health path: /api/v1/distribution/actuator/health
port: 8085 port: 8085
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10
failureThreshold: 30 failureThreshold: 30
readinessProbe: readinessProbe:
httpGet: httpGet:
path: /distribution/actuator/health/readiness path: /api/v1/distribution/actuator/health/readiness
port: 8085 port: 8085
initialDelaySeconds: 10 initialDelaySeconds: 10
periodSeconds: 5 periodSeconds: 5
failureThreshold: 3 failureThreshold: 3
livenessProbe: livenessProbe:
httpGet: httpGet:
path: /distribution/actuator/health/liveness path: /api/v1/distribution/actuator/health/liveness
port: 8085 port: 8085
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 10 periodSeconds: 10

View File

@ -26,7 +26,7 @@ import org.springframework.web.bind.annotation.*;
*/ */
@Slf4j @Slf4j
@RestController @RestController
@RequestMapping("/api/v1/distribution") @RequestMapping
@RequiredArgsConstructor @RequiredArgsConstructor
@Tag(name = "Distribution", description = "다중 채널 배포 관리 API") @Tag(name = "Distribution", description = "다중 채널 배포 관리 API")
public class DistributionController { public class DistributionController {

View File

@ -68,7 +68,7 @@ kafka:
server: server:
port: ${SERVER_PORT:8085} port: ${SERVER_PORT:8085}
servlet: servlet:
context-path: /distribution context-path: /api/v1/distribution
# Resilience4j Configuration # Resilience4j Configuration
resilience4j: resilience4j:
@ -136,6 +136,14 @@ springdoc:
display-request-duration: true display-request-duration: true
show-actuator: true show-actuator: true
# CORS Configuration
cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}
# Logging # Logging
logging: logging:
file: file:

View File

@ -31,6 +31,9 @@
<!-- JWT Configuration --> <!-- JWT Configuration -->
<entry key="JWT_SECRET" value="kt-event-marketing-secret-key-for-development-only-please-change-in-production" /> <entry key="JWT_SECRET" value="kt-event-marketing-secret-key-for-development-only-please-change-in-production" />
<!-- CORS Configuration -->
<entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*,http://*.nip.io:*" />
<!-- Logging Configuration --> <!-- Logging Configuration -->
<entry key="LOG_LEVEL" value="DEBUG" /> <entry key="LOG_LEVEL" value="DEBUG" />
<entry key="SQL_LOG_LEVEL" value="DEBUG" /> <entry key="SQL_LOG_LEVEL" value="DEBUG" />

View File

@ -167,3 +167,11 @@ app:
jwt: jwt:
secret: ${JWT_SECRET:default-jwt-secret-key-for-development-minimum-32-bytes-required} secret: ${JWT_SECRET:default-jwt-secret-key-for-development-minimum-32-bytes-required}
expiration: 86400000 # 24시간 (밀리초 단위) expiration: 86400000 # 24시간 (밀리초 단위)
# CORS Configuration
cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}

View File

@ -12,6 +12,7 @@
<entry key="JWT_EXPIRATION" value="86400000" /> <entry key="JWT_EXPIRATION" value="86400000" />
<entry key="JWT_SECRET" value="kt-event-marketing-secret-key-for-development-only-change-in-production" /> <entry key="JWT_SECRET" value="kt-event-marketing-secret-key-for-development-only-change-in-production" />
<entry key="KAFKA_BOOTSTRAP_SERVERS" value="20.249.182.13:9095,4.217.131.59:9095" /> <entry key="KAFKA_BOOTSTRAP_SERVERS" value="20.249.182.13:9095,4.217.131.59:9095" />
<entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*,http://*.nip.io:*" />
<entry key="LOG_FILE" value="logs/participation-service.log" /> <entry key="LOG_FILE" value="logs/participation-service.log" />
<entry key="LOG_LEVEL" value="INFO" /> <entry key="LOG_LEVEL" value="INFO" />
<entry key="REDIS_HOST" value="20.214.210.71" /> <entry key="REDIS_HOST" value="20.214.210.71" />

View File

@ -1,11 +1,17 @@
package com.kt.event.participation.infrastructure.config; package com.kt.event.participation.infrastructure.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import java.util.Arrays;
/** /**
* Security Configuration for Participation Service * Security Configuration for Participation Service
@ -18,10 +24,14 @@ import org.springframework.security.web.SecurityFilterChain;
@EnableWebSecurity @EnableWebSecurity
public class SecurityConfig { public class SecurityConfig {
@Value("${cors.allowed-origins:http://localhost:*}")
private String allowedOrigins;
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http http
.csrf(csrf -> csrf.disable()) .csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth .authorizeHttpRequests(auth -> auth
// Actuator endpoints // Actuator endpoints
@ -31,4 +41,26 @@ public class SecurityConfig {
return http.build(); return http.build();
} }
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
String[] origins = allowedOrigins.split(",");
configuration.setAllowedOriginPatterns(Arrays.asList(origins));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList(
"Authorization", "Content-Type", "X-Requested-With", "Accept",
"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers"
));
configuration.setAllowCredentials(true);
configuration.setMaxAge(3600L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
} }

View File

@ -54,6 +54,14 @@ jwt:
secret: ${JWT_SECRET:dev-jwt-secret-key-for-development-only} secret: ${JWT_SECRET:dev-jwt-secret-key-for-development-only}
expiration: ${JWT_EXPIRATION:86400000} expiration: ${JWT_EXPIRATION:86400000}
# CORS 설정
cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}
# 서버 설정 # 서버 설정
server: server:
port: ${SERVER_PORT:8084} port: ${SERVER_PORT:8084}

View File

@ -42,7 +42,7 @@
<entry key="JWT_ACCESS_TOKEN_VALIDITY" value="604800000" /> <entry key="JWT_ACCESS_TOKEN_VALIDITY" value="604800000" />
<!-- CORS Configuration --> <!-- CORS Configuration -->
<entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*" /> <entry key="CORS_ALLOWED_ORIGINS" value="http://localhost:*,http://*.nip.io:*" />
<!-- Logging Configuration --> <!-- Logging Configuration -->
<entry key="LOG_LEVEL_APP" value="DEBUG" /> <entry key="LOG_LEVEL_APP" value="DEBUG" />

View File

@ -76,7 +76,11 @@ jwt:
# CORS Configuration # CORS Configuration
cors: cors:
allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:*} allowed-origins: ${CORS_ALLOWED_ORIGINS:http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://kt-event-marketing.20.214.196.128.nip.io}
allowed-methods: ${CORS_ALLOWED_METHODS:GET,POST,PUT,DELETE,OPTIONS,PATCH}
allowed-headers: ${CORS_ALLOWED_HEADERS:*}
allow-credentials: ${CORS_ALLOW_CREDENTIALS:true}
max-age: ${CORS_MAX_AGE:3600}
# Actuator # Actuator
management: management: