← 아티클 목록

도커 레이어 캐시 — 빌드 순서로 속도 10배 올리기

2027-01-11#docker#캐시#빌드

코드 한 줄만 고쳤는데 docker build가 매번 의존성 설치부터 다시 한다면, 레이어 캐시가 깨지고 있다는 뜻입니다. 도커는 Dockerfile의 각 명령을 레이어로 쌓고, 바뀐 게 없으면 이전 빌드 결과를 그대로 재사용합니다. 문제는 한 레이어가 무효화되면 그 아래 모든 레이어도 함께 무효화된다는 점입니다. 그래서 "무엇을 먼저 쓰느냐"가 빌드 속도를 좌우합니다.

캐시가 깨지는 규칙

각 명령마다 도커는 캐시 키를 계산합니다. RUN은 명령 문자열로, COPY/ADD는 복사 대상 파일의 내용 해시로 키를 만듭니다. 즉 COPY . .을 위쪽에 두면 소스 파일 하나만 바뀌어도 그 아래 RUN npm ci까지 전부 다시 실행됩니다.

핵심 — 안 바뀌는 것을 위로

자주 안 바뀌는 의존성 정의를 먼저 복사·설치하고, 자주 바뀌는 소스는 맨 나중에 복사합니다.

Dockerfile
FROM node:20-slim
WORKDIR /app

# 1) 거의 안 바뀌는 의존성 정의만 먼저
COPY package.json package-lock.json ./
RUN npm ci

# 2) 자주 바뀌는 소스는 맨 마지막
COPY . .
RUN npm run build
CMD ["node", "dist/main.js"]

이렇게 하면 소스만 고쳤을 때 npm ci 레이어가 캐시에서 그대로 재사용돼 빌드가 수십 초에서 수 초로 줄어듭니다.

순서 비교

순서소스 1줄 변경 시결과
COPY . . 먼저 → RUN npm ci의존성 재설치 매번느림
COPY package*.jsonRUN npm ciCOPY . .의존성 캐시 재사용빠름

캐시 마운트로 한 번 더

BuildKit의 --mount=type=cache를 쓰면 레이어 캐시가 깨져도 패키지 매니저 캐시 디렉터리는 빌드 간에 유지됩니다.

Dockerfile
# syntax=docker/dockerfile:1
RUN --mount=type=cache,target=/root/.npm \
    npm ci

lock 파일이 바뀌어 RUN이 다시 돌더라도 이미 받아둔 패키지는 캐시 디렉터리에서 재사용해 네트워크 다운로드를 건너뜁니다.

점검 체크리스트

로컬 터미널
DOCKER_BUILDKIT=1 docker build -t myapp .   # 빌드 1회
docker build -t myapp .                     # 다시 빌드 → CACHED 표시 확인
docker history myapp                        # 레이어별 크기·생성 명령

두 번째 빌드 로그에서 CACHED가 의존성 단계까지 떠야 순서가 제대로 잡힌 것입니다. CACHED가 안 보이면 그 위 어떤 COPY가 캐시를 깨고 있는지 거슬러 올라가 봅니다.


Dockerfile 순서를 바꿔가며 CACHED 표시와 빌드 시간 변화를 직접 확인하는 실습은 도커 트랙에서 회원가입 없이 무료로 해볼 수 있습니다.