BindProject

구현된 모든 서비스를 컨테이너화 시키는 여정기

dding-shark 2025. 8. 5. 15:57
728x90

로컬 개발 환경의 지옥, 그리고 Docker의 등장

MSA가 제공하는 수많은 장점에도 불구하고, 개발 단계에서는 여러 서비스와 데이터베이스, 메시지 큐 등을 모두 로컬 머신에 띄워야 하는 '개발 환경의 지옥'을 마주하게 됩니다. 각 서비스의 의존성, 포트 충돌, 설정의 파편화는 개발자의 생산성을 심각하게 저하시키는 주범이죠.

저희 프로젝트 역시 인증, 메일, 사용자 프로필, 이미지, 합주실 정보/예약 등 수많은 서비스와 MySQL, Redis, Kafka, RabbitMQ 등 다양한 인프라를 사용하고 있었습니다. 이를 해결하기 위해 저희는 Docker와 Docker Compose를 도입하여, 명령어 한 줄로 전체 개발 환경을 일관성 있게 구축하는 것을 목표로 삼았습니다.

핵심 전략 1: 관심사 분리를 통한 docker-compose 파일 모듈화

가장 먼저 저희가 한 일은 거대한 docker-compose.yml 파일을 기능과 관심사에 따라 여러 개로 분리하는 것이었습니다. 모든 것을 한 파일에 담는 것은 가독성과 유지보수성을 해치는 지름길입니다.

저희는 다음과 같이 파일을 분리했습니다.

  • docker-compose.infra.yml: MySQL, Redis, Kafka 등 모든 서비스가 공유하는 핵심 인프라를 정의합니다.
  • docker-compose.service.yml: 인증, 메일, 이미지 등 공통 핵심 서비스를 정의합니다.
  • docker-compose.bandroom.yml: '합주실' 도메인에 특화된 서비스들을 별도로 정의합니다.
  • docker-compose.gateway.yml: Nginx, Certbot 등 외부 트래픽을 처리하는 게이트웨이를 정의합니다.
# docker-compose.infra.yml 예시
version: '3.7'

services:
  mysql:
    image: mysql:8
    container_name: mysql
    # ... (포트, 볼륨, 네트워크 설정)
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
      # ...

  redis:
    image: redis:7
    # ...

# ... (Kafka, Zookeeper 등 나머지 인프라)

networks:
  app-network:
    external: true

이러한 분리 덕분에 개발자는 필요한 부분만 선택적으로 실행할 수 있습니다. 예를 들어, 인프라만 실행하고 싶다면 docker-compose -f docker-compose.infra.yml up 명령어를, 전체 시스템을 실행하고 싶다면 여러 파일을 동시에 지정하여 실행하면 됩니다. 이는 팀원 간의 협업 효율을 극대화합니다.

핵심 전략 2: 재사용성을 극대화한 공용 Dockerfile

저희 프로젝트의 모든 Spring Boot 기반 마이크로서비스는 거의 동일한 빌드 및 실행 과정을 가집니다. 각 서비스마다 Dockerfile을 만드는 것은 명백한 중복이고 낭비였습니다.

저희는 이 문제를 단 하나의 공용 service.Dockerfile을 만들어 해결했습니다.

# service.Dockerfile
# 1. 베이스 이미지 선택 (Java 21 환경)
FROM openjdk:21-jdk-slim

# 2. 빌드 컨텍스트에서 빌드할 모듈의 경로를 인자로 받음
ARG MODULE_PATH

# 3. Gradle 빌드 실행
WORKDIR /app
COPY . .
RUN ./gradlew :${MODULE_PATH}:bootJar

