Docker 빌드 컨텍스트가 1.06GB까지 커진 이유
Docker 빌드가 느리면 패키지 설치나 애플리케이션 컴파일부터 보게 됩니다. 저도 타입 검사 실패를 고치는 데 집중하다가 그보다 앞선 load build context 단계에서 40초가 넘게 쓰이고 있다는 사실을 뒤늦게 봤습니다. 실패 원인과는 별개였지만, 매 배포마다 반복되는 낭비였습니다.
실패 로그 옆에 있던 1.06GB
처음에는 타입 오류만 고치면 배포 문제도 끝난다고 생각했습니다. 컨텍스트 전송 로그는 빌드 앞부분에 늘 붙는 정보 정도로 넘길 뻔했습니다. 실제 기록은 이랬습니다.
transferring context: 1.06GB 41.5s done
load build context: DONE 42.6s애플리케이션 소스가 정말 큰지 로컬 디렉터리부터 측정했습니다.
2.2G .next
983M node_modules
19M .git
9.3M src
2.0M public실제 소스와 정적 파일은 합쳐도 12MB가 채 되지 않았습니다. 용량 대부분은 이미 만들어진 Next.js 빌드 산출물과 설치된 의존성이었습니다.
Docker는 Git의 추적 여부를 보지 않았습니다
저장소에는 .gitignore가 있었지만 .dockerignore는 없었습니다. Git이 .next와 node_modules를 무시하고 있어도 Docker 빌드 컨텍스트에는 영향을 주지 않습니다. Docker는 컨텍스트 디렉터리 아래 파일을 별도 규칙이 없으면 빌드 엔진으로 전송합니다.
멀티 스테이지 Dockerfile에서 나중에 필요한 파일만 COPY한다고 해도 컨텍스트 전송 자체가 먼저 일어납니다. 최종 이미지에 node_modules를 직접 복사하지 않는다는 사실도 이 1.06GB 전송을 막아주지 않았습니다.
빌드에 필요 없는 로컬 상태를 제외했습니다
저는 프로젝트 루트에 .dockerignore를 추가했습니다. 핵심은 재생성 가능한 디렉터리와 로컬 비밀 파일을 컨텍스트에 넣지 않는 것이었습니다.
.git
.github
.next
node_modules
build
coverage
out
*.tsbuildinfo
npm-debug.log*
.env
.env.*
**/.env
**/.env.*패치 디렉터리처럼 의존성 설치에 실제로 필요한 파일은 제외하지 않았습니다. .dockerignore를 넓게 잡아 **/*에서 허용 목록을 만드는 방식은 새 파일이 조용히 누락될 여지가 있어 사용하지 않았습니다.
수정 뒤 같은 단계의 로그는 다음과 같이 바뀌었습니다.
transferring context: 4.83MB 1.6s done
load build context: DONE 1.7s전송량은 1.06GB에서 4.83MB로, 컨텍스트 준비 시간은 42.6초에서 1.7초로 줄었습니다. 이 수치는 애플리케이션 컴파일 시간이 아니라 Docker가 빌드를 시작하기 위해 파일을 모으는 시간만 비교한 것입니다.
이번에는 타입 오류가 배포를 멈춰 세워서 로그를 자세히 보게 됐고, 그 옆의 별도 병목까지 찾았습니다. 이후에는 Docker 빌드가 느릴 때 설치 시간만 보지 않고 load build context의 전송량과 시간부터 확인합니다.
같은 작업에서 겪은 다른 문제:
함께 읽기
- 로컬에서는 통과한 Next.js 타입 검사가 Docker 배포에서만 실패하는 이유Next.js 앱에서 로컬 타입 검사는 통과하는데 Docker 배포에서만 같은 오류가 다시 나오면 코드보다 빌드 이미지에 무엇이 들어갔는지 봐야 합니다. 이번 작업에서는 린트, 타입 검사, 프로덕션 빌드를 모두 통과시킨 뒤 배포했는데 원격 빌드만 실패했습니다. 같은 커밋과 같은 잠금 파일을 썼으니 처음에는 환경 차이가 …
- 태그 485개를 전부 색인시키고 있었습니다: 블로그 SEO를 다시 손본 기록블로그에는 이미 canonical, sitemap, robots.txt, 글별 Open Graph 이미지, 구조화 데이터가 들어가 있었습니다. RSS와 Atom, JSON Feed도 있었고 관련 글 링크도 붙어 있었습니다. 그래서 처음에는 큰 구멍보다는 메타 설명을 조금 다듬는 정도를 예상했습니다.
- robots.txt는 무엇이고 왜 필요한가웹사이트를 운영하다 보면 루트 주소에서 robots.txt라는 작은 텍스트 파일을 만나게 됩니다. 내용은 몇 줄뿐인데 검색엔진 최적화 점검표에는 거의 빠지지 않고 등장합니다.
- 사이트맵이 6일째 멈춘 이유: revalidateTag 가 닿지 않는 자리글을 두 편 발행하고 사이트맵을 열어 봤습니다. 둘 다 없었습니다.
- docker builder prune 상한: 왜 남의 캐시까지 깎일까?한 서비스의 개발 배포를 다른 호스트로 옮기는 중이었습니다. 러너를 새로 붙이고, 환경변수 출처를 바꾸고, 이제 워크플로를 켜기만 하면 되는 참이었습니다. 그런데 배포 스크립트 마지막에 있는 한 줄에서 멈췄습니다.