컨테이너 용어 사전
빌드multi-stage · COPY --from · 빌드 스테이지

멀티스테이지

빌드 도구를 최종 이미지에서 뺀다. 크기와 공격 표면이 함께 줄어든다.

빌드용 스테이지와 실행용 스테이지를 나눠, 산출물만 복사해 오는 방식.

# syntax=docker/dockerfile:1

FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /src
COPY pom.xml .
RUN --mount=type=cache,target=/root/.m2 mvn -B dependency:go-offline
COPY src ./src
RUN --mount=type=cache,target=/root/.m2 mvn -B package -DskipTests

FROM eclipse-temurin:21-jre-alpine AS runtime
WORKDIR /app
COPY --from=build /src/target/app.jar ./app.jar
USER 10001:10001
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

무엇을 얻나

  • 이미지 크기가 수백 MB → 수십 MB

    • JDK · maven · 소스 · 중간 산출물이 최종 이미지에 없다
  • 공격 표면이 줄어든다

    • 컴파일러 · 패키지 매니저 · 셸이 없으면 침투 후 할 수 있는 일이 적다
  • 빌드 도구의 취약점이 운영 이미지에 안 딸려 온다

    • 스캔 결과가 극적으로 깨끗해진다

스테이지를 골라 쓸 수 있다

docker build --target build .        # 빌드 스테이지까지만

활용

  • 테스트 전용 스테이지를 만들어 CI 에서 그것만 실행
  • 개발용/운영용 최종 스테이지를 나눠 둔다
  • 공통 베이스 스테이지를 만들어 중복을 줄인다

FROM base AS test RUN mvn test

외부 이미지에서도 복사할 수 있다

COPY --from=curlimages/curl /usr/bin/curl /usr/bin/curl

스테이지가 아니라 이미지 이름을 줘도 된다 도구 하나만 필요할 때 패키지 매니저 없이 가져온다

  • 다만 의존 라이브러리까지 함께 와야 동작한다
  • 정적 바이너리일 때 안전하다

캐시와 함께 설계한다

의존성 해석과 소스 컴파일을 다른 레이어로 나눈다

  • COPY pom.xml → 의존성 받기 → COPY src → 빌드

캐시 마운트를 쓰면 레이어에 굽지 않고도 재사용된다

  • --mount=type=cache,target=/root/.m2

두 기법을 함께 쓰면 소스만 바뀐 빌드가 수십 초 → 수 초가 된다

언어별 형태

# Go — 정적 바이너리라 scratch 까지 갈 수 있다
FROM golang:1.23 AS build
WORKDIR /src
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /app ./cmd/server

FROM gcr.io/distroless/static-debian12
COPY --from=build /app /app
USER 65532:65532
ENTRYPOINT ["/app"]

CGO_ENABLED=0 이 핵심이다 — 켜져 있으면 glibc 에 동적 링크된다 그 상태로 scratch·distroless/static 에 올리면 종료 코드 127

최종 이미지에 무엇이 남았는지 확인한다

docker run --rm myapp:1.0 sh -c 'which sh curl wget apt npm 2>/dev/null'
docker history myapp:1.0

멀티스테이지를 썼는데도 빌드 도구가 남아 있는 경우가 있다

  • 최종 스테이지의 베이스가 여전히 SDK 이미지다
  • COPY --from 을 빠뜨리고 그냥 COPY 했다

크기가 기대만큼 안 줄었으면 이 둘을 먼저 본다

면접 함정

  • "멀티스테이지는 이미지를 여러 개 만든다" → 최종 스테이지 하나만 이미지가 된다.
  • "크기만 줄이는 기법" → 공격 표면 감소가 그만큼 중요하다.

함께 보면 좋은 용어

노트에서 맥락과 함께 보기 — Dockerfile — 명령어와 그 함정