[Spotify Web API 5편] Docker 및 공통모듈 세팅

2026. 6. 7. 21:44·개인 프로젝트

5편에서는 구현전에 해놔야 하는 것들을 했다.

  • 각 서비스의 Dockerfile
  • docker-compose.yml
  • 공통에러, 응답 처리
  • 모든 서비스 연동 확인
  • 컨피그 Repo에 설정 파일 추가

내일부터는 밴드 서비스 -> 위키 서비스 -> 게이트웨이 및 유저 서비스 -> 챗 서비스 -> CI 구현 -> 배포 -> 모니터링 -> 프런트 개발 순서로 진행할 것이다.

아래 토글(더보기)은 개발 체크리스트이다.

더보기

BandFeed 개발 체크리스트

0단계 — 사전 준비

  • [x] API / 테이블 / 인프라 설계서 작성
  • [x] GitHub 레포 생성 (BandFeed, BandFeed-config)
  • [x] 모노레포 멀티모듈 구성 (Gradle)
  • [x] Config 레포 생성 및 Config Server 연동
  • [x] .gitignore / .env 설정
  • [x] Docker Compose 구성 (MySQL, Kafka, Redis, 모니터링 profile)
  • [x] 각 서비스 Dockerfile 작성 (7개)

1단계 — MSA 인프라 및 핵심 비즈니스 구축 (Base MVP)

인프라

  • [x] Eureka Server 구축 및 동작 확인
  • [x] Config Server 구축 및 각 서비스 yml 연동
  • [x] Gateway Service 생성 및 유레카 등록
  • [x] 공통 모듈 구성
    • [x] BaseEntity (Auditing)
    • [x] ErrorCode 인터페이스
    • [x] BusinessException
    • [x] CommonErrorCode
    • [x] CommonResponse<T>
    • [x] GlobalExceptionHandler

서비스 생성 및 유레카 등록

  • [x] User Service
  • [x] Band Service
  • [x] Wiki Service (Post/Song)
  • [x] Chat Service

Band Service — 핵심 기능 구현

  • [ ] 도메인 설계 (Entity, Repository)
  • [ ] Spotify API 연동
  • [ ] Band CRUD API

Wiki Service — 핵심 기능 구현

  • [ ] 도메인 설계 (Entity, Repository)
  • [ ] Post/Song 위키형 게시판 CRUD API (인증 없이 우선 개발)
  • [ ] Resilience4j 서킷 브레이커 적용
  • [ ] @Retryable 재시도 로직 적용 및 검증

2단계 — 게이트웨이 라우팅/보안 및 커뮤니티 확장 (Feature MVP)

Gateway 라우팅 및 인증

  • [ ] 각 서비스로의 라우팅(Routing) 설정
  • [ ] User Service 로그인/회원가입 구현
  • [ ] Gateway에서 JWT 토큰 발급·검증 흐름 완성
  • [ ] X-User-Id 헤더 전달 필터 구현

인증 기반 기능

  • [ ] BandMember 매핑 구현
  • [ ] 프라이빗 타임라인 (접근 제어) 구현

Chat Service

  • [ ] WebSocket + STOMP 개념 학습
  • [ ] 1:1 DM 기능 구현
  • [ ] Kafka 연동 (메시지 이벤트)

기타

  • [ ] FeignClient 서비스 간 통신 구현
  • [ ] 이벤트 기반 로직 구현 (Kafka)
  • [ ] 통합 시나리오 테스트용 .http 파일 작성

3단계 — 인프라 고도화 및 아키텍처 검증 (Architecture MVP)

배포

  • [ ] GitHub Actions CI 파이프라인 구축
  • [ ] Docker 기반 AWS 멀티 컨테이너 CD 구현
  • [ ] 배포 환경 동작 확인

모니터링

  • [ ] Actuator + Prometheus 엔드포인트 설정
  • [ ] Loki + Promtail 로그 수집 설정
  • [ ] Grafana 대시보드 구성
  • [ ] Alertmanager Slack 알림 설정

