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 배포에서만 같은 오류가 다시 나오면 코드보다 빌드 이미지에 무엇이 들어갔는지 봐야 합니다. 이번 작업에서는 린트, 타입 검사, 프로덕션 빌드를 모두 통과시킨 뒤 배포했는데 원격 빌드만 실패했습니다. 같은 커밋과 같은 잠금 파일을 썼으니 처음에는 환경 차이가 …
- Next.js Docker 빌드 캐시: 배포 CSS에서 패키지 스타일이 빠진 문제테마 메뉴에서 디자인 시스템을 바꾸는 기능을 배포했습니다. 메뉴에는 「Betelgeuse 라임 다크」라고 정확히 찍히는데, 화면은 기본 시스템 그대로였습니다. 바로 전 배포에서는 같은 기능이 잘 동작했습니다. 그 사이에 바뀐 것은 디자인 시스템 패키지의 버전 하나였습니다.
- Google 번역을 켰더니 React 앱이 오류 화면으로 바뀐 이유한국어, 영어, 일본어, 중국어를 직접 제공하는 React 랜딩 페이지에서 예상하지 못한 문제가 생겼습니다. Chrome이 띄운 "이 페이지를 번역하시겠습니까?" 제안을 수락하면 번역이 시작되는 듯하다가, 잠시 뒤 사이트의 "일시적인 오류가 발생했습니다" 화면으로 바뀌었습니다.
- Next.js에서 링크를 눌렀는데 로딩 뒤 이전 화면이 다시 나타나는 이유페이지 이동을 빠르게 보이게 만드는 장치는 대개 눈에 잘 띄지 않습니다. 미리 다음 화면을 받아 두거나, 서버 응답을 기다리는 동안 스켈레톤을 보여주는 식입니다. 이번에는 그 두 가지가 한꺼번에 작동하면서 오히려 이동을 늦추고 화면 상태까지 헷갈리게 만들었습니다.
- Next.js는 운영에서 멀쩡한데 로컬 개발 서버에서만 UI가 먹통이 되는 이유Next.js 애플리케이션은 운영 빌드가 안정적이면 개발 서버도 같은 방식으로 움직일 것 같지만, 둘은 클라이언트 코드의 수명이 다릅니다. 제가 확인한 환경은 Next.js 16.2.7과 Turbopack이었고, 운영 사이트에서는 잘 눌리던 상단 메뉴가 로컬 개발 서버에서만 간헐적으로 먹통이 됐습니다.