💻 뚝딱뚝딱/북북클럽
[개발일지 #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
🚀 사용 방법
- 위 명령으로 실행하면 모든 서비스 + 인프라가 컨테이너로 실행됨
- Postman에서 http://localhost:8080 으로 API 테스트 가능
- DB, Redis, Kafka도 도커로 떠 있기 때문에 별도 설치 없이 사용 가능
- 소스 변경 후에는 변경한 서비스만 다시 빌드해주면 됨.
✅ 참고 정리
상황 | 해야 하는 작업 |
특정 서비스 소스만 수정한 경우 | 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 구조에서 각 서비스를 변경할 때마다 아래 작업을 반복하는 건 너무 귀찮다.
- Gradle bootJar 빌드
- Docker 이미지 재빌드
- 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