docker build를 쓰다 보면 똑같은 Dockerfile인데 어떤 환경에선 빌드가 빠르고, 어떤 환경에선 느린 경험을 합니다. 차이의 상당 부분은 어떤 빌더 엔진을 쓰느냐에서 옵니다. 도커에는 오래된 레거시 빌더와 그 후속인 BuildKit이 있고, 둘은 빌드 방식부터 기능까지 꽤 다릅니다. 최신 도커는 BuildKit이 기본이지만, 무엇이 왜 좋은지 알아야 제대로 활용할 수 있습니다.
두 빌더의 근본 차이
레거시 빌더는 Dockerfile을 위에서 아래로 한 줄씩 순서대로 처리합니다. BuildKit은 Dockerfile을 의존성 그래프로 분석해, 서로 무관한 단계는 동시에 빌드합니다. 멀티 스테이지 빌드에서 이 차이가 특히 큽니다.
| 항목 | 레거시 빌더 | BuildKit |
|---|---|---|
| 실행 방식 | 단계별 순차 | 의존성 그래프 기반 병렬 |
| 불필요한 단계 | 항상 실행 | 결과에 안 쓰이면 건너뜀 |
| 캐시 마운트 | 없음 | --mount=type=cache 지원 |
| 빌드 시크릿 | 이미지에 남을 위험 | --mount=type=secret로 안전 |
| 빌드 출력 | 장황한 로그 | 단계별 진행 표시 |
캐시 마운트와 빌드 시크릿
BuildKit의 대표 기능 두 가지입니다. 캐시 마운트는 패키지 매니저 캐시(npm, pip, apt 등)를 빌드 간에 유지해, 의존성을 매번 새로 받지 않게 합니다. 빌드 시크릿은 토큰 같은 민감 정보를 이미지 레이어에 남기지 않고 빌드 중에만 쓰게 합니다.
# syntax=docker/dockerfile:1
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
# 캐시 마운트: npm 캐시를 빌드 간 재사용
RUN --mount=type=cache,target=/root/.npm npm ci
COPY . .
# syntax=docker/dockerfile:1 첫 줄과 --mount 문법은 BuildKit에서만 동작합니다. 레거시 빌더는 이 줄을 이해하지 못합니다.
어떤 빌더를 쓰는지 확인·전환
최신 도커는 BuildKit이 기본이지만, 환경에 따라 명시적으로 켜야 할 때가 있습니다.
docker version # Buildx/BuildKit 버전 확인
DOCKER_BUILDKIT=1 docker build -t app . # 레거시 환경에서 강제 활성화
docker buildx build -t app . # buildx로 빌드(BuildKit)
DOCKER_BUILDKIT=0으로 두면 레거시 빌더로 돌아갑니다. 빌드 시크릿이나 캐시 마운트를 쓰는 Dockerfile이 이 환경에서 실패한다면 빌더가 레거시인지 먼저 의심해야 합니다.
요점 정리
- 레거시 빌더는 순차 실행, BuildKit은 의존성 그래프 기반 병렬 실행이다.
- BuildKit은 결과에 안 쓰이는 단계를 건너뛰어 불필요한 빌드를 줄인다.
- 캐시 마운트(
--mount=type=cache)로 의존성 캐시를 빌드 간 재사용한다. - 빌드 시크릿(
--mount=type=secret)으로 민감 정보를 이미지에 남기지 않는다.
캐시 마운트와 멀티 스테이지 빌드로 빌드 속도가 실제로 어떻게 달라지는지 직접 측정하는 실습은 도커 트랙에서 할 수 있습니다 — 회원가입 없이 무료로.