아래는 나의 애플리케이션을 이미지화 하는 Dockerfile 이다.
# 멀티스테이지를 활용하였다. FROM 기준으로 다른 컨텍스트라고 생각하면됨 .
# 1) Gradle 빌드 스테이지
FROM gradle:8.5-jdk21 AS builder
WORKDIR /app
COPY . .
# 필요에 따라 --no-daemon, -x test 등 옵션을 조정
RUN gradle clean build -x test
# 2) 실제 실행 스테이지
FROM openjdk:21
WORKDIR /app
COPY --from=builder /app/build/libs/*.jar app.jar
# 환경 변수로 Spring Boot 프로파일 설정
ENV SPRING_PROFILES_ACTIVE=localcontainer
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
소스를 대강 보면 ,
1) 빌드 스테이지 단계
1-1) 빌드전용 컨테이너 생성 예약어 (FROM ) + 이미지명 ( gradle:8.5-jdk21 )
1-2) [1-1] 단계 에서 생성한 컨테이너에 /app 폴더 생성
1-3) 내프로젝트 통째로 복사
1-4) [1-1] 단계에서 정의하여 생긴 gradle 컨테이너이므로 , gradle 빌드를통해 원하는 산출물 생성
* 빌드 완료 후 , 이 컨테이너는 실행되지 않고 정지상태로 남아있고 , 파일시스템은 Docker 캐시에 보관됨 .
아래는 빌드스테이지 단계만 거친 이미지의 컨테이너이다 .

2) 실제 실행 스테이지 단계
2-1) 실제 실행용 컨테이너 생성 예약어 (FROM ) + 이미지명 ( openjdk:21 )
2-2) [2-1] 단계에서 생성한 컨테이너에 /app 폴더 생성
2-3) COPY --from=builder /app/build/lib/*.jar app.jar
( 해석 : 빌드 스테이지 단계의 컨테이너 /app/build/lib/*.jar 의 파일을 -> 실행 스테이지 의 WORKDIR(/app) 하위에 app.jar 라는 이름으로 복사한다. )
2-4) 이하 단계는 생략 ( spring profiles 설정 , 노출할 포트 (참고용) , 해당 파일 실행 명령어
아래는 실행스테이지까지 모두 처리한 컨테이너의 내부 구조이다.

빌드 및 배포를 어떻게할지는 각 팀 , 개인에 맞게 조절하면된다.