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 배포에서만 같은 오류가 다시 나오면 코드보다 빌드 이미지에 무엇이 들어갔는지 봐야 합니다. 이번 작업에서는 린트, 타입 검사, 프로덕션 빌드를 모두 통과시킨 뒤 배포했는데 원격 빌드만 실패했습니다. 같은 커밋과 같은 잠금 파일을 썼으니 처음에는 환경 차이가 …
- robots.txt는 무엇이고 왜 필요한가웹사이트를 운영하다 보면 루트 주소에서 robots.txt라는 작은 텍스트 파일을 만나게 됩니다. 내용은 몇 줄뿐인데 검색엔진 최적화 점검표에는 거의 빠지지 않고 등장합니다.
- 블로그를 서브도메인에서 하위 경로로 옮긴 이유, 그리고 CSP가 애드센스를 막고 있었습니다회사 사이트와 기술 블로그를 따로 운영하는 구성은 흔합니다. 회사는 duolabs.co.kr, 블로그는 blog.duolabs.co.kr.
- 로컬에서는 정상인데 운영에서만 깨진 AI 스트리밍문서 AI 기능을 로컬에서 완성하고 운영에 배포했을 때, 답변 자체는 정상인데 화면의 느낌이 완전히 달라졌습니다. 스트리밍 답변은 한꺼번에 나타났고, 전체 화면 패널은 작은 섹션 안에 갇혔으며, 모달이 열리자마자 배경 스크롤 잠금이 풀렸습니다.
- 온프레미스 Next.js 서비스를 Vercel과 Supabase로 옮기기온프레미스에서 서비스를 운영하면 애플리케이션, 데이터베이스, Redis, WebSocket 서버와 백그라운드 워커를 한 네트워크 안에 둘 수 있습니다. 프로세스를 계속 띄워두기도 쉽습니다. setInterval로 10초마다 데이터베이스를 확인하는 코드도 일단은 잘 동작합니다.