성능 검증

  • [ ] JMeter / k6 부하테스트 환경 구성
  • [ ] 외부 API 지연 시 서킷 브레이커 Fallback 검증
  • [ ] Redis 캐싱 적용 전후 TPS 비교

프런트엔드

  • [ ] 프론트 개발
  • [ ] 프론트 배포
  • [ ] 프론트로 동작 테스트
  • [ ] 버그 수정

마무리

  • [ ] 실사용자 배포
  • [ ] 피드백 수집 및 반영

오늘 배운 것

1. 도커 컴포즈 구성시, 변수처럼 묶어서 설정을 적용할 수도 있다.

x-java-tz: &java-tz
  TZ: Asia/Seoul
  JAVA_TOOL_OPTIONS: -Duser.timezone=Asia/Seoul

x-common-service: &common-service
  depends_on:
    eureka-server:
      condition: service_healthy
    config-server:
      condition: service_healthy
    mysql:
      condition: service_healthy
  networks:
    - bandfeed-network
    
  band-service:
    build:
      context: .
      dockerfile: apps/band-service/Dockerfile
    container_name: bandfeed-band
    ports:
      - "${BAND_SERVER_PORT}:9020"
    environment:
      <<: *java-tz
      SERVER_PORT: 9020
      SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/${MYSQL_BAND_DB}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
      SPRING_DATASOURCE_USERNAME: ${MYSQL_USER}
      SPRING_DATASOURCE_PASSWORD: ${MYSQL_PASSWORD}
      EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka/
      CONFIG_SERVER_URL: ${CONFIG_SERVER_URL}
    <<: *common-service

 

- 모든 서비스의 공통으로 적용되는 타임존 설정
- 핵심 비즈니스 로직을 처리하는 마이크로 서비스에 적용하는 depends-on 설정

2. 도커 컴포즈 구성 시, 프로필 설정으로 원하는 서비스만 실행

  prometheus:
    image: prom/prometheus:v2.53.0
    container_name: bandfeed-prometheus
    profiles: ["monitoring"]
    environment:
      - TZ=Asia/Seoul
    ports:
      - "${PROMETHEUS_PORT}:9090"
    volumes:
      - ./monitoring/prometheus/prometheus.yaml:/etc/prometheus/prometheus.yaml
      - ./monitoring/prometheus/alert-rules.yaml:/etc/prometheus/alert-rules.yaml
      - prometheus-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
      - '--storage.tsdb.retention.time=14d'
    restart: unless-stopped
    networks:
      - bandfeed-network

- profiles: ["프로필명"]을 추가했다.

docker-compose up -d
docker-compose --profile monitoring up -d

모니터링 서비스는 내가 설계한 개발 순서상, 나중에 사용하기에
지금 사용할 서비스만 도커 컴포즈로 실행할 수 있도록 했다.
이후 모니터링 관련 이미지도 포함하여 실행하고 싶다면 --profile monitoring을 추가하면 된다.

 

3. 컨피그 Repo에 있어야 하는 설정과 각 서비스에서 가지고 있어야 할 설정

# 각 서비스가 가져야할 설정들
spring:
  application:
    name: band-service        # Config server가 이 이름으로 파일을 찾음
  config:
    import: optional:configserver:http://localhost:8888  # Config server 연결

server:
  port: 9020   # 로컬 실행 시 fallback 포트

# 컨피그 Repo에 넣어야 할 설정들
spring:
  datasource:		# DB 접속 정보
    url: jdbc:mysql://mysql:3306/band_db
    username: bandfeed
    password: secret
  jpa:
    hibernate:
      ddl-auto: update

# 서비스 디스커버리
eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8761/eureka/

# 외부 서비스 URL, 각종 키, feature flag 등

DB 정보같이 각 서비스별로 달라지는 설정들은 컨피그 Repo에서 관리한다.

 

4. 모니터링 개념 및 방식

각 서비스(Spring Boot)
    ↓ /actuator/prometheus (메트릭)
Prometheus (수집)
    ↓
Grafana (시각화)

각 서비스(로그)
    ↓ Docker 컨테이너 로그
Promtail (수집)
    ↓
Loki (저장)
    ↓
Grafana (시각화)

