💻 뚝딱뚝딱/북북클럽

[개발일지 #046] 도커(Docker)로 MSA 통합 실행 환경 구축하기 (+ 자동화 스크립트)

뚜루리 2025. 6. 18. 17:12
728x90
320x100

 

✨ 왜 도커(Docker)로 MSA 통합 실행 환경 구축하는지

현재 BookBookClub 프로젝트는 MSA 기반으로 구성되어 있어서 서비스가 user, post, notification, gateway 등 여러 개로 나뉨.근데 개발하거나 테스트할 때 각각 IntelliJ에서 따로 켜는 게 너무 번거롭고 비효율적이여서  Docker + docker-compose로 한 번에 통합 실행되게 설정함!
  • Docker: 애플리케이션을 컨테이너라는 단위로 포장해 어디서든 실행 가능하게 해주는 도구.
  • Docker Compose: 여러 컨테이너를 정의하고 한 번에 실행할 수 있는 설정 파일(docker-compose.yml) 포맷.

 

🛠️ 구현 방법

1. 각 서비스에 Dockerfile 작성

# 1. Java 17이 설치된 베이스 이미지 사용
FROM openjdk:17-jdk-slim

# 2. 작업 디렉토리 생성 및 이동
WORKDIR /app

# 3. 빌드된 JAR 파일을 컨테이너에 복사
COPY build/libs/bbc-user-service-0.0.1-SNAPSHOT.jar app.jar

# 4. 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "app.jar"]
  • 각 서비스에 모두 만들어 줌.
 

2. docker-compose.yml 작성

version: '3'
services:
  # 🐘 MySQL: 모든 서비스에서 사용하는 RDB
  mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "3307:3306"
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: bookbookclub
    volumes:
      - mysql-data:/var/lib/mysql

  # 🧠 Redis: 이메일 인증, 토큰 저장 등 캐시용
  redis:
    image: redis:7.2
    container_name: redis
    ports:
      - "6379:6379"

  # 🦍 Zookeeper: Kafka 브로커 관리를 위한 필수 서비스
  zookeeper:
    image: confluentinc/cp-zookeeper:7.4.0
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  # 📣 Kafka: 비동기 메시지 통신 (알림, 이벤트 처리)
  kafka:
    image: confluentinc/cp-kafka:7.4.0
    container_name: kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
    depends_on:
      - zookeeper

  # 👤 사용자 서비스
  user-service:
    build: ./bbc-user-service
    container_name: user-service
    ports:
      - "8081:8081"
    depends_on:
      - mysql
      - redis
    environment:
      SPRING_PROFILES_ACTIVE: docker

  # 📝 게시글 서비스
  post-service:
    build: ./bbc-post-service
    container_name: post-service
    ports:
      - "8082:8082"
    depends_on:
      - mysql
      - kafka
    environment:
      SPRING_PROFILES_ACTIVE: docker

  # 📢 알림 서비스
  notification-service:
    build: ./bbc-notification-service
    container_name: notification-service
    ports:
      - "8083:8083"
    depends_on:
      - kafka
    environment:
      SPRING_PROFILES_ACTIVE: docker

  # 🚪 API Gateway: 요청 라우팅 + 인증 처리
  gateway:
    build: ./bbc-gateway
    container_name: gateway
    ports:
      - "8080:8080"
    depends_on:
      - user-service
      - post-service
    environment:
      SPRING_PROFILES_ACTIVE: docker

volumes:
  mysql-data:

 

3. build & 실행

# 각 서비스 jar 빌드
./gradlew :bbc-user-service:bootJar
./gradlew :bbc-post-service:bootJar
./gradlew :bbc-notification-service:bootJar
./gradlew :bbc-gateway:bootJar

# 통합 실행
docker compose up --build

 

 

🚀 사용 방법

  1. 위 명령으로 실행하면 모든 서비스 + 인프라가 컨테이너로 실행됨
  2. Postman에서 http://localhost:8080 으로 API 테스트 가능
  3. DB, Redis, Kafka도 도커로 떠 있기 때문에 별도 설치 없이 사용 가능
  4. 소스 변경 후에는 변경한 서비스만 다시 빌드해주면 됨.

 

✅ 참고 정리

상황 해야 하는 작업
특정 서비스 소스만 수정한 경우 bootJar + docker compose up --build [서비스명]
공통 모듈(bbc-common) 수정 시 의존하는 서비스들 전부 재빌드 필요
모든 서비스 코드 싹 수정한 경우 그냥 ./gradlew build + docker compose up --build 추천

 

 

✅ 장점

  • 모든 MSA 서비스 & 인프라를 한 번에 실행 가능
  • 실무에서 사용되는 도커 환경에 익숙해질 수 있음
  • 배포나 CI/CD에도 이어질 수 있는 기반을 마련

❌ 단점 / 주의할 점

  • 처음에는 설정이 번거롭고 익숙하지 않음
  • 소스 코드 변경 시 bootJar 다시 빌드 + 도커 이미지 재실행 필요
  • 포트 충돌, 캐시 이슈 등 트러블슈팅이 자주 필요함

 

🧠 팁

도커 정리 명령어

docker container prune      # 중지된 컨테이너 정리
docker volume prune         # 안 쓰는 볼륨 정리
docker compose down         # 전체 종료

에러: port already in use → 포트 변경하거나 로컬 MySQL 꺼줘야 함

 

🔁 완전 새로고침하고 싶을 때

docker compose down
./gradlew build
docker compose up --build

 

 


🛠️ MSA 개발 효율을 위한 자동화 스크립트 - rebuild.sh

 

✨ 목적

MSA 구조에서 각 서비스를 변경할 때마다 아래 작업을 반복하는 건 너무 귀찮다.

  1. Gradle bootJar 빌드
  2. Docker 이미지 재빌드
  3. Docker Compose 재실행

👉 이를 한 번에 처리하는 자동화 스크립트를 만들어 작업 효율을 높임.

 

📄 스크립트 코드

#!/bin/bash

# 서비스 목록 정의
SERVICES=("user-service" "post-service" "notification-service" "gateway")

echo "🔨 Gradle bootJar 빌드 시작 (전체 서비스)"
for SERVICE in "${SERVICES[@]}"
do
  echo "👉 빌드 중: bbc-$SERVICE"
  ./gradlew ":bbc-$SERVICE:bootJar"
  if [ $? -ne 0 ]; then
    echo "❌ Gradle 빌드 실패: bbc-$SERVICE"
    exit 1
  fi
done

echo "🐳 Docker Compose 전체 서비스 재빌드 & 실행"
docker compose up --build

 

 

 

✅ 사용 방법

  •  1. 저장 위치 : 프로젝트 루트 (BookBookClub-MSA)에 rebuild.sh 파일 저장
  •  2. 실행 권한 부여 chmod +x rebuild.sh
  •  3. 실행 ./rebuild.sh
 
 

💡 스크립트 동작 요약

단계 설명
1️⃣ Gradle 빌드 bbc-user-service, bbc-post-service, 등 전체 bootJar 빌드
2️⃣ Docker 재실행 docker compose up --build로 전체 서비스 재시작
⛔ 실패 시 해당 서비스 빌드 실패 시 즉시 중단
 

✅ 장점

  • 매번 서비스별로 수동 빌드할 필요 없음
  • 실수로 누락되는 빌드 방지
  • MSA 구조에서도 빠른 통합 테스트 가능
  • CI/CD 적용 전에 로컬 자동화의 첫걸음

 

🚨 단점 & 보완 아이디어

항목 설명
전체 빌드라 시간이 좀 걸릴 수 있음 → 선택적 서비스 빌드 버전도 나중에 추가 가능
jar 파일만 바뀐 경우 굳이 전체 빌드는 과함 → 변경된 서비스만 추적해서 빌드 가능하도록 확장 가능

 

728x90
320x100