Merge branch 'develop' into feature/content

This commit is contained in:
Cherry Kim
2025-10-29 09:42:16 +09:00
committed by GitHub
108 changed files with 6546 additions and 846 deletions
+212 -222
View File
@@ -1,187 +1,195 @@
# Content Service 컨테이너 이미지 빌드 및 배포 가이드
# Event Service 컨테이너 이미지 빌드 가이드
## 1. 사전 준비사항
## 1. 빌드 일시
- **빌드 날짜**: 2025-10-28
- **빌드 시간**: 14:35 KST
### 필수 소프트웨어
- **Docker Desktop**: Docker 컨테이너 실행 환경
- **JDK 23**: Java 애플리케이션 빌드
- **Gradle**: 프로젝트 빌드 도구
## 2. 수정 사항
### 외부 서비스
- **Redis 서버**: 20.214.210.71:6379
- **Kafka 서버**: 4.230.50.63:9092
- **Replicate API**: Stable Diffusion 이미지 생성
- **Azure Blob Storage**: 이미지 CDN
### 2.1 타입 불일치 수정
Event Service 컴파일 오류 해결을 위해 다음 파일들을 수정했습니다:
## 2. 빌드 설정
#### UserPrincipal.java (common 모듈)
- **파일 경로**: `common/src/main/java/com/kt/event/common/security/UserPrincipal.java`
- **수정 내용**: userId와 storeId 타입을 Long에서 UUID로 변경
- **변경 이유**: EventService의 메서드 시그니처가 UUID를 기대하므로 일관성 유지
```java
// Before
private final Long userId;
private final Long storeId;
// After
private final UUID userId;
private final UUID storeId;
```
#### JwtTokenProvider.java (common 모듈)
- **파일 경로**: `common/src/main/java/com/kt/event/common/security/JwtTokenProvider.java`
- **수정 내용**: JWT 토큰 파싱 시 Long.parseLong()을 UUID.fromString()으로 변경
- **변경 이유**: UserPrincipal의 타입 변경에 따른 파싱 로직 수정
```java
// Before
Long userId = Long.parseLong(claims.getSubject());
Long storeId = storeIdStr != null ? Long.parseLong(storeIdStr) : null;
// After
UUID userId = UUID.fromString(claims.getSubject());
UUID storeId = storeIdStr != null ? UUID.fromString(storeIdStr) : null;
```
#### event-service/build.gradle
- **수정 내용**: bootJar 설정 추가
- **변경 이유**: 컨테이너 이미지 빌드를 위한 JAR 파일명 명시
### build.gradle 설정 (content-service/build.gradle)
```gradle
// 실행 JAR 파일명 설정
bootJar {
archiveFileName = 'content-service.jar'
archiveFileName = 'event-service.jar'
}
```
## 3. 배포 파일 구조
## 3. 빌드 명령어
```
deployment/
└── container/
├── Dockerfile-backend # 백엔드 서비스용 Dockerfile
├── docker-compose.yml # Docker Compose 설정
└── build-and-run.sh # 자동화 배포 스크립트
```
## 4. 수동 빌드 및 배포
### 4.1 Gradle 빌드
### 3.1 Common 모듈 컴파일
```bash
# 프로젝트 루트에서 실행
./gradlew clean content-service:bootJar
./gradlew common:compileJava
```
### 4.2 Docker 이미지 빌드
```bash
DOCKER_FILE=deployment/container/Dockerfile-backend
**결과**: BUILD SUCCESSFUL in 6s
### 3.2 Event Service 컴파일
```bash
./gradlew event-service:compileJava
```
**결과**: BUILD SUCCESSFUL in 6s
### 3.3 Event Service JAR 빌드
```bash
./gradlew event-service:bootJar
```
**결과**:
- BUILD SUCCESSFUL in 5s
- JAR 파일 생성: `event-service/build/libs/event-service.jar` (94MB)
### 3.4 Docker 이미지 빌드
```bash
docker build \
--platform linux/amd64 \
--build-arg BUILD_LIB_DIR="content-service/build/libs" \
--build-arg ARTIFACTORY_FILE="content-service.jar" \
-f ${DOCKER_FILE} \
-t content-service:latest .
```
### 4.3 빌드된 이미지 확인
```bash
docker images | grep content-service
```
예상 출력:
```
content-service latest abc123def456 2 minutes ago 450MB
```
### 4.4 Docker Compose로 컨테이너 실행
```bash
docker-compose -f deployment/container/docker-compose.yml up -d
```
### 4.5 컨테이너 상태 확인
```bash
# 실행 중인 컨테이너 확인
docker ps
# 로그 확인
docker logs -f content-service
# 헬스체크
curl http://localhost:8084/actuator/health
```
## 5. 자동화 배포 스크립트 사용 (권장)
### 5.1 스크립트 실행
```bash
# 프로젝트 루트에서 실행
./deployment/container/build-and-run.sh
```
### 5.2 스크립트 수행 단계
1. Gradle 빌드
2. Docker 이미지 빌드
3. 이미지 확인
4. 기존 컨테이너 정리
5. 새 컨테이너 실행
## 6. 환경변수 설정
`docker-compose.yml`에 다음 환경변수가 설정되어 있습니다:
### 필수 환경변수
- `SPRING_PROFILES_ACTIVE`: Spring Profile (prod)
- `SERVER_PORT`: 서버 포트 (8084)
- `REDIS_HOST`: Redis 호스트
- `REDIS_PORT`: Redis 포트
- `REDIS_PASSWORD`: Redis 비밀번호
- `JWT_SECRET`: JWT 서명 키 (최소 32자)
- `REPLICATE_API_TOKEN`: Replicate API 토큰
- `AZURE_STORAGE_CONNECTION_STRING`: Azure Storage 연결 문자열
- `AZURE_CONTAINER_NAME`: Azure Storage 컨테이너 이름
### JWT_SECRET 요구사항
- **최소 길이**: 32자 이상 (256비트)
- **형식**: 영문자, 숫자 조합
- **예시**: `kt-event-marketing-jwt-secret-key-for-authentication-and-authorization-2025`
## 7. VM 배포
### 7.1 VM에 파일 전송
```bash
# VM으로 파일 복사 (예시)
scp -r deployment/ user@vm-host:/path/to/project/
scp docker-compose.yml user@vm-host:/path/to/project/deployment/container/
scp content-service/build/libs/content-service.jar user@vm-host:/path/to/project/content-service/build/libs/
```
### 7.2 VM에서 이미지 빌드
```bash
# VM에 SSH 접속 후
cd /path/to/project
# 이미지 빌드
docker build \
--platform linux/amd64 \
--build-arg BUILD_LIB_DIR="content-service/build/libs" \
--build-arg ARTIFACTORY_FILE="content-service.jar" \
--build-arg BUILD_LIB_DIR="event-service/build/libs" \
--build-arg ARTIFACTORY_FILE="event-service.jar" \
-f deployment/container/Dockerfile-backend \
-t content-service:latest .
-t event-service:latest .
```
### 7.3 VM에서 컨테이너 실행
```bash
# Docker Compose로 실행
docker-compose -f deployment/container/docker-compose.yml up -d
**결과**: 이미지 빌드 성공
- Image ID: bbeecf2ccaf2
- Size: 1.08GB
- Created: 19 seconds ago
# 또는 직접 실행
## 4. 빌드 검증
### 4.1 JAR 파일 확인
```bash
ls -lh event-service/build/libs/
```
**출력**:
```
-rw-r--r-- 1 KTDS 197121 94M 10월 28 14:35 event-service.jar
```
### 4.2 Docker 이미지 확인
```bash
docker images | grep event-service
```
**출력**:
```
event-service latest bbeecf2ccaf2 19 seconds ago 1.08GB
```
## 5. Dockerfile 구조
**파일 위치**: `deployment/container/Dockerfile-backend`
### 빌드 스테이지 (Build Stage)
- **Base Image**: openjdk:23-oraclelinux8
- **작업**: JAR 파일 복사
### 실행 스테이지 (Run Stage)
- **Base Image**: openjdk:23-slim
- **사용자**: k8s (non-root user)
- **작업 디렉토리**: /home/k8s
- **진입점**: `java ${JAVA_OPTS} -jar app.jar`
## 6. 컨테이너 실행 가이드
### 6.1 기본 실행
```bash
docker run -d \
--name content-service \
-p 8084:8084 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SERVER_PORT=8084 \
-e REDIS_HOST=20.214.210.71 \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD=Hi5Jessica! \
-e JWT_SECRET=kt-event-marketing-jwt-secret-key-for-authentication-and-authorization-2025 \
-e REPLICATE_API_TOKEN=r8_Q33U00fSnpjYlHNIRglwurV446h7g8V2wkFFa \
-e AZURE_STORAGE_CONNECTION_STRING="DefaultEndpointsProtocol=https;AccountName=blobkteventstorage;AccountKey=tcBN7mAfojbl0uGsOpU7RNuKNhHnzmwDiWjN31liSMVSrWaEK+HHnYKZrjBXXAC6ZPsuxUDlsf8x+AStd++QYg==;EndpointSuffix=core.windows.net" \
-e AZURE_CONTAINER_NAME=content-images \
content-service:latest
--name event-service \
-p 8082:8082 \
-e SPRING_PROFILES_ACTIVE=dev \
-e SERVER_PORT=8082 \
event-service:latest
```
## 8. 모니터링 및 로그
### 6.2 환경변수 설정
Event Service 실행을 위한 주요 환경변수:
### 8.1 컨테이너 상태 확인
#### 필수 환경변수
- `SERVER_PORT`: 서버 포트 (기본값: 8082)
- `DB_HOST`: PostgreSQL 호스트
- `DB_PORT`: PostgreSQL 포트 (기본값: 5432)
- `DB_NAME`: 데이터베이스 이름
- `DB_USERNAME`: 데이터베이스 사용자명
- `DB_PASSWORD`: 데이터베이스 비밀번호
- `REDIS_HOST`: Redis 호스트
- `REDIS_PORT`: Redis 포트 (기본값: 6379)
- `REDIS_PASSWORD`: Redis 비밀번호
- `KAFKA_BOOTSTRAP_SERVERS`: Kafka 브로커 주소
- `JWT_SECRET`: JWT 서명 키 (최소 32자)
#### 선택 환경변수
- `DISTRIBUTION_SERVICE_URL`: Distribution Service URL
- `JAVA_OPTS`: JVM 옵션
### 6.3 Docker Compose 실행 예시
```yaml
services:
event-service:
image: event-service:latest
container_name: event-service
ports:
- "8082:8082"
environment:
- SPRING_PROFILES_ACTIVE=prod
- SERVER_PORT=8082
- DB_HOST=your-db-host
- DB_PORT=5432
- DB_NAME=event_db
- DB_USERNAME=event_user
- DB_PASSWORD=your-password
- REDIS_HOST=your-redis-host
- REDIS_PORT=6379
- REDIS_PASSWORD=your-redis-password
- KAFKA_BOOTSTRAP_SERVERS=your-kafka:9092
- JWT_SECRET=your-jwt-secret-key-minimum-32-characters
- DISTRIBUTION_SERVICE_URL=http://distribution-service:8086
restart: unless-stopped
```
## 7. 헬스체크
### 7.1 Spring Boot Actuator
```bash
docker ps
curl http://localhost:8082/actuator/health
```
### 8.2 로그 확인
```bash
# 실시간 로그
docker logs -f content-service
# 최근 100줄
docker logs --tail 100 content-service
```
### 8.3 헬스체크
```bash
curl http://localhost:8084/actuator/health
```
예상 응답:
**예상 응답**:
```json
{
"status": "UP",
@@ -189,6 +197,9 @@ curl http://localhost:8084/actuator/health
"ping": {
"status": "UP"
},
"db": {
"status": "UP"
},
"redis": {
"status": "UP"
}
@@ -196,81 +207,60 @@ curl http://localhost:8084/actuator/health
}
```
## 9. Swagger UI 접근
배포 후 Swagger UI로 API 테스트 가능:
### 7.2 Swagger UI
```
http://localhost:8084/swagger-ui/index.html
http://localhost:8082/swagger-ui/index.html
```
## 10. 이미지 생성 API 테스트
## 8. 빌드 결과 요약
### 10.1 이미지 생성 요청
### 서비스 정보
- **서비스명**: event-service
- **포트**: 8082
- **JAR 크기**: 94MB
- **이미지 크기**: 1.08GB
- **Base Image**: openjdk:23-slim
- **Platform**: linux/amd64
### 빌드 통계
- **Common 컴파일**: 6초
- **Event Service 컴파일**: 6초
- **JAR 빌드**: 5초
- **Docker 이미지 빌드**: 약 120초
### 주요 의존성
- Spring Boot Actuator
- Spring Kafka
- Spring Data Redis
- Spring Cloud OpenFeign
- PostgreSQL Driver
- Jackson
## 9. 트러블슈팅
### 9.1 컴파일 오류 해결
**증상**: userId/storeId 타입 불일치 오류
**해결**:
- UserPrincipal의 userId, storeId를 UUID로 변경
- JwtTokenProvider의 파싱 로직을 UUID.fromString()으로 수정
### 9.2 Gradle Clean 오류
**증상**: `Unable to delete directory 'common\build'`
**해결**: clean 없이 빌드 수행
```bash
curl -X POST "http://localhost:8084/api/v1/content/images/generate" \
-H "Content-Type: application/json" \
-d '{
"eventDraftId": 1001,
"industry": "고깃집",
"location": "강남",
"trends": ["가을", "단풍", "BBQ"],
"styles": ["FANCY"],
"platforms": ["INSTAGRAM"]
}'
./gradlew event-service:bootJar
```
### 10.2 Job 상태 확인
```bash
curl http://localhost:8084/api/v1/content/jobs/{jobId}
```
### 9.3 Docker 빌드 컨텍스트 오류
**증상**: JAR 파일을 찾을 수 없음
## 11. 컨테이너 관리 명령어
**해결**:
- JAR 파일이 실제로 빌드되었는지 확인
- 빌드 아규먼트 경로가 올바른지 확인
### 11.1 컨테이너 중지
```bash
docker-compose -f deployment/container/docker-compose.yml down
```
### 11.2 컨테이너 재시작
```bash
docker-compose -f deployment/container/docker-compose.yml restart
```
### 11.3 컨테이너 삭제
```bash
# 컨테이너만 삭제
docker rm -f content-service
# 이미지도 삭제
docker rmi content-service:latest
```
## 12. 트러블슈팅
### 12.1 JWT 토큰 오류
**증상**: `Error creating bean with name 'jwtTokenProvider'`
**해결방법**:
- `JWT_SECRET` 환경변수가 32자 이상인지 확인
- docker-compose.yml에 올바르게 설정되어 있는지 확인
### 12.2 Redis 연결 오류
**증상**: `Unable to connect to Redis`
**해결방법**:
- Redis 서버(20.214.210.71:6379)가 실행 중인지 확인
- 방화벽 설정 확인
- 비밀번호 확인
### 12.3 Azure Storage 오류
**증상**: `Azure storage connection failed`
**해결방법**:
- `AZURE_STORAGE_CONNECTION_STRING`이 올바른지 확인
- Storage Account가 활성화되어 있는지 확인
- 컨테이너 이름(`content-images`)이 존재하는지 확인
## 13. 빌드 결과
## 10. 다음 단계
### 빌드 수행 이력
@@ -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
```
---
이 가이드를 통해 백엔드 서비스를 안전하고 효율적으로 컨테이너로 실행할 수 있습니다. 추가 질문이나 문제가 있으면 언제든지 문의해 주세요! 🚀
+402
View File
@@ -0,0 +1,402 @@
# 백엔드 컨테이너 실행 가이드
## 목차
1. [개요](#개요)
2. [VM 접속](#vm-접속)
3. [Git Repository 클론](#git-repository-클론)
4. [컨테이너 이미지 빌드](#컨테이너-이미지-빌드)
5. [컨테이너 레지스트리 설정](#컨테이너-레지스트리-설정)
6. [컨테이너 이미지 푸시](#컨테이너-이미지-푸시)
7. [컨테이너 실행](#컨테이너-실행)
8. [컨테이너 확인](#컨테이너-확인)
9. [재배포](#재배포)
---
## 개요
본 가이드는 **kt-event-marketing** 시스템의 백엔드 마이크로서비스들을 Docker 컨테이너로 실행하는 방법을 안내합니다.
### 시스템 정보
- **시스템명**: kt-event-marketing
- **ACR명**: acrdigitalgarage01
- **서비스 목록**:
- user-service (포트: 8081)
- event-service (포트: 8080)
- analytics-service (포트: 8086)
- participation-service (포트: 8084)
### VM 정보
- **IP**: 20.196.65.160
- **사용자 ID**: P82265804@ktds.co.kr
- **SSH Key 파일**: ~/home/bastion-dg0505
---
## VM 접속
### 1단계: 터미널 실행
- **Linux/Mac**: 기본 터미널 실행
- **Windows**: Windows Terminal 실행
### 2단계: SSH Key 파일 권한 설정 (최초 1회)
```bash
chmod 400 ~/home/bastion-dg0505
```
### 3단계: VM 접속
```bash
ssh -i ~/home/bastion-dg0505 P82265804@ktds.co.kr@20.196.65.160
```
---
## Git Repository 클론
### 1단계: workspace 디렉토리 생성 및 이동
```bash
mkdir -p ~/home/workspace
cd ~/home/workspace
```
### 2단계: 소스 클론
```bash
git clone https://github.com/ktds-dg0501/kt-event-marketing.git
```
### 3단계: 프로젝트 디렉토리로 이동
```bash
cd kt-event-marketing
```
---
## 컨테이너 이미지 빌드
### 이미지 빌드 가이드 참조
프로젝트 내 빌드 가이드를 참조하여 컨테이너 이미지를 생성합니다:
```bash
# 빌드 가이드 파일 열기
cat deployment/container/build-image.md
```
빌드 가이드에 따라 각 서비스의 컨테이너 이미지를 생성하세요.
---
## 컨테이너 레지스트리 설정
### 1단계: ACR 인증 정보 확인
Azure CLI를 사용하여 ACR 인증 정보를 확인합니다:
```bash
az acr credential show --name acrdigitalgarage01
```
**출력 예시**:
```json
{
"passwords": [
{
"name": "password",
"value": "{암호}"
},
{
"name": "password2",
"value": "{암호2}"
}
],
"username": "acrdigitalgarage01"
}
```
- **ID**: `username` 값 (예: acrdigitalgarage01)
- **암호**: `passwords[0].value`
### 2단계: Docker 로그인
```bash
docker login acrdigitalgarage01.azurecr.io -u {ID} -p {암호}
```
**예시**:
```bash
docker login acrdigitalgarage01.azurecr.io -u acrdigitalgarage01 -p mySecretPassword123
```
---
## 컨테이너 이미지 푸시
각 서비스의 이미지를 ACR에 푸시합니다.
### user-service
```bash
docker tag user-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
```
### event-service
```bash
docker tag event-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
```
### 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
```
### participation-service
```bash
docker tag participation-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/participation-service:latest
```
---
## 컨테이너 실행
각 서비스를 Docker 컨테이너로 실행합니다.
### user-service 실행
```bash
SERVER_PORT=8081
docker run -d --name user-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
-e SERVER_PORT=8081 \
-e DB_URL=jdbc:postgresql://20.249.125.115:5432/userdb \
-e DB_DRIVER=org.postgresql.Driver \
-e DB_HOST=20.249.125.115 \
-e DB_PORT=5432 \
-e DB_NAME=userdb \
-e DB_USERNAME=eventuser \
-e DB_PASSWORD=Hi5Jessica! \
-e DB_KIND=postgresql \
-e DDL_AUTO=update \
-e SHOW_SQL=true \
-e JPA_DIALECT=org.hibernate.dialect.PostgreSQLDialect \
-e H2_CONSOLE_ENABLED=false \
-e REDIS_ENABLED=true \
-e REDIS_HOST=20.214.210.71 \
-e REDIS_PORT=6379 \
-e REDIS_PASSWORD=Hi5Jessica! \
-e REDIS_DATABASE=0 \
-e EXCLUDE_REDIS="" \
-e KAFKA_BOOTSTRAP_SERVERS=4.230.50.63:9092 \
-e KAFKA_CONSUMER_GROUP=user-service-consumers \
-e EXCLUDE_KAFKA="" \
-e JWT_SECRET=kt-event-marketing-secret-key-for-development-only-please-change-in-production \
-e JWT_ACCESS_TOKEN_VALIDITY=604800000 \
-e CORS_ALLOWED_ORIGINS="http://localhost:*,http://20.196.65.160:3000" \
-e LOG_LEVEL_APP=DEBUG \
-e LOG_LEVEL_WEB=INFO \
-e LOG_LEVEL_SQL=DEBUG \
-e LOG_LEVEL_SQL_TYPE=TRACE \
-e LOG_FILE_PATH=logs/user-service.log \
acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
```
### event-service 실행
```bash
SERVER_PORT=8080
docker run -d --name event-service --rm -p ${SERVER_PORT}:${SERVER_PORT} \
-e SERVER_PORT=8080 \
-e DB_HOST=20.249.177.232 \
-e DB_PORT=5432 \
-e DB_NAME=eventdb \
-e DB_USERNAME=eventuser \
-e DB_PASSWORD=Hi5Jessica! \
-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 CONTENT_SERVICE_URL=http://localhost:8082 \
-e DISTRIBUTION_SERVICE_URL=http://localhost:8084 \
-e JWT_SECRET=kt-event-marketing-secret-key-for-development-only-please-change-in-production \
-e LOG_LEVEL=DEBUG \
-e SQL_LOG_LEVEL=DEBUG \
acrdigitalgarage01.azurecr.io/kt-event-marketing/event-service:latest
```
### 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://20.196.65.160: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
```
### 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=update \
-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
```
---
## 컨테이너 확인
모든 서비스가 정상적으로 실행되었는지 확인합니다.
### 전체 서비스 확인
```bash
docker ps
```
### 개별 서비스 확인
```bash
docker ps | grep user-service
docker ps | grep event-service
docker ps | grep analytics-service
docker ps | grep participation-service
```
### 서비스 로그 확인
```bash
docker logs user-service
docker logs event-service
docker logs analytics-service
docker logs participation-service
```
---
## 재배포
소스 코드 수정 후 재배포 방법입니다.
### 1단계: 로컬에서 수정된 소스 푸시
로컬 개발 환경에서 소스 수정 후 Git에 푸시합니다.
### 2단계: VM 접속
```bash
ssh -i ~/home/bastion-dg0505 P82265804@ktds.co.kr@20.196.65.160
```
### 3단계: 디렉토리 이동 및 소스 내려받기
```bash
cd ~/home/workspace/kt-event-marketing
git pull
```
### 4단계: 컨테이너 이미지 재생성
빌드 가이드에 따라 이미지를 재생성합니다:
```bash
cat deployment/container/build-image.md
```
### 5단계: 컨테이너 이미지 푸시 (예: user-service)
```bash
docker tag user-service:latest acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
docker push acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
```
### 6단계: 기존 컨테이너 중지
```bash
docker stop user-service
```
### 7단계: 컨테이너 이미지 삭제
```bash
docker rmi acrdigitalgarage01.azurecr.io/kt-event-marketing/user-service:latest
```
### 8단계: 컨테이너 재실행
위 [컨테이너 실행](#컨테이너-실행) 섹션의 명령을 다시 실행합니다.
---
## 참고 사항
### CORS 설정
- 프론트엔드 접근을 위해 `CORS_ALLOWED_ORIGINS` 환경변수에 `http://20.196.65.160:3000`이 추가되었습니다.
- 필요에 따라 추가 도메인을 콤마(,)로 구분하여 추가할 수 있습니다.
### 포트 매핑
- user-service: 8081
- event-service: 8080
- analytics-service: 8086
- participation-service: 8084
### 환경변수 보안
- 본 가이드는 개발 환경용입니다.
- 운영 환경에서는 비밀번호, JWT 시크릿 등을 환경변수 파일이나 Secret 관리 시스템을 통해 관리해야 합니다.
### Docker 네트워크
- 현재는 호스트 네트워크 모드로 실행됩니다.
- 서비스 간 통신이 필요한 경우 Docker 네트워크를 생성하여 사용하는 것을 권장합니다.
---
## 문제 해결
### 컨테이너가 시작되지 않는 경우
```bash
docker logs {서비스명}
```
### 포트가 이미 사용 중인 경우
```bash
# 포트 사용 프로세스 확인
sudo netstat -tulpn | grep {포트번호}
# 기존 컨테이너 중지
docker stop {서비스명}
```
### 이미지 다운로드 실패
```bash
# Docker 로그인 재시도
docker login acrdigitalgarage01.azurecr.io -u {ID} -p {암호}
# 이미지 pull 재시도
docker pull acrdigitalgarage01.azurecr.io/kt-event-marketing/{서비스명}:latest
```