LabHub
배우기 러닝패스 코스

イメージのビルド

ビルドが始まる前にもう遅くなっている

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

docker build . 의 그 점 하나가 현재 디렉터리 전체를 빌더로 전송합니다. 캐시를 아무리 잘 짜도, 전송해야 할 게 800MB 면 빌드는 그 전에 이미 느립니다.

概念マップ: 점 하나・전송은 됩니다.・속도・캐시

왜 이게 필요했나

Dockerfile 은 두 줄뿐인데 빌드가 40초 걸립니다. 로그 첫 줄을 보면 답이 있습니다.

Sending build context to Docker daemon  812.4MB

빌드가 시작되기도 전에, 현재 디렉터리를 통째로 압축해 빌더에게 보내는 단계입니다. node_modules, .git, dist, 어제 받아 둔 덤프 파일까지 전부 갑니다. Dockerfile 에서 안 쓰더라도 전송은 됩니다.

여기서 두 가지가 동시에 망가집니다.

  1. 속도 — 매 빌드마다 수백 MB 를 옮깁니다.
  2. 캐시COPY . . 는 컨텍스트 안 파일이 하나라도 바뀌면 깨집니다. .git/indexgit status 만 쳐도 바뀝니다. 그래서 소스를 안 고쳤는데도 캐시가 깨지는 일이 생깁니다.

어떻게 동작하나

.dockerignore.gitignore 와 문법이 비슷하지만 목적이 다릅니다. .gitignore 는 "버전 관리하지 않을 것", .dockerignore 는 "빌더에게 보내지 않을 것"입니다. 겹치는 부분이 많지만 같지 않습니다 — 예를 들어 .git.gitignore 에 넣을 수 없지만 .dockerignore 에는 반드시 넣어야 합니다.

.git
node_modules
**/__pycache__
*.log
dist/
.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_TOKEN
RUN curl -H "Authorization: $API_TOKEN" ...

이렇게 쓰면 docker history 에 그 값이 남습니다. 빌드 타임 비밀은 ARG 가 아니라 BuildKit 의 시크릿 마운트로 넘깁니다. ARG 는 "버전 번호" 같은 공개해도 되는 값에만 씁니다.

현장에서 만나는 모습

컨텍스트를 줄이는 것 말고 안 보내는 방법

.dockerignore 는 보낼 것을 줄이지만, 아예 다른 길로 가져오는 방법도 있다. 어느 쪽이 맞는지는 그 파일이 빌드에 필요한 이유로 갈린다.

빌드에만 필요하고 최종 이미지에는 없어야 하는 것 — 앞 코스에서 본 다단계 빌드와 비밀 마운트가 이 자리다. 자격 증명은 컨텍스트에 아예 넣지 않고 마운트로 건네고, 컴파일 도구와 중간 산출물은 앞 단계에 두고 결과만 옮긴다.

빌드 중에 받아 오는 것 — 캐시 마운트를 쓰면 의존성 디렉터리를 컨텍스트에 넣지 않고도 빌드 사이에 재사용할 수 있다. node_modules 를 통째로 보내지 않아도 되는 이유가 이것이고, 컨텍스트가 작아지는 동시에 캐시도 좋아진다.

원격에서 가져오는 것 — 빌더는 컨텍스트 대신 git 저장소 주소나 tarball 주소를 받을 수도 있다. CI 처럼 이미 그 자리에 소스가 있는 환경에서는 큰 차이가 없지만, 컨텍스트를 만들 수 없는 자리에서는 이 길이 유일하다.

그리고 무엇이 실제로 갔는지 확인하는 방법을 알아 두면 좋다. 컨텍스트에 무엇이 담기는지는 .dockerignore 규칙의 순서와 부정 패턴에 따라 헷갈리기 쉬운데, 이미지를 만든 뒤 그 안의 파일 목록을 훑어 보면 의도하지 않은 것이 들어갔는지 바로 드러난다. 비밀이 들어갔는지 확인하는 가장 확실한 방법도 이것이고, 앞 코스에서 본 대로 레지스트리에 올라간 뒤에는 되돌릴 수 없으므로 올리기 전에 한 번 보는 값이 크다.

다음 확인에서 볼 것

이어지는 퀴즈에서는 빌드 컨텍스트의 경계, .dockerignore, 캐시 키와 비밀 전달 방식을 판단합니다. 앞 실습에서 측정한 전송 크기와 캐시 무효화 결과를 근거로 소스 변경과 무관한 파일이 빌드에 미치는 영향을 구분해 보세요.