Docker 실행 흐름 :

Dockerfile로 이미지를 만들고 → 이미지를 컨테이너로 실행하고 → compose로 여러 컨테이너를 한 번에 관리

1. Dockerfile 작성

spring boot 앱을 이미지로 만드는 작업

JDK로 bootJar 빌드 → JRE 런타임(비루트 유저)로 경량화

# syntax=docker/dockerfile:1

# multi stage :
    # 빌드 스테이지랑 런타임 스테이지를 분리. 만약 스테이지를 나누지 않고 JDK 이미지 하나로 빌드하게 되면
    # 최종 이미지는 다시 쓸일 없는 컴파일러와 빌드 도구, gradle 캐시 등도 전부 딸려 들어가 이미지가 훨씬 커짐.
    # 멀티 스테이지로 나눌시 빌드에만 필요한 무거운 것들은 build 스테이지에 버리고 실행에 필요한
    # jar만 runtime 스테이지에 골라 담기 때문에 최종 이미지가 가벼워짐.

# ============================================================
# 1) 빌드 스테이지 — Gradle Wrapper 로 실행 가능한 bootJar 생성
# ============================================================
FROM eclipse-temurin:21-jdk AS build                # jdk가 든 베이스 이미지를 가져오고 이 빌드 스테이지에 as로 build라는 이름을 붙임. --from=build로 빌드된 jar를 가져오기 위함.
WORKDIR /workspace

# 의존성 레이어 캐시: 빌드 스크립트/래퍼를 먼저 복사해 두면
# 소스만 바뀌고 build.gradle은 안바뀌었을 때 의존성 다운로드 레이어를 재사용한다.
COPY gradlew settings.gradle build.gradle ./
COPY gradle ./gradle
# --no-daemon : Gradle 데몬(백그라운드 상주 프로세스) 없이 실행. 컨테이너는 한 번 빌드하고 끝이라 데몬을 띄울 이유가 없음.
# || true : 이 줄이 혹시 실패해도 빌드를 멈추지 않음. 어차피 진짜 빌드는 아래에서 하기 때문.
RUN chmod +x gradlew && ./gradlew --no-daemon dependencies > /dev/null 2>&1 || true

# 소스 복사 후 실제 jar 파일 빌드
#  - 테스트는 Testcontainers(Docker 필요)라 이미지 빌드 중엔 제외(-x test)
COPY src ./src
RUN ./gradlew --no-daemon clean bootJar -x test

# ============================================================
# 2) 런타임 스테이지 — JRE 만 담아 경량화
# ============================================================
FROM eclipse-temurin:21-jre AS runtime # jre 이미지로 스테이지 시작
WORKDIR /app

# 루트로 실행하지 않도록 전용 사용자 생성
# 전용 사용자 미생성시 기본값 root(최고 권한 관리자)로 실행.
RUN useradd -r -u 1001 appuser

# bootJar 만 복사(같이 생기는 *-plain.jar 는 실행 불가라 glob 에서 제외됨)
# -- from=build로 build 스테이지에서 만든 jar만 골라서(jdk 빌드 도구 제외) runtime 스테이지로 가져와서 app.jar라는 이름을 붙임.
COPY --from=build /workspace/build/libs/*-SNAPSHOT.jar app.jar
USER appuser

EXPOSE 8080 # 이 컨테이너는 8080 포트를 쓴다는 문서화. 실제 포트 개방은 docker run -p나 compose ports가 담당.
ENTRYPOINT ["java", "-jar", "app.jar"] # 컨테이너가 시작될 때 실행할 명령. java -jar app.jar로 넘겨 받은 jar를 jre로 실행

경량화

** JDK

.java → .class 컴파일러인(javac), 디버깅 도구, 문서화 도구 등이 다 들어있는 자바 개발 키트

** JRE