v1.4.0
What's Changed
- Introduce multi-module Gradle
- Extract chat-common
- Add chat-history module for chat message persistence
- Unify CI/CD for chat-ws & chat-history
Full Changelog: v1.3.0...v1.4.0
Build: adopt prebuilt JAR images & split dev/prod compose for safer, faster deploys
왜 바꿨나 (배경)
- 멀티모듈에서 Dockerfile이 infra/ 아래로 이동하면서, 모듈 컨텍스트(
./chat-ws,./chat-history)로는 Dockerfile을 참조하기 어려움 → 루트 컨텍스트 필요. - 과거 멀티스테이지(컨테이너 내부 Gradle 빌드)는 컨텍스트가 크고, 모듈 간 교차 COPY/오염 위험이 있었음.
- 배포 시 WS/History 두 이미지를 일관되게 빌드·푸시·롤아웃하고 싶었음(이전엔 ws만 pull/up).
무엇이 바뀌었나 (요약)
-
CI에서 JAR 선빌드 → 얇은 런타임 이미지
- CI에서
./gradlew :chat-ws:bootJar :chat-history:bootJar --no-daemon -x test로 산출물 확정. infra/dockerfile/*.Dockerfile은 런타임 전용으로 단순화(컨테이너 내 Gradle 빌드 제거).- Docker 빌드 시 context는 루트(.),
file은infra/dockerfile/chat-ws.Dockerfile,.../chat-history.Dockerfile.
- CI에서
-
Compose 역할 분리
docker-compose.prod.yml은 이미지 참조만 하도록 정리(빌드 X).- 앱 이미지 변수를
WS_IMAGE/HIST_IMAGE로 명확히 분리해 주입. deploy스크립트에서 두 서비스 모두pull+up --no-deps수행.
-
GitHub Actions 정리
- matrix로 chat-ws / chat-history 두 이미지를 병렬 빌드·푸시.
장점 (이득)
- 안정성↑: CI에서 검증된 JAR를 기반으로 이미지 생성 → 모듈 교차 오염/경로 문제 제거.
- 속도·효율↑: 런타임 이미지 얇아져 푸시/풀 빠름, 배포 시간 단축.
- 일관성↑: 두 서비스(ws/history) 동일한 파이프라인·태그 전략 → 롤백/추적 용이.
- 보안/크기↓: 최종 이미지에 빌드 도구·소스 미포함 → 공격면 축소, 이미지 사이즈 감소.
단점/트레이드오프
- 컨테이너 내부 캐시 이점 감소: Gradle 의존성 캐시를 빌드 레이어에 못 싣기 때문에, “소스→JAR” 단계는 CI 캐시에 의존.
- CI 의존성: JAR 선빌드가 실패하면 이미지도 빌드 불가(의도된 보수성).
- 컨텍스트 규칙: Dockerfile이 infra/에 있으므로 dev에서 context는 루트(.) 여야 함(모듈 폴더 컨텍스트 불가).
이전과 이후 (Before → After)
- Before(멀티스테이지): 컨테이너 안에서 Gradle 빌드 → 컨텍스트 큼, COPY 경로 민감, ws/history 교차 이슈 가능, 배포는 ws 위주.
- After(선빌드): CI에서 JAR 확정 → 런타임 전용 Dockerfile, 두 서비스 모두 병렬 빌드·푸시, prod는 이미지 참조만으로 빠른 롤아웃.
왜 이 방식을 골랐는가
- 멀티모듈/멀티이미지 환경에서 교차 경로 이슈를 원천 차단하고, 배포 속도와 가시성(태그/롤백) 을 강화하기 위해.
- 운영(prod)은 가볍고 예측가능해야 하며, 개발(dev)은 compose로 자동 빌드 편의를 유지하도록 역할을 분리.
운영 팁 / 알아두면 좋은 특징
-
이미지 변수: prod에서
WS_IMAGE,HIST_IMAGE,IMAGE_TAG만 바꾸면 특정 릴리즈로 즉시 롤백/고정 가능. -
dev vs prod 분리:
- dev:
docker compose -f infra/docker-compose.base.yml -f infra/docker-compose.dev.yml up -d --build로 빌드+실행 한 번에. - prod: CI가 푸시한 태그를 pull하여 실행—서버에는 JDK/Gradle 불필요.
- dev:
-
.dockerignore 재검토: 루트 컨텍스트 사용 시, 불필요한 파일(예:
.git, 대용량 데이터)을 제외해 빌드 전송량 최소화. -
두 서비스 동시 배포: deploy 스크립트에서
pull app-chat-ws app-chat-history후up -d --no-deps로 동일 태그를 맞춰 주행.
후속 작업(TODO)
-
.dockerignore최적화(루트 컨텍스트 기준) - Slack/알림 연동(배포 성공/실패, 이미지 태그)
- 성능/용량 측정: 이미지 크기·배포 시간 전후 비교 기록
결론: 컨테이너 내부 빌드의 편의성 대신, 배포 안정성과 속도를 선택. 멀티모듈/멀티이미지 운영에 적합한 파이프라인으로 정리했다.