# 4. 빌드된 JAR 파일 경로 설정
ARG JAR_FILE=build/libs/*.jar

# 5. 컨테이너가 시작될 때 실행할 명령어 정의
ENTRYPOINT ["java", "-jar", "app.jar"]

그리고 docker-compose.yml 파일에서는 build 컨텍스트의 args를 사용하여 어떤 모듈을 빌드할지 동적으로 지정해줍니다.

# docker-compose.service.yml의 auth-service 예시
services:
  auth-service:
    build:
      context: . # 프로젝트 루트를 빌드 컨텍스트로 사용
      dockerfile: service.Dockerfile # 공용 Dockerfile 지정
      args:
        MODULE_PATH: service:auth # :service:auth 모듈을 빌드하도록 인자 전달
    container_name: auth-service
    # ...

이 전략 덕분에 모든 서비스의 빌드 환경을 한 곳에서 관리할 수 있게 되었고, 새로운 서비스가 추가되더라도 Dockerfile을 새로 작성할 필요 없이 docker-compose.yml에 몇 줄만 추가하면 되니 확장성이 크게 향상되었습니다.

핵심 전략 3: .env를 활용한 설정 중앙화 및 보안 강화

DB 접속 정보, JWT 시크릿 키, 포트 번호 등 민감하거나 변경이 잦은 설정 값들을 docker-compose.yml 파일에 하드코딩하는 것은 매우 위험하고 비효율적입니다.

저희는 모든 설정 값을 .env 파일에 정의하고, docker-compose.yml에서는 이 변수들을 참조(${...})하도록 구성했습니다.

.env 파일 예시

AUTH_PORT=8081
MYSQL_AUTHDATABASE=auth_db
AUTH_DB_USERNAME=auth_user
AUTH_DB_PASSWORD=secret_password
TOKEN_KEY=your_super_secret_jwt_key
...

docker-compose.service.yml 참조 예시

auth-service:
    # ...
    ports:
      - "${AUTH_PORT}:${AUTH_PORT}"
    environment:
      - SERVER_PORT=${AUTH_PORT}
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_AUTHDATABASE}?useSSL=false
      - SPRING_DATASOURCE_USERNAME=${AUTH_DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${AUTH_DB_PASSWORD}
      - JWT_SECRET=${TOKEN_KEY}

이 방식은 보안을 강화할 뿐만 아니라(.env 파일은 Git에 포함시키지 않음), 각 개발자가 자신의 로컬 환경에 맞게 설정을 쉽게 변경할 수 있는 유연성을 제공합니다.

핵심 전략 4: healthcheckdepends_on을 이용한 안정적인 서비스 실행 순서 보장

마이크로서비스는 서로에게 의존합니다. 애플리케이션 컨테이너가 시작되기 전에 데이터베이스나 메시지 큐가 먼저 준비되어야 하죠. depends_on만으로는 컨테이너 시작 순서만 제어할 뿐, 내부 애플리케이션이 완전히 준비되었는지는 보장할 수 없습니다.

저희는 docker-compose.infra.ymlmysql, redis 등에 healthcheck 옵션을 추가하여 이 문제를 해결했습니다.

# docker-compose.infra.yml의 mysql 서비스
  mysql:
    # ...
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

healthcheck를 통해 MySQL 서버가 실제로 핑(ping)에 응답할 준비가 되었을 때 'healthy' 상태가 되도록 설정했습니다. 서비스 컨테이너에서는 depends_oncondition: service_healthy를 추가하여, 의존하는 인프라가 'healthy' 상태가 된 이후에 시작되도록 제어함으로써 실행 안정성을 크게 높였습니다.

결론: 개발자의 행복을 위한 똑똑한 컨테이너화

Docker Compose를 활용한 컨테이너화는 단순히 '로컬에서 실행되던 것들을 컨테이너에 넣는' 작업이 아닙니다. 어떻게 분리하고, 어떻게 재사용하며, 어떻게 설정하고, 어떻게 안정적으로 실행할 것인가에 대한 깊은 고민이 담긴 '설계'의 과정입니다.

저희가 적용한 파일 분리, 공용 Dockerfile, .env를 통한 설정 중앙화, healthcheck를 통한 실행 순서 보장 전략 덕분에 저희 팀은 다음과 같은 이점을 얻을 수 있었습니다.

  • 일관된 개발 환경: 모든 팀원이 동일한 환경에서 개발하여 "제 컴퓨터에서는 됐는데..." 하는 문제를 원천 차단했습니다.
  • 신규 팀원 온보딩 시간 단축: Git clone 받고 docker-compose up 한 번이면 모든 환경 설정이 끝납니다.
  • 인프라 관리 부담 감소: 복잡한 인프라 설치 및 설정 과정이 모두 자동화되었습니다.
  • 개발 생산성 향상: 개발자는 인프라가 아닌, 비즈니스 로직 개발에만 집중할 수 있게 되었습니다.

이어서, 저희 프로젝트의 docker-compose 파일들을 직접 보여드리며 각 파일이 어떤 역할을 담당하고 어떻게 유기적으로 동작하는지 자세히 설명해 드리겠습니다.

아래는 저희 프로젝트의 핵심 구성 파일들입니다. 각 파일은 명확한 '관심사 분리' 원칙에 따라 작성되었습니다.


1. docker-compose.infra.yml - 모든 서비스의 기반, 인프라스트럭처

이 파일은 애플리케이션의 모든 서비스가 공유하는 핵심 인프라 컨테이너들을 정의합니다. 데이터베이스, 캐시 서버, 메시지 큐 등 애플리케이션의 뼈대를 이루는 구성 요소들이죠.

  • 주요 역할: 데이터 저장, 캐싱, 비동기 통신 등 시스템의 근간을 이루는 인프라를 한곳에서 관리합니다.
  • 핵심 포인트:
    • healthcheck: mysql, redis와 같은 서비스에 healthcheck를 정의하여, 해당 서비스가 완전히 실행되고 요청을 받을 준비가 되었을 때까지 의존하는 다른 서비스들이 대기하도록 만듭니다. 이를 통해 서비스 실행 순서로 인한 오류를 방지합니다.
    • networks: 모든 인프라 서비스는 app-network라는 공용 네트워크에 연결되어, 서비스 컨테이너들이 mysql, redis와 같은 컨테이너 이름으로 쉽게 통신할 수 있습니다.
    • volumes: mysql-data와 같은 볼륨을 사용하여 컨테이너가 삭제되더라도 데이터가 영구적으로 보존되도록 합니다.

services:

# 3\. Infrastructure Services

mysql:  
image: mysql:8  
container\_name: mysql  
environment:  
\- MYSQL\_DATABASE=${MYSQL\_DATABASE}  
\- MYSQL\_USER=${MYSQL\_USER}  
\- MYSQL\_PASSWORD=${MYSQL\_PASSWORD}  
\- MYSQL\_ROOT\_PASSWORD=${MYSQL\_ROOT\_PASSWORD}  
ports:  
\- "3306:3306"  
volumes:  
\- mysql-data:/var/lib/mysql  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용  
healthcheck:  
test: \["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "${MYSQL\_USER}", "-p${MYSQL\_PASSWORD}"\]  
interval: 10s  
timeout: 5s  
retries: 5  
start\_period: 30s

redis:  
image: redis:7  
container\_name: redis  
ports:  
\- "6380:6379"  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용  
healthcheck:  
test: \["CMD", "redis-cli", "ping"\]  
interval: 10s  
timeout: 5s  
retries: 5

rabbitmq:  
image: rabbitmq:3-management-alpine  
container\_name: rabbitmq  
environment:  
\- RABBITMQ\_DEFAULT\_USER=${RABBITMQ\_DEFAULT\_USER}  
\- RABBITMQ\_DEFAULT\_PASS=${RABBITMQ\_DEFAULT\_PASS}  
ports:  
\- "5672:5672"  
\- "15672:15672"  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용  
healthcheck:  
test: \["CMD", "rabbitmq-diagnostics", "ping", "-q"\]  
interval: 10s  
timeout: 5s  
retries: 5

zookeeper:  
image: confluentinc/cp-zookeeper:7.2.15  
container\_name: zookeeper  
environment:  
ZOOKEEPER\_CLIENT\_PORT: 2181  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용

kafka:  
image: confluentinc/cp-kafka:7.2.15  
container\_name: kafka  
depends\_on:  
\- zookeeper  
environment:  
KAFKA\_ZOOKEEPER\_CONNECT: zookeeper:2181  
\# 2. Kafka 리스너 설정 명확화  
KAFKA\_LISTENERS: INTERNAL://0.0.0.0:9092,EXTERNAL://0.0.0.0:9093  
KAFKA\_ADVERTISED\_LISTENERS: INTERNAL://kafka:9092,EXTERNAL://${DOCKER\_HOST\_IP:-localhost}:9093  
KAFKA\_LISTENER\_SECURITY\_PROTOCOL\_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT  
KAFKA\_INTER\_BROKER\_LISTENER\_NAME: INTERNAL  
KAFKA\_OFFSETS\_TOPIC\_REPLICATION\_FACTOR: 1  
ports:  
\- "9093:9093"  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용

mongo:  
image: mongo:6  
container\_name: mongo  
ports:  
\- "27017:27017"  
networks:  
\- app-network # 1. 외부에서 생성된 공통 네트워크 사용

# 1\. 외부 네트워크를 참조하도록 변경

networks:  
app-network:  
external: true

# 3\. volumes 설정은 올바릅니다.

volumes:  
mysql-data:

2. docker-compose.service.yml - 핵심 비즈니스 로직, 공통 서비스

이 파일은 도메인에 종속되지 않는 공통 핵심 서비스들을 정의합니다. 예를 들어 인증, 메일 발송, 이미지 처리, 사용자 프로필과 같은 기능은 여러 도메인에서 필요로 하는 공통 기능이죠.

  • 주요 역할: MSA의 핵심 비즈니스 로직을 담당하는 공통 서비스들을 그룹화합니다.
  • 핵심 포인트:
    • 공용 Dockerfile 활용: 모든 서비스는 service.Dockerfile이라는 공용 파일을 사용합니다. build.args.MODULE_PATH를 통해 빌드할 Gradle 모듈만 지정해주면 되므로, Dockerfile의 중복을 완벽하게 제거했습니다.
    • 환경 변수 주입: 각 서비스에 필요한 데이터베이스 정보, 포트, 외부 서비스 키 등을 .env 파일과 연동하여 환경 변수로 주입합니다. 이를 통해 설정의 유연성과 보안을 확보했습니다.
    • 볼륨 마운트: image-service의 경우, 호스트의 특정 경로 (./nginx/images/uploads)를 컨테이너 내부로 마운트합니다. 이는 사용자가 업로드한 이미지를 Nginx가 직접 정적 파일로 서빙할 수 있도록 하기 위한 중요한 설정입니다.
version: '3.7'

# 모든 서비스가 통신할 수 있도록 외부에서 생성된 공용 네트워크를 사용합니다.
networks:
  app-network:
    external: true

services:
  # ===================================================
  #              Authentication Service
  # ===================================================
  auth-service:
    build:
      context: . # 빌드 컨텍스트는 프로젝트 루트입니다.
      dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.
      args:
        MODULE_PATH: service/auth # 빌드할 모듈의 경로를 전달합니다.
    container_name: auth-service
    ports:
      # .env 파일에 정의된 포트 번호를 사용합니다.
      - "${AUTH_PORT}:${AUTH_PORT}"
    networks:
      - app-network
    restart: on-failure:10
    environment:
      # --- 서버 포트 ---
      - SERVER_PORT=${AUTH_PORT}

      # --- 데이터베이스 (MySQL) ---
      # Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_AUTHDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
      - SPRING_DATASOURCE_USERNAME=${AUTH_DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${AUTH_DB_PASSWORD}

      # --- 캐시 (Redis) ---
      - SPRING_DATA_REDIS_HOST=redis
      - SPRING_DATA_REDIS_PORT=6379

      # --- 메시지 큐 (Kafka) ---
      - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}

      # --- JWT 토큰 설정 ---
      - JWT_SECRET=${TOKEN_KEY}
      - JWT_ACCESS_EXPIRATION=${ACCESSTOKEN_EXPIRATION}
      - JWT_REFRESH_EXPIRATION=${REFRESHTOKEN_EXPIRATION}

      # --- 소셜 로그인 (Kakao) ---
      - KAKAO_CLIENT_ID=${KAKAO_REST_API_KEY}
      - KAKAO_REDIRECT_URI_PC=${REDIRECT_KAKAO}

  # ===================================================
  #                  Mail Service
  # ===================================================
  mail-service:
    build:
      context: .
      dockerfile: service.Dockerfile
      args:
        MODULE_PATH: service/mail
    container_name: mail-service
    ports:
      - "${MAIL_SERVER_PORT}:${MAIL_SERVER_PORT}"
    networks:
      - app-network
    restart: on-failure:10
    environment:
      # --- 서버 포트 ---
      - SERVER_PORT=${MAIL_SERVER_PORT}

      # --- 데이터베이스 (MySQL) ---
      # auth-service와 동일한 DB를 사용하므로 같은 변수를 참조합니다.
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_AUTHDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
      - SPRING_DATASOURCE_USERNAME=${AUTH_DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${AUTH_DB_PASSWORD}

      # --- 메시지 큐 (Kafka) ---
      - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}

      # --- 이메일 (Gmail SMTP) ---
      - SPRING_MAIL_HOST=smtp.gmail.com
      - SPRING_MAIL_PORT=587
      - SPRING_MAIL_USERNAME=${EMAIL}
      - SPRING_MAIL_PASSWORD=${EMAIL_PASSWORD}
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_AUTH=true
      - SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE=true

      # --- 애플리케이션 URL ---
      - BANDER_APP_URL=${DNS}:${BFF_PORT}



  # ===================================================
  #                User Profile Service
  # ===================================================
  user-profile-service:
    build:
      context: .
      dockerfile: service.Dockerfile
      args:
        MODULE_PATH: service/user-profile # 빌드할 모듈 경로 지정
    container_name: user-profile-service
    ports:
      - "${USER_PROFILE_PORT}:${USER_PROFILE_PORT}" # .env 파일 변수 사용
    networks:
      - app-network
    restart: on-failure:10
    environment:
      # --- 서버 포트 ---
      - SERVER_PORT=${USER_PROFILE_PORT}

      # --- 데이터베이스 (MySQL) ---
      # user-profile 전용 데이터베이스를 사용하도록 변수명을 지정합니다. (예: MYSQL_USERPROFILE_DATABASE)
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_USERPROFILE_DATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
      - SPRING_DATASOURCE_USERNAME=${USER_PROFILE_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${USER_PROFILE_PASSWORD}

      # --- 캐시 (Redis) ---
      - SPRING_DATA_REDIS_HOST=redis
      - SPRING_DATA_REDIS_PORT=6379

      # --- 메시지 큐 (Kafka) ---
      - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}



  # ===================================================
  #                  Image Service
  # ===================================================
  image-service:
    build:
      context: .
      dockerfile: service.Dockerfile
      args:
        MODULE_PATH: service/image
    container_name: image-service
    ports:
      - "${IMAGE_SERVER_PORT}:${IMAGE_SERVER_PORT}"
    networks:
      - app-network
    restart: on-failure:10
    volumes:
      # [핵심] 호스트의 이미지 저장 경로와 컨테이너 내부 경로를 연결합니다.
      # 호스트의 ./nginx/images/uploads/ 경로를 컨테이너의 /app/uploads 경로로 마운트합니다.
      - ./nginx/images/uploads:/app/uploads
    environment:
      # --- 서버 포트 ---
      - SERVER_PORT=${IMAGE_SERVER_PORT}

      # --- 애플리케이션 설정 ---
      # application.yaml의 하드코딩된 경로 대신, 컨테이너 내부 경로(/app/uploads)를 사용하도록 환경 변수를 주입합니다.
      - IMAGE_UPLOAD_DIR=/app/uploads
      - IMAGE_NGINX_URL=${NGINX_URL}
      - APP_SCHEDULER_IMAGE_CLEANUP_CRON=0 0 3 * * *

      # --- 데이터베이스 (MySQL) ---
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_IMAGE_DATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
      - SPRING_DATASOURCE_USERNAME=${IMAGE_DB_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${IMAGE_DB_PASSWORD}

      # --- 캐시 (Redis) ---
      - SPRING_DATA_REDIS_HOST=redis
      - SPRING_DATA_REDIS_PORT=6379

      # --- 메시지 큐 (Kafka) ---
      - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}

3. docker-compose.bandroom.yml - 도메인별 서비스 확장

이 파일은 '합주실'이라는 특정 도메인과 관련된 마이크로서비스들을 모아놓은 것입니다. 합주실 정보, 상품, 예약, 쿠폰 등 합주실과 관련된 기능들이 여기에 해당합니다.

  • 주요 역할: 특정 도메인(합주실)에 관련된 서비스들을 그룹화하여 관리의 편의성을 높입니다.
  • 핵심 포인트:
    • 도메인 기반 분리: 프로젝트가 확장되어 '공연'이나 '커뮤니티' 같은 새로운 도메인이 추가된다면, docker-compose.show.yml 이나 docker-compose.community.yml 과 같은 파일을 추가하는 것만으로 손쉽게 확장이 가능합니다.
    • 일관된 패턴 적용: service.yml과 마찬가지로 공용 Dockerfile, 환경 변수, 공용 네트워크 등 동일한 패턴을 적용하여 일관성을 유지하고 있습니다.

# 모든 서비스가 통신할 수 있도록 외부에서 생성된 공용 네트워크를 사용합니다.

networks:  
app-network:  
external: true

services:

# \===================================================

# BandRoomInfo Service

# \===================================================

bandroom-info-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/band-room/bandroom-info # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-info-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${BANDROOM\_INFO\_SERVER\_PORT}:${BANDROOM\_INFO\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${BANDROOM\_INFO\_SERVER\_PORT}


  # --- 데이터베이스 (MySQL) ---
  # Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.
  - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_BANDROOMINFODATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
  - SPRING_DATASOURCE_USERNAME=${BANDROOM_INFO_USERNAME}
  - SPRING_DATASOURCE_PASSWORD=${BANDROOM_INFO_USERNAME}

  # --- 캐시 (Redis) ---
  - SPRING_DATA_REDIS_HOST=redis
  - SPRING_DATA_REDIS_PORT=6379

  # --- 메시지 큐 (Kafka) ---
  - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}


# \===================================================

# BandRoomProductInfo Service

# \===================================================

bandroom-product-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/band-room/product-info # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-product-info-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${PRODUCT\_SERVER\_PORT}:${PRODUCT\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${PRODUCT\_SERVER\_PORT}


  # --- 데이터베이스 (MySQL) ---
  # Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.
  - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/${MYSQL_PRODUCTDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
  - SPRING_DATASOURCE_USERNAME=${PRODUCT_USERNAME}
  - SPRING_DATASOURCE_PASSWORD=${PRODUCT_PASSWORD}

  # --- 캐시 (Redis) ---
  - SPRING_DATA_REDIS_HOST=redis
  - SPRING_DATA_REDIS_PORT=6379

  # --- 메시지 큐 (Kafka) ---
  - SPRING_KAFKA_BOOTSTRAP_SERVERS=${KAFKA_URL_PROD}


# \===================================================

# BandRoomStudioInfo Service

# \===================================================

bandroom-studio-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/band-room/studio # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-studio-info-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${STUDIO\_SERVER\_PORT}:${STUDIO\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${STUDIO\_SERVER\_PORT}


# \--- 데이터베이스 (MySQL) ---

# Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.

-   SPRING\_DATASOURCE\_URL=jdbc:mysql://mysql:3306/${MYSQL\_STUDIODATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
-   SPRING\_DATASOURCE\_USERNAME=${STUDIO\_USERNAME}
-   SPRING\_DATASOURCE\_PASSWORD=${STUDIO\_PASSWORD}
-   \--- 캐시 (Redis) ---
-   SPRING\_DATA\_REDIS\_HOST=redis
-   SPRING\_DATA\_REDIS\_PORT=6379
-   \--- 메시지 큐 (Kafka) ---
-   SPRING\_KAFKA\_BOOTSTRAP\_SERVERS=${KAFKA\_URL\_PROD}

# \===================================================

# BandRoom Operation-hour Service

# \===================================================

bandroom-operation-hour-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/operation-hour # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-operation-hour-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${OPERATE\_HOURS\_SERVER\_PORT}:${OPERATE\_HOURS\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${OPERATE\_HOURS\_SERVER\_PORT}

# \--- 데이터베이스 (MySQL) ---

# Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.

-   SPRING\_DATASOURCE\_URL=jdbc:mysql://mysql:3306/${MYSQL\_OPERATIONDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
-   SPRING\_DATASOURCE\_USERNAME=${OPERATE\_HOURS\_USERNAME}
-   SPRING\_DATASOURCE\_PASSWORD=${OPERATE\_HOURS\_PASSWORD}
-   \--- 캐시 (Redis) ---
-   SPRING\_DATA\_REDIS\_HOST=redis
-   SPRING\_DATA\_REDIS\_PORT=6379
-   \--- 메시지 큐 (Kafka) ---
-   SPRING\_KAFKA\_BOOTSTRAP\_SERVERS=${KAFKA\_URL\_PROD}

# \===================================================

# BandRoom Reservation Booking Service

# \===================================================

bandroom-reservation-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/reservation/booking # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-reservation-booking-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${RESERVATION\_SERVER\_PORT}:${RESERVATION\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${RESERVATION\_SERVER\_PORT}

# \--- 데이터베이스 (MySQL) ---

# Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.

-   SPRING\_DATASOURCE\_URL=jdbc:mysql://mysql:3306/${MYSQL\_RESRVATIONDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
-   SPRING\_DATASOURCE\_USERNAME=${RESERVATION\_USERNAME}
-   SPRING\_DATASOURCE\_PASSWORD=${RESERVATION\_PASSWORD}
-   \--- 캐시 (Redis) ---
-   SPRING\_DATA\_REDIS\_HOST=redis
-   SPRING\_DATA\_REDIS\_PORT=6379
-   \--- 메시지 큐 (Kafka) ---
-   SPRING\_KAFKA\_BOOTSTRAP\_SERVERS=${KAFKA\_URL\_PROD}
-   #--- 메시지큐 (RabbitMQ)
-   SPRING\_RABBITMQ\_HOST=${SPRING\_RABBITMQ\_HOST\_PROD}
-   SPRING\_RABBITMQ\_PORT=${SPRING\_RABBITMQ\_PORT}
-   SPRING\_RABBITMQ\_USERNAME=${SPRING\_RABBITMQ\_USERNAME}
-   SPRING\_RABBITMQ\_PASSWORD=${SPRING\_RABBITMQ\_PASSWORD}

# \===================================================

# BandRoom Operation-hour Service

# \===================================================

bandroom-coupon-service:  
build:  
context: . # 빌드 컨텍스트는 프로젝트 루트입니다.  
dockerfile: service.Dockerfile # 공용 Dockerfile을 사용합니다.  
args:  
MODULE\_PATH: bandroom/reservation/coupon # 빌드할 모듈의 경로를 전달합니다.  
container\_name: bandroom-reservation-coupon-service  
ports:  
\# .env 파일에 정의된 포트 번호를 사용합니다.  
\- "${COUPON\_SERVER\_PORT}:${COUPON\_SERVER\_PORT}"  
networks:  
\- app-network  
restart: on-failure:10  
environment:  
\# --- 서버 포트 ---  
\- SERVER\_PORT=${COUPON\_SERVER\_PORT}

# \--- 데이터베이스 (MySQL) ---

# Docker 네트워크 내의 'mysql' 컨테이너에 접속합니다.

-   SPRING\_DATASOURCE\_URL=jdbc:mysql://mysql:3306/${MYSQL\_COUPONDATABASE}?useSSL=false&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true
-   SPRING\_DATASOURCE\_USERNAME=${COUPON\_DB\_USERNAME}
-   SPRING\_DATASOURCE\_PASSWORD=${COUPON\_DB\_PASSWORD}
-   \--- 캐시 (Redis) ---
-   SPRING\_DATA\_REDIS\_HOST=redis
-   SPRING\_DATA\_REDIS\_PORT=6379
-   \--- 메시지 큐 (Kafka) ---
-   SPRING\_KAFKA\_BOOTSTRAP\_SERVERS=${KAFKA\_URL\_PROD}  
728x90