Docker build cache가 갱신되지 않는 것처럼 보일 때, 보통 문제는 Docker가 변경을 무시하는 게 아닙니다. 실제 원인은 Dockerfile 구조, build context, 복사되는 파일 범위가 기대한 layer invalidation을 만들지 못하는 데 있습니다.
짧게 말하면, 먼저 어떤 layer가 바뀌어야 하는지 정하고, 변경한 파일이 실제로 build context에 들어오는지 확인한 뒤, --no-cache보다 Dockerfile 순서를 먼저 고치는 편이 맞습니다.
먼저 어떤 layer가 다시 빌드되어야 하는지 이해하세요
Docker는 추측하지 않습니다. instruction과 그 입력이 같으면 layer를 재사용합니다.
그래서 먼저 아래를 알아야 합니다.
- 어떤 파일이 바뀌었는지
- 어떤
COPY나RUN단계가 그 파일에 의존하는지 - 그 파일이 build context 안에 있는지
- 더 앞선 instruction이 예상한 cache 동작을 가리고 있지는 않은지
이 구조를 모르면 cache 디버깅은 계속 시행착오가 됩니다.
cache가 이상해 보이는 흔한 이유
1. 바뀐 파일이 build context에 없음
.dockerignore가 파일을 제외했거나, 빌드 디렉터리가 잘못되면 Docker는 그 변화를 아예 볼 수 없습니다.
이건 가장 먼저 확인할 가치가 큰 항목입니다.
2. Dockerfile 순서가 실제 invalidation 지점을 가리고 있음
dependency install, source copy, build command 순서가 나쁘면 Docker는 정상 동작 중인데도 cache가 이상해 보일 수 있습니다.
3. COPY 경계가 너무 넓거나 너무 좁음
소스 전체를 너무 이른 단계에서 복사하면 cache가 시끄러워지고, 반대로 너무 적게 복사하면 팀은 source 변경이 반영돼야 한다고 생각하지만 실제로 그 instruction과 연결되지 않을 수 있습니다.
4. BuildKit에 대한 기대가 불분명함
요즘 Docker cache는 빠르지만, 결정적 cache reuse와 의도적 cache busting을 구분하지 않으면 체감이 혼란스러울 수 있습니다.
5. --no-cache를 너무 자주 써서 구조 문제가 숨겨짐
--no-cache는 검증에는 좋지만, 그게 기본 습관이 되면 Dockerfile 자체의 문제는 영영 고쳐지지 않습니다.
실전 점검 순서
1. 바뀐 파일이 정말 build context 안에 있는지 확인하세요
가장 빠른 첫 단계입니다. 파일이 build context에 없으면 그 뒤의 cache 논의는 의미가 없습니다.
2. .dockerignore와 COPY 범위를 점검하세요
기대한 rebuild를 일으켜야 하는 layer가 실제로 그 파일을 보고 있는지 확인해야 합니다.
많은 오해가 여기서 풀립니다.
3. Dockerfile 순서를 다시 보세요
dependency install layer와 application source 변경은 가능한 한 분리하는 편이 좋습니다. 그렇지 않으면 cache가 이해하기 어렵고 속도도 나빠집니다.
4. 실제 build 출력을 확인하세요
plain progress와 image history를 보면 어떤 layer가 재사용됐고, invalidation이 정확히 어디서 시작됐는지 보입니다.
docker build --progress=plain -t app .
docker history app
cat .dockerignore
5. 구조가 맞은 뒤에만 명시적 cache busting을 쓰세요
레이아웃이 잘못된 상태에서 cache-busting flag를 쓰면 설계 문제를 가릴 뿐입니다.
패턴을 찾은 뒤 어떻게 바꿀지
파일이 build context에서 제외된 경우
.dockerignore나 build directory를 고쳐서 Docker가 입력 변화를 실제로 보게 해야 합니다.
Dockerfile 순서가 문제인 경우
관련 입력이 바뀔 때만 무거운 단계가 invalidation 되도록 dependency install과 source copy를 재배치하세요.
너무 넓은 COPY가 cache를 시끄럽게 만드는 경우
dependency manifest와 application source를 분리해서 복사하세요.
cache는 정상인데 image가 여전히 큰 경우
그때는 invalidation 문제가 아니라 패키징 문제에 가깝기 때문에 Docker image가 너무 클 때로 넘어가는 편이 맞습니다.
빠른 체크리스트
build cache가 stale 해 보일 때는 아래 순서가 가장 좋습니다.
- 바뀐 파일이 build context 안에 있는지 확인한다
.dockerignore와COPY범위를 본다- Dockerfile 순서가 기대한 invalidation과 맞는지 본다
- plain build output과 image history를 확인한다
--no-cache는 검증용으로만 쓴다
FAQ
Q. 항상 --no-cache를 써야 하나요?
아닙니다. 검증에는 도움이 되지만 Dockerfile 구조 문제를 숨길 수 있습니다.
Q. 가장 빠른 첫 단계는 무엇인가요?
바뀐 파일이 실제로 build context 안에 있고, 기대한 layer와 연결돼 있는지 확인하는 것입니다.
Q. 코드를 바꿨는데 왜 Docker가 layer를 재사용하나요?
그 파일이 제외됐거나, 더 나중에 복사되거나, 생각한 instruction과 연결돼 있지 않기 때문인 경우가 많습니다.
Q. 언제 Dockerfile 설계 문제로 봐야 하나요?
기대한 동작을 얻기 위해 계속 cache-busting flag가 필요할 때입니다.
Read Next
- cache 구조 문제와 함께 image도 무겁다면 Docker image가 너무 클 때를 보세요.
- 반복 build가 host 디스크를 채운다면 Docker no space left on device를 비교해 보세요.
- rebuild는 되는데 container가 여전히 종료된다면 Docker container keeps restarting로 이어가세요.
- 더 넓은 인프라 글은 Infra 카테고리에서 볼 수 있습니다.
Related Posts
- Docker image가 너무 클 때
- Docker no space left on device
- Docker container keeps restarting
- Docker port가 이미 할당되었을 때
Sources:
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.
먼저 읽어볼 가이드
검색 유입이 많은 핵심 글부터 이어서 보세요.
- 미들웨어 트러블슈팅 가이드: Redis vs RabbitMQ vs Kafka 개발자를 위한 미들웨어 트러블슈팅 허브 글입니다. Redis, RabbitMQ, Kafka 중 어떤 증상부터 먼저 봐야 하는지와 어떤 문제 패턴이 각 시스템에 가까운지 정리합니다.
- Kubernetes CrashLoopBackOff: 먼저 볼 것들 startup failure, probe, config, resource limit 관점에서 CrashLoopBackOff를 어떻게 나눠서 봐야 하는지 정리한 가이드입니다.
- Kafka consumer lag가 계속 늘 때: 트러블슈팅 가이드 Kafka consumer lag가 계속 늘어날 때 무엇부터 봐야 하는지 정리합니다. poll 주기, 처리 속도, rebalance, consumer 설정까지 실전 기준으로 다룹니다.
- Kafka Rebalancing Too Often 가이드 Kafka consumer group에서 rebalance가 너무 자주 일어날 때 membership flapping, poll timing, protocol, assignment churn을 어떤 순서로 봐야 하는지 설명하는 실전 가이드입니다.
- Docker container가 계속 재시작될 때: 먼저 확인할 것들 exit code, command failure, environment mistake, health check 관점에서 Docker restart loop를 푸는 실전 가이드입니다.
심사 대기 중에는 광고 대신 관련 가이드를 먼저 보여줍니다.