이미지 빌드 · 빌드 컨텍스트와 재현성 · 이론
빌드가 시작되기 전에 이미 느려져 있다
한 줄 요약
docker build . 의 그 점 하나가 현재 디렉터리 전체를 빌더로 전송합니다.
캐시를 아무리 잘 짜도, 전송해야 할 게 800MB 면 빌드는 그 전에 이미 느립니다.
왜 이게 필요했나
Dockerfile 은 두 줄뿐인데 빌드가 40초 걸립니다. 로그 첫 줄을 보면 답이
있습니다.
Sending build context to Docker daemon 812.4MB빌드가 시작되기도 전에, 현재 디렉터리를 통째로 압축해 빌더에게 보내는
단계입니다. node_modules, .git, dist, 어제 받아 둔 덤프 파일까지
전부 갑니다. Dockerfile 에서 안 쓰더라도 전송은 됩니다.
여기서 두 가지가 동시에 망가집니다.
1. 속도 — 매 빌드마다 수백 MB 를 옮깁니다.
2. 캐시 — COPY . . 는 컨텍스트 안 파일이 하나라도 바뀌면 깨집니다..git/index 는 git status 만 쳐도 바뀝니다. 그래서 소스를 안 고쳤는데도
캐시가 깨지는 일이 생깁니다.
어떻게 동작하나
.dockerignore 는 .gitignore 와 문법이 비슷하지만 목적이 다릅니다..gitignore 는 "버전 관리하지 않을 것", .dockerignore 는 "빌더에게 보내지
않을 것"입니다. 겹치는 부분이 많지만 같지 않습니다 — 예를 들어 .git 은.gitignore 에 넣을 수 없지만 .dockerignore 에는 반드시 넣어야 합니다.
.gitnode_modules**/__pycache__*.logdist/.env마지막 줄이 중요합니다. .env 를 컨텍스트에 두면 COPY . . 로 **이미지에
그대로 박힙니다.** 나중에 지우는 레이어를 추가해도 앞 레이어에는 남습니다.
재현성 — 같은 Dockerfile, 다른 결과
.dockerignore 로 컨텍스트를 줄여도 빌드가 재현되지 않는 흔한 이유가 둘 더
있습니다.
떠다니는 태그. FROM python:3.12 는 오늘과 다음 달이 다른 이미지입니다.FROM python:3.12.7-slim 처럼 고정하거나, 더 엄격하게는 다이제스트로FROM python@sha256:... 를 씁니다.
패키지 인덱스. apt-get install curl 은 그날의 최신 버전을 가져옵니다.
어제 통과한 빌드가 오늘 깨지는 고전적인 원인이고, 정말 필요한 곳에서는
버전을 명시합니다.
| 문제 | 증상 | 대응 |
| --- | --- | --- |
| 큰 컨텍스트 | "Sending build context" 가 수백 MB | .dockerignore |
| .git 포함 | 소스 안 고쳤는데 캐시가 깨짐 | .dockerignore 에 .git |
| 떠다니는 태그 | 지난주 빌드와 결과가 다름 | 패치 버전·다이제스트 고정 |
| 시크릿 유입 | 이미지에 .env 가 들어감 | .dockerignore + 빌드 시크릿 |
ARG 는 이미지에 남는다
ARG API_TOKENRUN curl -H "Authorization: $API_TOKEN" ...이렇게 쓰면 docker history 에 그 값이 남습니다. 빌드 타임 비밀은 ARG 가
아니라 BuildKit 의 시크릿 마운트로 넘깁니다. ARG 는 "버전 번호" 같은
공개해도 되는 값에만 씁니다.
현장에서 만나는 모습
- 신규 입사자가
git clone후 첫 빌드에 5분 —.dockerignore가 없다. - CI 는 빠른데 로컬만 느리다 — 로컬에는
node_modules와 빌드 산출물이 있다. - 이미지에서 고객 덤프 CSV 가 발견됐다 — 컨텍스트에 있었고
COPY . .였다.
다음 확인에서 볼 것
이어지는 퀴즈에서는 빌드 컨텍스트의 경계, .dockerignore, 캐시 키와 비밀 전달
방식을 판단합니다. 앞 실습에서 측정한 전송 크기와 캐시 무효화 결과를 근거로
소스 변경과 무관한 파일이 빌드에 미치는 영향을 구분해 보세요.