5. 공통 에러 처리

  • ErrorCode 객체를 인터페이스로 선언.
  • BusinessException에서 ErrorCode를 생성자 주입받음.
  • 각 서비스에서 enum 객체를 생성 후 ErrorCode를 구현.
  • 예외 발생 시, GlobalExceptionHandler에서 가로채어 예외 반환.
  • 예외 반환 시, CommonResponse로 형식이 통일되어 반환됨.

 

 

6. 공통 모듈 자체의 jar 파일 생성 문제

 

문제 상황

 

Gradle> bandfeed> Tasks> build> build 중 문제 발생!

- 에러 로그

Error while evaluating property 'mainClass' of task ':apps:bootJar'.
> Main class name has not been configured and it could not be resolved

 

문제는 apps 모듈의 jar파일을 생성하는데, main 클래스가 없다는 점이었다.


분석

 

- 루트 폴더의 build.gradle의 일부분

// 루트 모듈을 제외한 하위 프로젝트 공통 설정
subprojects {
    apply plugin: 'java'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'

    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(21)
        }
    }

    configurations {
        compileOnly {
            extendsFrom annotationProcessor
        }
    }

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    }

    tasks.named('test') {
        useJUnitPlatform()
    }
}

루트 폴더 하위의 모듈들에게 공통 의존성을 추가하는 부분이다.
근데 setting.gradle 설정 때문에 apps 자체도 모듈이 된다.

rootProject.name = 'bandfeed'

include 'common'
include 'apps:config-server'
include 'apps:eureka-server'
include 'apps:gateway-service'
include 'apps:band-service'
include 'apps:user-service'
include 'apps:wiki-service'
include 'apps:chat-service'

apps:라고 prefix를 둔 순간 gradle이 apps라는 중간 부모 모듈을 만든다.

 

조치 및 해결

 

- apps 모듈의 자체 jar 파일 생성기능을 비활성화

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.5.14'
    id 'io.spring.dependency-management' version '1.1.7'
}

// root project 실행 가능 Jar 파일 생성기능 Off
bootJar.enabled = false

// subprojects 설정(루트 프로젝트 하위 모듈 서비스들 공통 설정)


// 모듈의 기본 jar 파일 생성기능 off
project(':common') {
    bootJar.enabled = false
    jar.enabled = true
}

project(':apps') {
    bootJar.enabled = false
    jar.enabled = false
}

// 나머지 서비스들 플러그인 적용(gradle 감지)

 

subprojects에 대상으로 포함되어도 jar파일을 생성하지 않게 함으로써 에러를 해결했다.

 

'개인 프로젝트' 카테고리의 다른 글

[Spotify Web API 7편] 배포 방법 구상  (0) 2026.06.15
[Spotify Web API 6편] Band 서비스 구현  (0) 2026.06.10
[Spotify Web API 4편] MSA 프로젝트 초기 세팅  (0) 2026.06.07
[Spotify Web API 3편] 애그리거트 경계 설정 및 SA 문서 작성  (0) 2026.06.06
[Spotify Web API 2편] API 분석  (0) 2026.06.05
'개인 프로젝트' 카테고리의 다른 글
  • [Spotify Web API 7편] 배포 방법 구상
  • [Spotify Web API 6편] Band 서비스 구현
  • [Spotify Web API 4편] MSA 프로젝트 초기 세팅
  • [Spotify Web API 3편] 애그리거트 경계 설정 및 SA 문서 작성
MvA
MvA
백엔드 개발자 김재현입니다. 주로 공부하면서 느낀점을 기록합니다.
  • MvA
    Man vs Ai
    MvA
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • Java (6)
      • Python (8)
        • 딥러닝 (1)
        • 머신러닝 (7)
      • JavaScript (2)
      • 내배캠 (60)
      • 개인 프로젝트 (11)
      • 책 후기 (5)
      • 기타 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    머신러닝
    배포
    내일배움캠프
    TiL
    딥러닝
    Riot API
    아키텍처
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
MvA
[Spotify Web API 5편] Docker 및 공통모듈 세팅
상단으로

티스토리툴바