https://docs.docker.com/get-started/docker-concepts/building-images/multi-stage-builds/
오래된 빌드 방식의 경우엔, 모든 빌드 지침들(instructions)은 순차적이며 하나의 빌드 컨테이너 안에서 실행됨(의존성 설치, 코드 컴파일, 앱 패키징). 이러한 레이어들은 최종 이미지에서 끝남. 이러한 방식은 작동하긴 하지만 불필요한 무게와 보안 문제를 가지면서 사이즈를 불필요하게 키우게됨. 이때 Multi-stage 빌드 방식이 등장함.
Multi-stage 빌드는 Dockerfile 내에서 명확한 목적을 가진 각각의 다수의 스테이지를 도입함. 여러 개의 다른 환경들 내 빌드의 다른 부분들을 동시에 실행하는 능력을 생각하면 됨. 최종 런타임 환경으로부터 빌드 환경을 분리함으로써, 우리는 상당한 양의 이미지 사이즈와 공격 표면을 줄일 수 있게 됨. 이는 거대한 빌드 의존성을 가진 앱에게 특히나 유용함.
Multi-stage 빌드는 모든 타입의 앱들에게 유용함
여기 pseudo-code를 이용해 multi-stage 빌드 구조의 간단한 예시가 있음. **FROM
지시문과 새로운 AS <stage-name>
**을 주의깊게 볼 것. 추가적으로, COPY
지시문이 이전 스테이지( —from
)을 복사한다는 것을 확인할 것
# Stage 1: Build Environment
FROM builder-image AS build-stage
# Install build tools (e.g., Maven, Gradle)
# Copy source code
# Build commands (e.g., compile, package)
# Stage 2: Runtime environment
FROM runtime-image AS final-stage
# Copy application artifacts from the build stage (e.g., JAR file)
COPY --from=build-stage /path/in/build/stage /path/to/place/in/final/stage
# Define runtime configuration (e.g., CMD, ENTRYPOINT)
이 Dockerfile은 두 단계를 사용함 :
CMD
, ENTRYPOINT
를 사용해서)이번에는 샘플 자바 애플리케이션을 위한 간소하고 효율적인 도커 이미지들을 생성하기 위한 multi-stage 빌드의 강력함을 알아볼 것임. 예시로 Maven으로 빌드된 “Hello World” 스프링부트 기반 애플리케이션을 사용할 예정
Docker Desktop을 설치
pre-initialized project를 열어 ZIP file을 생성함 :
다음과 같은 화면이 보일 것
Generate를 선택하고 zip file을 다운받음.
프로젝트 디렉토리로 이동. zip file을 풀고 나면, 다음과 같은 폴더 구조를 확인 가능 :
/src/main/java
: 소스코드를 포함/src/test/java
: 테스트 코드를 포함pom.xml
: Project Object Model
“Hello World!”를 디스플레이하는 RESTful 웹 서비스를 생성
src/main/java/com/example/spring_boot_docker/
폴더 아래, SpringBootDockerApplication.java
파일을 다음 내용으로 수정 :
package com.example.spring_boot_docker;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class SpringBootDockerApplication {
@RequestMapping("/")
public String home() {
return "Hello World";
}
public static void main(String[] args) {
SpringApplication.run(SpringBootDockerApplication.class, args);
}
}
SpringbootDockerApplication.java
파일은 com.example.spring_boot_docker
패키지를 선언하고 필요한 스프링 프레임워크들을 import해옴으로써 시작함. 이 자바 파일은 유저가 홈페이지를 방문하면 “Hello World!”를 응답하는 간단한 스프링 부트 웹앱을 생성함