Quick Reference
FROM node:22-alpine
WORKDIR /app
# 의존성 파일만 먼저 복사 — 소스 변경이 캐시에 영향 없음
COPY package.json package-lock.json ./
RUN npm ci
# 소스 코드는 나중에 — 자주 바뀌는 파일을 뒤에 둔다
COPY . .
RUN npm run buildcontext는 COPY·ADD가 읽는 입력이고, cache는 Dockerfile 지시어와 그 지시어가 읽은 파일 metadata가 같을 때 재사용됩니다. 의존성 manifest를 먼저 복사하고 source를 나중에 복사하면 source 변경이 의존성 설치 cache까지 무효화하지 않습니다.
context와 cache 무효화
build context는 Dockerfile의 파일 입력 범위를 정한다
docker build .의 마지막 .은 현재 디렉터리를 build context로 지정한다는 뜻입니다. COPY와 ADD는 context 안의 파일만 읽을 수 있고, 원격 builder에서는 context 크기가 전송 비용과 빌드 시작 시간에 직접 영향을 줍니다. .dockerignore로 입력을 좁힌 뒤, 필요한 파일만 COPY합니다.
# context 크기 확인 전략 — 빌드 전 어떤 파일이 포함되는지 확인
docker build --no-cache --progress=plain . 2>&1 | grep "transferring context"cache는 지시어와 실제 파일 입력을 함께 비교한다
Docker는 각 Dockerfile 지시어에 대해 이전 결과를 재사용할 수 있는지 확인합니다. COPY와 ADD, bind mount를 쓴 RUN은 읽은 파일 metadata의 checksum도 비교합니다. 일치하지 않는 단계부터 뒤 단계는 다시 실행되므로, dependency manifest와 source를 한 COPY . .에 섞지 않습니다.
# 나쁜 예 — 소스 코드 한 줄만 바꿔도 npm ci가 다시 실행됨
COPY . .
RUN npm ci
# 좋은 예 — 소스 변경은 npm ci 캐시에 영향 없음
COPY package.json package-lock.json ./
RUN npm ci
COPY . .COPY 순서로 캐시를 최대화 — 자주 바뀌는 파일을 나중에 복사한다
캐시 전략의 핵심은 변경 빈도가 낮은 파일을 앞에, 자주 바뀌는 파일을 뒤에 배치하는 것입니다. 의존성 파일(package.json, requirements.txt, go.mod)은 소스 코드보다 훨씬 덜 바뀌므로 먼저 복사해 npm ci나 pip install 레이어를 캐시합니다.
# Python 예시
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY src/ ./src/
# requirements.txt가 안 바뀌면 pip install은 캐시 재사용build context와 레이어 캐시는 서로 연결돼 있다
context에 들어간 파일이 바뀌면 관련 COPY 레이어부터 캐시가 깨집니다. 그래서 .dockerignore로 불필요한 파일을 빼는 것과 COPY 순서를 조정하는 작업은 사실 같은 문제의 두 면입니다. context가 더럽고 넓으면 캐시 전략도 같이 무너집니다.
context 최소화
.git, node_modules, 빌드 산출물을 context에 그대로 보내면 빌드가 느리고 캐시가 자주 깨진다. Dockerfile과 .dockerignore는 항상 함께 설계해야 하며, context 파일 변경이 캐시 무효화로 이어지는 범위를 의식하며 COPY 순서를 잡아야 한다.
참고 링크
2 sources