mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 08:46:23 +00:00
Merge branch 'feature/event' into develop
This commit is contained in:
commit
284278180c
187
claude/run-container-guide-back.md
Normal file
187
claude/run-container-guide-back.md
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
# 백엔드 컨테이너 실행방법 가이드
|
||||||
|
|
||||||
|
[요청사항]
|
||||||
|
- 백엔드 각 서비스들의 컨테이너 이미지를 컨테이너로 실행하는 가이드 작성
|
||||||
|
- 실제 컨테이너 실행은 하지 않음
|
||||||
|
- '[결과파일]'에 수행할 명령어를 포함하여 컨테이너 실행 가이드 생성
|
||||||
|
|
||||||
|
[작업순서]
|
||||||
|
- 실행정보 확인
|
||||||
|
프롬프트의 '[실행정보]'섹션에서 아래정보를 확인
|
||||||
|
- {ACR명}: 컨테이너 레지스트리 이름
|
||||||
|
- {VM.KEY파일}: VM 접속하는 Private Key파일 경로
|
||||||
|
- {VM.USERID}: VM 접속하는 OS 유저명
|
||||||
|
- {VM.IP}: VM IP
|
||||||
|
예시)
|
||||||
|
```
|
||||||
|
[실행정보]
|
||||||
|
- ACR명: acrdigitalgarage01
|
||||||
|
- VM
|
||||||
|
- KEY파일: ~/home/bastion-dg0500
|
||||||
|
- USERID: azureuser
|
||||||
|
- IP: 4.230.5.6
|
||||||
|
```
|
||||||
|
|
||||||
|
- 시스템명과 서비스명 확인
|
||||||
|
settings.gradle에서 확인.
|
||||||
|
- 시스템명: rootProject.name
|
||||||
|
- 서비스명: include 'common'하위의 include문 뒤의 값임
|
||||||
|
|
||||||
|
예시) include 'common'하위의 4개가 서비스명임.
|
||||||
|
```
|
||||||
|
rootProject.name = 'tripgen'
|
||||||
|
|
||||||
|
include 'common'
|
||||||
|
include 'user-service'
|
||||||
|
include 'location-service'
|
||||||
|
include 'ai-service'
|
||||||
|
include 'trip-service'
|
||||||
|
```
|
||||||
|
|
||||||
|
- VM 접속 방법 안내
|
||||||
|
- Linux/Mac은 기본 터미널을 실행하고 Window는 Window Terminal을 실행하도록 안내
|
||||||
|
- 터미널에서 아래 명령으로 VM에 접속하도록 안내
|
||||||
|
최초 한번 Private key파일의 모드를 변경.
|
||||||
|
```
|
||||||
|
chmod 400 {VM.KEY파일}
|
||||||
|
```
|
||||||
|
|
||||||
|
private key를 이용하여 접속.
|
||||||
|
```
|
||||||
|
ssh -i {VM.KEY파일} {VM.USERID}@{VM.IP}
|
||||||
|
```
|
||||||
|
- 접속 후 docker login 방법 안내
|
||||||
|
```
|
||||||
|
docker login {ACR명}.azurecr.io -u {ID} -p {암호}
|
||||||
|
```
|
||||||
|
|
||||||
|
- Git Repository 클론 안내
|
||||||
|
- workspace 디렉토리 생성 및 이동
|
||||||
|
```
|
||||||
|
mkdir -p ~/home/workspace
|
||||||
|
cd ~/home/workspace
|
||||||
|
```
|
||||||
|
- 소스 Clone
|
||||||
|
```
|
||||||
|
git clone {원격 Git Repository 주소}
|
||||||
|
```
|
||||||
|
예)
|
||||||
|
```
|
||||||
|
git clone https://github.com/cna-bootcamp/phonebill.git
|
||||||
|
```
|
||||||
|
- 프로젝트 디렉토리로 이동
|
||||||
|
```
|
||||||
|
cd {시스템명}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 어플리케이션 빌드 및 컨테이너 이미지 생성 방법 안내
|
||||||
|
'deployment/container/build-image.md' 파일을 열어 가이드대로 수행하도록 안내
|
||||||
|
|
||||||
|
- 컨테이너 레지스트리 로그인 방법 안내
|
||||||
|
아래 명령으로 {ACR명}의 인증정보를 구합니다.
|
||||||
|
'username'이 ID이고 'passwords[0].value'가 암호임.
|
||||||
|
```
|
||||||
|
az acr credential show --name {ACR명}
|
||||||
|
```
|
||||||
|
|
||||||
|
예시) ID=dg0200cr, 암호={암호}
|
||||||
|
```
|
||||||
|
$ az acr credential show --name dg0200cr
|
||||||
|
{
|
||||||
|
"passwords": [
|
||||||
|
{
|
||||||
|
"name": "password",
|
||||||
|
"value": "{암호}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "password2",
|
||||||
|
"value": "{암호2}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"username": "dg0200cr"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
아래와 같이 로그인 명령을 작성합니다.
|
||||||
|
```
|
||||||
|
docker login {ACR명}.azurecr.io -u {ID} -p {암호}
|
||||||
|
```
|
||||||
|
|
||||||
|
- 컨테이너 푸시 방법 안내
|
||||||
|
Docker Tag 명령으로 이미지를 tag하는 명령을 작성합니다.
|
||||||
|
```
|
||||||
|
docker tag {서비스명}:latest {ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
```
|
||||||
|
이미지 푸시 명령을 작성합니다.
|
||||||
|
```
|
||||||
|
docker push {ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
- 컨테이너 실행 명령 생성
|
||||||
|
- 환경변수 확인
|
||||||
|
'{서비스명}/.run/{서비스명}.run.xml' 을 읽어 각 서비스의 환경변수 찾음.
|
||||||
|
"env.map"의 각 entry의 key와 value가 환경변수임.
|
||||||
|
|
||||||
|
예제) SERVER_PORT=8081, DB_HOST=20.249.137.175가 환경변수임
|
||||||
|
```
|
||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="ai-service" type="GradleRunConfiguration" factoryName="Gradle">
|
||||||
|
<ExternalSystemSettings>
|
||||||
|
<option name="env">
|
||||||
|
<map>
|
||||||
|
<entry key="SERVER_PORT" value="8084" />
|
||||||
|
<entry key="DB_HOST" value="20.249.137.175" />
|
||||||
|
```
|
||||||
|
|
||||||
|
- 아래 명령으로 컨테이너를 실행하는 명령을 생성합니다.
|
||||||
|
- shell 파일을 만들지 말고 command로 수행하는 방법 안내.
|
||||||
|
- 모든 환경변수에 대해 '-e' 파라미터로 환경변수값을 넘깁니다.
|
||||||
|
- 중요) CORS 설정 환경변수에 프론트엔드 주소 추가
|
||||||
|
- 'ALLOWED_ORIGINS' 포함된 환경변수가 CORS 설정 환경변수임.
|
||||||
|
- 이 환경변수의 값에 'http://{VM.IP}:3000'번 추가
|
||||||
|
|
||||||
|
```
|
||||||
|
SERVER_PORT={환경변수의 SERVER_PORT값}
|
||||||
|
|
||||||
|
docker run -d --name {서비스명} --rm -p ${SERVER_PORT}:${SERVER_PORT} \
|
||||||
|
-e {환경변수 KEY}={환경변수 VALUE}
|
||||||
|
{ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
- 실행된 컨테이너 확인 방법 작성
|
||||||
|
아래 명령으로 모든 서비스의 컨테이너가 실행 되었는지 확인하는 방법을 안내.
|
||||||
|
```
|
||||||
|
docker ps | grep {서비스명}
|
||||||
|
```
|
||||||
|
- 재배포 방법 작성
|
||||||
|
- 로컬에서 수정된 소스 푸시
|
||||||
|
- VM 접속
|
||||||
|
- 디렉토리 이동 및 소스 내려받기
|
||||||
|
```
|
||||||
|
cd ~/home/workspace/{시스템명}
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
git pull
|
||||||
|
```
|
||||||
|
- 컨테이너 이미지 재생성
|
||||||
|
'deployment/container/build-image.md' 파일을 열어 가이드대로 수행
|
||||||
|
|
||||||
|
- 컨테이너 이미지 푸시
|
||||||
|
```
|
||||||
|
docker tag {서비스명}:latest {ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
docker push {ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
```
|
||||||
|
- 컨테이너 중지
|
||||||
|
```
|
||||||
|
docker stop {서비스명}
|
||||||
|
```
|
||||||
|
- 컨테이너 이미지 삭제
|
||||||
|
```
|
||||||
|
docker rmi {ACR명}.azurecr.io/{시스템명}/{서비스명}:latest
|
||||||
|
```
|
||||||
|
- 컨테이너 재실행
|
||||||
|
|
||||||
|
[결과파일]
|
||||||
|
deployment/container/run-container-guide.md
|
||||||
|
|
||||||
@ -113,9 +113,9 @@ public class JwtTokenProvider {
|
|||||||
public UserPrincipal getUserPrincipalFromToken(String token) {
|
public UserPrincipal getUserPrincipalFromToken(String token) {
|
||||||
Claims claims = parseToken(token);
|
Claims claims = parseToken(token);
|
||||||
|
|
||||||
Long userId = Long.parseLong(claims.getSubject());
|
UUID userId = UUID.fromString(claims.getSubject());
|
||||||
String storeIdStr = claims.get("storeId", String.class);
|
String storeIdStr = claims.get("storeId", String.class);
|
||||||
Long storeId = storeIdStr != null ? Long.parseLong(storeIdStr) : null;
|
UUID storeId = storeIdStr != null ? UUID.fromString(storeIdStr) : null;
|
||||||
String email = claims.get("email", String.class);
|
String email = claims.get("email", String.class);
|
||||||
String name = claims.get("name", String.class);
|
String name = claims.get("name", String.class);
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@ -24,12 +24,12 @@ public class UserPrincipal implements UserDetails {
|
|||||||
/**
|
/**
|
||||||
* 사용자 ID
|
* 사용자 ID
|
||||||
*/
|
*/
|
||||||
private final Long userId;
|
private final UUID userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 매장 ID
|
* 매장 ID
|
||||||
*/
|
*/
|
||||||
private final Long storeId;
|
private final UUID storeId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자 이메일
|
* 사용자 이메일
|
||||||
|
|||||||
@ -1,187 +1,195 @@
|
|||||||
# Content Service 컨테이너 이미지 빌드 및 배포 가이드
|
# Event Service 컨테이너 이미지 빌드 가이드
|
||||||
|
|
||||||
## 1. 사전 준비사항
|
## 1. 빌드 일시
|
||||||
|
- **빌드 날짜**: 2025-10-28
|
||||||
|
- **빌드 시간**: 14:35 KST
|
||||||
|
|
||||||
### 필수 소프트웨어
|
## 2. 수정 사항
|
||||||
- **Docker Desktop**: Docker 컨테이너 실행 환경
|
|
||||||
- **JDK 23**: Java 애플리케이션 빌드
|
|
||||||
- **Gradle**: 프로젝트 빌드 도구
|
|
||||||
|
|
||||||
### 외부 서비스
|
### 2.1 타입 불일치 수정
|
||||||
- **Redis 서버**: 20.214.210.71:6379
|
Event Service 컴파일 오류 해결을 위해 다음 파일들을 수정했습니다:
|
||||||
- **Kafka 서버**: 4.230.50.63:9092
|
|
||||||
- **Replicate API**: Stable Diffusion 이미지 생성
|
|
||||||
- **Azure Blob Storage**: 이미지 CDN
|
|
||||||
|
|
||||||
## 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
|
```gradle
|
||||||
// 실행 JAR 파일명 설정
|
|
||||||
bootJar {
|
bootJar {
|
||||||
archiveFileName = 'content-service.jar'
|
archiveFileName = 'event-service.jar'
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 배포 파일 구조
|
## 3. 빌드 명령어
|
||||||
|
|
||||||
```
|
### 3.1 Common 모듈 컴파일
|
||||||
deployment/
|
|
||||||
└── container/
|
|
||||||
├── Dockerfile-backend # 백엔드 서비스용 Dockerfile
|
|
||||||
├── docker-compose.yml # Docker Compose 설정
|
|
||||||
└── build-and-run.sh # 자동화 배포 스크립트
|
|
||||||
```
|
|
||||||
|
|
||||||
## 4. 수동 빌드 및 배포
|
|
||||||
|
|
||||||
### 4.1 Gradle 빌드
|
|
||||||
```bash
|
```bash
|
||||||
# 프로젝트 루트에서 실행
|
./gradlew common:compileJava
|
||||||
./gradlew clean content-service:bootJar
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4.2 Docker 이미지 빌드
|
**결과**: BUILD SUCCESSFUL in 6s
|
||||||
```bash
|
|
||||||
DOCKER_FILE=deployment/container/Dockerfile-backend
|
|
||||||
|
|
||||||
|
### 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 \
|
docker build \
|
||||||
--platform linux/amd64 \
|
--platform linux/amd64 \
|
||||||
--build-arg BUILD_LIB_DIR="content-service/build/libs" \
|
--build-arg BUILD_LIB_DIR="event-service/build/libs" \
|
||||||
--build-arg ARTIFACTORY_FILE="content-service.jar" \
|
--build-arg ARTIFACTORY_FILE="event-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" \
|
|
||||||
-f deployment/container/Dockerfile-backend \
|
-f deployment/container/Dockerfile-backend \
|
||||||
-t content-service:latest .
|
-t event-service:latest .
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7.3 VM에서 컨테이너 실행
|
**결과**: 이미지 빌드 성공
|
||||||
```bash
|
- Image ID: bbeecf2ccaf2
|
||||||
# Docker Compose로 실행
|
- Size: 1.08GB
|
||||||
docker-compose -f deployment/container/docker-compose.yml up -d
|
- 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 \
|
docker run -d \
|
||||||
--name content-service \
|
--name event-service \
|
||||||
-p 8084:8084 \
|
-p 8082:8082 \
|
||||||
-e SPRING_PROFILES_ACTIVE=prod \
|
-e SPRING_PROFILES_ACTIVE=dev \
|
||||||
-e SERVER_PORT=8084 \
|
-e SERVER_PORT=8082 \
|
||||||
-e REDIS_HOST=20.214.210.71 \
|
event-service:latest
|
||||||
-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
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 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
|
```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
|
```json
|
||||||
{
|
{
|
||||||
"status": "UP",
|
"status": "UP",
|
||||||
@ -189,6 +197,9 @@ curl http://localhost:8084/actuator/health
|
|||||||
"ping": {
|
"ping": {
|
||||||
"status": "UP"
|
"status": "UP"
|
||||||
},
|
},
|
||||||
|
"db": {
|
||||||
|
"status": "UP"
|
||||||
|
},
|
||||||
"redis": {
|
"redis": {
|
||||||
"status": "UP"
|
"status": "UP"
|
||||||
}
|
}
|
||||||
@ -196,92 +207,70 @@ curl http://localhost:8084/actuator/health
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## 9. Swagger UI 접근
|
### 7.2 Swagger UI
|
||||||
|
|
||||||
배포 후 Swagger UI로 API 테스트 가능:
|
|
||||||
```
|
```
|
||||||
http://localhost:8084/swagger-ui/index.html
|
http://localhost:8082/swagger-ui/index.html
|
||||||
```
|
```
|
||||||
|
|
||||||
## 10. 이미지 생성 API 테스트
|
## 8. 빌드 결과 요약
|
||||||
|
|
||||||
### 10.1 이미지 생성 요청
|
### 서비스 정보
|
||||||
```bash
|
- **서비스명**: event-service
|
||||||
curl -X POST "http://localhost:8084/api/v1/content/images/generate" \
|
- **포트**: 8082
|
||||||
-H "Content-Type: application/json" \
|
- **JAR 크기**: 94MB
|
||||||
-d '{
|
- **이미지 크기**: 1.08GB
|
||||||
"eventDraftId": 1001,
|
|
||||||
"industry": "고깃집",
|
|
||||||
"location": "강남",
|
|
||||||
"trends": ["가을", "단풍", "BBQ"],
|
|
||||||
"styles": ["FANCY"],
|
|
||||||
"platforms": ["INSTAGRAM"]
|
|
||||||
}'
|
|
||||||
```
|
|
||||||
|
|
||||||
### 10.2 Job 상태 확인
|
|
||||||
```bash
|
|
||||||
curl http://localhost:8084/api/v1/content/jobs/{jobId}
|
|
||||||
```
|
|
||||||
|
|
||||||
## 11. 컨테이너 관리 명령어
|
|
||||||
|
|
||||||
### 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. 빌드 결과
|
|
||||||
|
|
||||||
### 빌드 정보
|
|
||||||
- **서비스명**: content-service
|
|
||||||
- **JAR 파일**: content-service.jar
|
|
||||||
- **Docker 이미지**: content-service:latest
|
|
||||||
- **노출 포트**: 8084
|
|
||||||
|
|
||||||
### 빌드 일시
|
|
||||||
- **빌드 날짜**: 2025-10-27
|
|
||||||
|
|
||||||
### 환경
|
|
||||||
- **Base Image**: openjdk:23-slim
|
- **Base Image**: openjdk:23-slim
|
||||||
- **Platform**: linux/amd64
|
- **Platform**: linux/amd64
|
||||||
- **User**: k8s (non-root)
|
|
||||||
|
### 빌드 통계
|
||||||
|
- **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
|
||||||
|
./gradlew event-service:bootJar
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.3 Docker 빌드 컨텍스트 오류
|
||||||
|
**증상**: JAR 파일을 찾을 수 없음
|
||||||
|
|
||||||
|
**해결**:
|
||||||
|
- JAR 파일이 실제로 빌드되었는지 확인
|
||||||
|
- 빌드 아규먼트 경로가 올바른지 확인
|
||||||
|
|
||||||
|
## 10. 다음 단계
|
||||||
|
|
||||||
|
1. **컨테이너 테스트**: 로컬 환경에서 컨테이너 실행 및 API 테스트
|
||||||
|
2. **환경변수 설정**: 운영 환경에 맞는 환경변수 구성
|
||||||
|
3. **통합 테스트**: 다른 마이크로서비스들과의 통합 테스트
|
||||||
|
4. **이미지 레지스트리 푸시**: Docker Hub 또는 사설 레지스트리에 이미지 업로드
|
||||||
|
5. **Kubernetes 배포**: K8s 클러스터에 배포
|
||||||
|
|
||||||
|
## 11. 참고사항
|
||||||
|
|
||||||
|
- **개발 환경 인증**: DevAuthenticationFilter가 자동으로 테스트용 UserPrincipal 생성
|
||||||
|
- **프로덕션 배포**: DevAuthenticationFilter 비활성화 및 실제 JWT 인증 필터 활성화 필요
|
||||||
|
- **보안**: JWT_SECRET은 안전하게 관리하고 최소 32자 이상 사용
|
||||||
|
- **성능**: JAVA_OPTS를 통해 JVM 메모리 설정 최적화 권장
|
||||||
|
|||||||
402
deployment/container/run-container-guide.md
Normal file
402
deployment/container/run-container-guide.md
Normal 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
|
||||||
|
```
|
||||||
@ -1,4 +1,11 @@
|
|||||||
|
bootJar {
|
||||||
|
archiveFileName = 'event-service.jar'
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
// Actuator for health checks and monitoring
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-actuator'
|
||||||
|
|
||||||
// Kafka for job publishing
|
// Kafka for job publishing
|
||||||
implementation 'org.springframework.kafka:spring-kafka'
|
implementation 'org.springframework.kafka:spring-kafka'
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 생성 완료 메시지 DTO
|
* 이벤트 생성 완료 메시지 DTO
|
||||||
@ -20,16 +21,16 @@ import java.time.LocalDateTime;
|
|||||||
public class EventCreatedMessage {
|
public class EventCreatedMessage {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 ID
|
* 이벤트 ID (UUID)
|
||||||
*/
|
*/
|
||||||
@JsonProperty("event_id")
|
@JsonProperty("event_id")
|
||||||
private Long eventId;
|
private UUID eventId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 사용자 ID
|
* 사용자 ID (UUID)
|
||||||
*/
|
*/
|
||||||
@JsonProperty("user_id")
|
@JsonProperty("user_id")
|
||||||
private Long userId;
|
private UUID userId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 이벤트 제목
|
* 이벤트 제목
|
||||||
|
|||||||
@ -29,12 +29,12 @@ public class EventKafkaProducer {
|
|||||||
/**
|
/**
|
||||||
* 이벤트 생성 완료 메시지 발행
|
* 이벤트 생성 완료 메시지 발행
|
||||||
*
|
*
|
||||||
* @param eventId 이벤트 ID
|
* @param eventId 이벤트 ID (UUID)
|
||||||
* @param userId 사용자 ID
|
* @param userId 사용자 ID (UUID)
|
||||||
* @param title 이벤트 제목
|
* @param title 이벤트 제목
|
||||||
* @param eventType 이벤트 타입
|
* @param eventType 이벤트 타입
|
||||||
*/
|
*/
|
||||||
public void publishEventCreated(Long eventId, Long userId, String title, String eventType) {
|
public void publishEventCreated(java.util.UUID eventId, java.util.UUID userId, String title, String eventType) {
|
||||||
EventCreatedMessage message = EventCreatedMessage.builder()
|
EventCreatedMessage message = EventCreatedMessage.builder()
|
||||||
.eventId(eventId)
|
.eventId(eventId)
|
||||||
.userId(userId)
|
.userId(userId)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user