개요

GitHub Actions + Docker Hub + 멀티스테이지 Dockerfile을 활용한 빌드 및 배포 파이프라인입니다. 빌드는 GitHub Actions 서버에서 처리하고, Lightsail 서버는 Docker Hub에서 이미지를 pull해서 실행만 해요.

전체 흐름

개발자 (develop 브랜치 push)
  ↓
GitHub Actions 서버 (ubuntu-latest)
  ├── 코드 clone
  ├── Docker 이미지 빌드 (멀티스테이지 Dockerfile)
  │     ├── 1단계: JDK + gradlew bootJar → JAR 생성
  │     └── 2단계: JAR만 복사 → 경량 실행 이미지
  └── Docker Hub push
        ↓
  sm010422/sofly-core:{github.sha}
        ↓
Lightsail 서버 (SSH)
  ├── docker pull
  ├── 새 컨테이너 실행 (Blue/Green)
  ├── 헬스체크
  ├── Nginx 트래픽 전환
  └── 이전 컨테이너 종료

왜 멀티스테이지 Dockerfile을 쓰냐

기존 방식 (비효율적)

GitHub Actions
  ├── JDK 설치
  ├── gradlew bootJar    ← 1번째 빌드
  └── docker build       ← Dockerfile 안에서 또 gradlew 실행 (2번째 빌드)
        └── docker push

JAR 빌드가 두 번 일어나서 시간 낭비예요.

현재 방식 (멀티스테이지)

GitHub Actions
  └── docker build       ← Dockerfile 안에서 빌드 한 번만
        └── docker push

GitHub Actions에서 JDK 설치, gradlew 빌드 step이 전부 필요 없어요.

Dockerfile 설명

# ── 1단계: 빌드 ────────────────────────
FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /app

COPY gradlew .
COPY gradle gradle
COPY build.gradle .
COPY settings.gradle .
RUN chmod +x ./gradlew && \
    ./gradlew dependencies --no-daemon

COPY src src
RUN ./gradlew clean bootJar -x test --no-daemon

# ── 2단계: 실행 ────────────────────────
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
ENTRYPOINT ["java", "-Dspring.config.name=application-core", "-jar", "app.jar"]

캐시 레이어 동작 방식

첫 번째 빌드
  → 의존성 다운로드 (시간 걸림)
  → JAR 빌드

두 번째 빌드 (src만 변경)
  → 의존성 캐시 재사용 ✅
  → JAR 빌드만 재실행 (빠름)

두 번째 빌드 (build.gradle 변경)
  → 의존성부터 다시 다운로드
  → JAR 빌드

build.gradle이나 gradle 폴더가 바뀌지 않으면 의존성 레이어는 캐시를 쓰안 빌드 시간이 크게 단축돼요.

GitHub Actions 워크플로우 설명

트리거 조건

on:
  push:
    branches: [ "develop" ]
    paths:
      - 'services/travel-core-service/**'
      - '.github/workflows/deploy-core.yml'
      - 'docker-compose.yml'

세 경로 중 하나라도 변경되면 실행돼요.