🎯 학습 목표
- Spring Boot 앱을 컨테이너화하는 흐름을 이해한다.
- 멀티스테이지 빌드로 이미지 용량을 줄인다.
- 빌드한 이미지를 실행하고 동작을 확인한다.
📖 개념 설명
Spring Boot 앱은 보통 jar 하나로 패키징되어 java -jar app.jar로 실행됩니다. 컨테이너화한다는 것은 이 실행에 필요한 JRE와 jar를 이미지에 담아, 어느 PC·서버에서도 동일하게 돌게 만드는 것입니다.
멀티스테이지 빌드가 핵심입니다. 1단계(빌드 스테이지)에서는 JDK + 빌드 도구로 소스를 컴파일해 jar를 만들고, 2단계(런타임 스테이지)에서는 가벼운 JRE 이미지에 jar만 복사합니다. 그러면 무거운 빌드 도구가 최종 이미지에 포함되지 않아 용량이 크게 줄고 보안 표면도 작아집니다.
💻 실습 — 예제 앱 (간단한 REST 컨트롤러)
// src/main/java/com/example/demo/HelloController.java
package com.example.demo;
import org.springframework.web.bind.annotation.*;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello from Spring Boot in Docker!";
}
}
💻 Dockerfile (멀티스테이지)
# ---- 1단계: 빌드 ----
FROM eclipse-temurin:21-jdk AS build
WORKDIR /app
COPY . .
# Gradle 사용 시 (Maven이면 ./mvnw clean package -DskipTests)
RUN chmod +x gradlew && ./gradlew clean bootJar -x test
# ---- 2단계: 런타임 ----
FROM eclipse-temurin:21-jre
WORKDIR /app
# 빌드 스테이지에서 만든 jar만 복사
COPY --from=build /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
💻 이미지 빌드 & 실행
# 프로젝트 루트(Dockerfile 위치)에서 빌드
docker build -t demo-app:1.0 .
# 실행 (8080 → 8080)
docker run -d --name demo -p 8080:8080 demo-app:1.0
# 동작 확인
curl http://localhost:8080/hello
# → Hello from Spring Boot in Docker!
⚠️ 주의사항
.dockerignore에build/,.git/,*.iml등을 넣어 빌드 컨텍스트를 줄이세요(빌드 속도↑).- WSL에서 빌드하면 윈도우보다 빠릅니다. 프로젝트를 리눅스 홈에 두고 빌드하세요.
- JDK 버전 태그(예:
21)를 프로젝트 자바 버전과 맞추세요.
💡 팁
- 의존성 캐시를 활용하려면 빌드 파일(
build.gradle)을 먼저 COPY 후 의존성만 받고, 그 다음 소스를 COPY하는 레이어 순서를 쓰면 재빌드가 빨라집니다. - 빌드 없이 이미 만든 jar만 담고 싶다면 1단계를 생략하고
COPY build/libs/*.jar app.jar만 써도 됩니다.