ENOSPC no space left on device는 디스크 블록이나 아이노드가 차서 쓰기가 거절될 때 나는 코드입니다. df -h와 df -i를 먼저 보고, 도커는 빌드 캐시와 안 쓰는 이미지부터 지웁니다. 파일 감시 한도가 찬 같은 코드와는 메시지가 다릅니다. Docker, npm, CI, 한국 1인 개발. 2026년 10월 문서.
ENOSPC: no space left on device는 파일 감시 한도가 아니라, 디스크 블록이나 아이노드가 차서 쓰기와 mkdir이 거절될 때 나는 코드입니다. df -h와 df -i를 먼저 보고, 도커는 빌드 캐시와 안 쓰는 이미지부터 지우세요.
넥스트 빌드가 .next를 쓰다 멈추거나, 액션 로그에 no space left on device, write만 남는 장면이 이 줄입니다. df의 사용률이 100%가 아니어도 아이노드가 0이면 같은 코드가 납니다.
감시자가 System limit for number of file watchers reached라고 하는 ENOSPC와는 문장이 다릅니다. 근거는 Node.js 시스템 오류와 docker system df에 뒀습니다.
쓰기 실패와 감시 한도를 가른다
노드의 ENOSPC는 운영체제가 남긴 자리 없음입니다. 경로 뒤에 오는 동사가 원인을 가릅니다. write, mkdir, open이면 디스크입니다. watch이고 문장에 file watchers가 있으면 inotify 개수입니다.
디스크 쪽 전체 문장은 보통 Error: ENOSPC: no space left on device, write입니다. 빌드 중인 파일 경로가 뒤에 붙습니다. 그 경로는 실패한 이유를 설명하지 않고, 쓰려다 거절된 파일만 보여 줍니다. 지울 대상은 그 파일의 상위인 캐시 디렉터리입니다.
감시 한도를 늘리는 fs.inotify.max_user_watches는 이 문장을 고치지 않습니다. 반대로 디스크를 비워도 감시 한도 문장은 그대로입니다. 로그에서 no space left와 file watchers 중 어느 쪽이 있는지 먼저 표시하세요.
한 줄 분기 | no space left on device면 df입니다. file watchers reached면 감시 한도입니다. 코드 이름이 같아도 다음 명령이 다릅니다.
write, mkdir 뒤의 ENOSPC는 블록이나 아이노드가 찬 것이다
블록과 아이노드를 따로 본다
df -h .는 지금 디렉터리가 있는 파일시스템의 바이트입니다. Use%가 99에서 100이면 블록이 찬 것입니다. df -i .의 IUse%가 100이면 파일 개수 한도가 찬 것입니다. 바이트는 남았는데 작은 파일이 너무 많으면 아이노드만 바닥납니다.
확인
100에 가까우면
먼저 볼 디렉터리
df -h .
블록 부족
도커 데이터, .next, 빌드 산출물
df -i .
아이노드 부족
node_modules, overlay 작은 파일
docker system df
이미지, 컨테이너, 빌드 캐시
Build cache, Images
du -xh -d 1
어느 하위 폴더가 큰지
홈의 Library, 프로젝트 루트
맥 도커 데스크톱은 리눅스 VM 안의 디스크가 따로입니다. 맥 파인더의 남은 용량이 충분해도 VM 디스크가 차면 빌드만 ENOSPC가 납니다. docker system df가 VM 안 사용량입니다. 호스트 df -h만 보고 괜찮다고 넘기지 마세요.
깃허브 호스티드 러너도 디스크가 유한합니다. 같은 잡에서 브라우저를 깔고 도커 이미지를 여러 개 빌드하면 후반 스텝에서 write가 죽습니다. 앞 스텝의 성공은 디스크가 남았다는 증거가 아닙니다.
바이트, 아이노드, 도커 사용량
df -h .
df -i .
docker system df
du -xh -d 1 . | sort -h | tail
도커는 빌드 캐시부터 비운다
로컬에서 가장 큰 덩어리는 대개 도커 빌드 캐시와 안 쓰는 이미지입니다. docker builder prune -f는 빌드 캐시를 지웁니다. docker image prune -f는 태그가 없는 이미지만 지웁니다. 둘 다 이름 있는 볼륨의 데이터베이스 파일은 건드리지 않습니다.
볼륨은 마지막입니다. docker volume prune은 컨테이너가 쓰지 않는 볼륨을 지웁니다. 로컬 포스트그레스 데이터가 볼륨에만 있으면 그 명령 뒤에 표가 사라집니다. docker volume ls로 이름을 보고, 프로젝트 compose가 만든 볼륨인지 확인한 뒤에만 지우세요.
docker system prune -a는 안 쓰는 이미지까지 넓게 지웁니다. 다음에 pull과 빌드가 길어집니다. 디스크가 당장 0인 러너에서는 그 비용이 맞을 수 있습니다. 맥의 일상 개발에서는 builder prune과 태그 없는 이미지부터로 충분한 경우가 많습니다.
컨테이너가 지워져도 로그가 큰 json 파일로 남는 일이 있습니다. docker system df의 Local Volumes와 Build Cache 크기를 나란히 보고, 숫자가 큰 줄만 지우세요. 한 번에 모든 종류를 비우는 습관은 로컬 디비를 같이 지웁니다.
캐시와 태그 없는 이미지만 먼저
docker builder prune -f
docker image prune -f
docker system df
# 볼륨은 이름을 확인한 뒤에만
docker volume ls
빌드 캐시와 태그 없는 이미지를 먼저 지우고, 데이터베이스 볼륨은 이름을 본 뒤에 둔다
프로젝트 캐시 중 다시 만들어도 되는 것
저장소 안에서는 재생성되는 디렉터리만 지웁니다. 넥스트 .next, 테스트 산출물, 패키지 매니저 캐시는 다음 명령이 다시 만듭니다. 소스와 .env는 지우지 않습니다.
경로
지워도 되나
다음에 생기는 비용
.next
된다
다음 빌드가 처음부터
node_modules
된다
설치 시간과 아이노드
npm 캐시
된다
패키지를 다시 받는다
도커 볼륨의 디비
이름 확인 전엔 안 된다
데이터가 사라짐
.git
안 된다
이력 손실
아이노드가 문제면 node_modules를 지우는 효과가 큽니다. 작은 파일이 수십만 개라서입니다. 지운 뒤 설치가 다시 ENOSPC면, 설치 전에 도커 캐시로 블록을 확보하세요. 설치 도중 실패하면 반쯤 받은 폴더가 남아 다음 설치가 더 헷갈립니다. 그때는 그 프로젝트의 node_modules만 지우고 다시 설치합니다.
깃허브 액션에서는 체크아웃과 캐시 액션이 러너 디스크를 나눕니다. 캐시 키가 너무 넓으면 옛 캐시가 같이 풀립니다. 한 주 동안 같은 러너 종류에서 빌드 산출물을 캐시하지 말고, 의존 캐시만 남기는 편이 후반 스텝의 write 실패를 줄입니다.
감시 한도, 열린 파일 수와 다른 줄
같은 ENOSPC라도 넥스트 dev가 System limit for number of file watchers reached, watch라고 하면 디스크 정리가 답이 아닙니다. 그 글은 inotify 개수입니다. 이 글의 문장에는 no space left on device와 write 또는 mkdir이 있습니다.
열린 파일 개수가 프로세스 한도에 닿으면 디스크가 남아 있어도 파일을 더 못 엽니다. 그때는 한도 값을 보는 줄이고, 남은 용량과는 다릅니다. 도커 소켓 권한 오류는 데몬에 연결 자체가 안 되는 문장이라, 용량을 비워도 그룹이 없으면 그대로입니다.
포트가 이미 쓰여 서버가 못 뜨는 오류와도 무관합니다. 빌드 로그 중간에 쓰기가 실패하면 그 위에 문법 오류가 따라붙을 수 있습니다. 첫 공간 부족을 남기고 아래 문법부터 고치면, 다음 빌드도 같은 자리에서 디스크에 막힙니다. 관련 글은 감시 한도가 찼을 때, 파일을 더 못 열 때, 도커 소켓 권한입니다.
한국에서 맥북 하나만 쓰는 경우에는 도커 데스크톱의 가상 디스크가 집 용량과 따로 놀습니다. 파인더에는 여유가 보여도 가상 디스크가 가득 차면 이미지 빌드만 공간 부족으로 죽습니다. 데스크톱 설정에서 디스크 이미지 크기를 늘리기 전에, 빌드 캐시와 이름 없는 이미지를 지워 가상 디스크 안을 먼저 비우세요. 크기를 늘리면 맥 저장 공간을 더 예약할 뿐, 안 지운 캐시는 그대로 남습니다.
노트북 저장 공간이 작은 모델은 프로젝트마다 의존 폴더를 두면 아이노드보다 바이트가 먼저 찹니다. 지금 다루지 않는 저장소의 의존 폴더와 빌드 산출물을 지우는 편이, 시스템 전체를 건드리는 정리보다 안전합니다. 환경 파일과 깃 이력은 그대로 두세요. 카카오 키처럼 로컬에만 있는 값은 의존 폴더 밖에 있으니, 그 폴더를 지워도 키가 같이 사라지지는 않습니다. 지운 뒤 설치가 반쯤 실패하면 그 저장소의 의존 폴더만 다시 지우고 설치를 처음부터 하세요.