
"이런 건 주니어 때나 겪는 거 아닌가?"
나는 그렇게 생각했다. 그리고 틀렸다.
오전에 아무 생각 없이 Spring Boot 프로젝트를 빌드하려는데 갑자기 IDE가 멈췄다.
docker pull도 안 되고, 로그도 안 쌓이고, 심지어 새 파일 하나 저장도 안 됐다.
탐색기를 켰더니 C 드라이브: 540GB / 540GB
지금까지 개발하면서 처음 보는 숫자였다.
맥북도 아니고, 스펙 좋은 윈도우 개발 머신에서 이런 일이 생길 거라고 전혀 예상하지 못했다.
순간 "내가 뭔가 이상한 짓을 한 게 있나?" 싶어서 최근 작업을 되짚어봤다.
특별한 게 없었다. 그냥 평소처럼 Docker 쓰고, 코딩하고, 컨테이너 띄우고 내리고…
그런데 왜?
WinDirStat으로 디스크를 분석해보니 상황이 한눈에 들어왔다.
C:\Users\[사용자]\AppData\Local\Docker\wsl\disk\docker_data.vhdx → 164GB
C:\Users\[사용자]\Videos\화면 녹화\ → 45GB
C:\Users\[사용자]\.gradle\caches\ → 9GB
C:\Users\[사용자]\.m2\repository\ → 3.5GB
가장 충격적인 건 단연 docker_data.vhdx — 164GB.
Docker 이미지가 많긴 했다. Oracle, Kafka, PostgreSQL(pgvector), Zookeeper...
그래도 실제 이미지 용량을 docker images로 확인해보면 총합이 30GB 남짓이었다.
그럼 나머지 134GB는 어디서 온 걸까?
나는 vhdx가 뭔지 안다. Virtual Hard Disk 파일이다.
WSL2(Windows Subsystem for Linux 2)를 사용할 때 리눅스 파일 시스템을 윈도우에서 저장하는 방식이다.
Docker Desktop on Windows는 내부적으로 WSL2를 사용하고, 모든 Docker 데이터(이미지, 볼륨, 레이어 캐시 등)를 이 vhdx 파일 하나에 담는다.
여기까지는 알고 있었다.
그런데 내가 몰랐던 것, 혹은 알면서도 신경 안 쓰던 것이 있었다.
vhdx 파일은 한 번 커지면 데이터를 지워도 자동으로 줄어들지 않는다.
리눅스 ext4 파일 시스템이 그렇듯, vhdx 내부에서 데이터가 삭제되면 해당 블록은 "비어있음"으로 마킹되지만, vhdx 파일 자체의 크기는 그대로다.
OS 입장에서는 그 공간을 다시 쓸 수 있다고 알고 있지만, 호스트 윈도우 입장에서는 파일 크기 164GB가 그대로 유지된다.
비유하자면 이렇다.
커다란 창고가 있다고 치자. 창고 안에 짐을 가득 채웠다가 다 꺼냈다.
창고 내부는 비었지만, 창고 건물 자체가 작아지진 않는다.
그게 vhdx다.
나는 몇 달 동안 Docker 컨테이너를 수도 없이 올리고 내리고, 이미지를 받고 지우고를 반복했다. Oracle DB, Kafka 클러스터, pgvector PostgreSQL, Minikube까지.
그 흔적들이 모두 vhdx 파일을 부풀렸고, docker rmi로 이미지를 지워도 vhdx는 전혀 줄어들지 않았던 것이다.
이걸 몰랐다는 게 창피하기보다, 알면서도 "설마 이렇게까지 커지겠어?" 했던 안일함이 더 부끄러웠다.
일단 Docker 내부부터 정리했다.
# 사용하지 않는 이미지, 컨테이너, 네트워크, 빌드 캐시 전부 삭제
docker system prune -a
# 결과: ~30GB 정리
그런데 여기서 함정이 있다. docker system prune -a를 실행해도 vhdx 파일 크기는 그대로다. 내부 데이터를 정리했을 뿐, 윈도우가 인식하는 파일 크기는 변하지 않는다.
Windows Home에는 Optimize-VHD PowerShell 명령이 없다 (Pro 이상 전용). 그래서 diskpart를 써야 한다.
주의: 반드시 Docker를 완전히 종료하고 WSL을 셧다운한 뒤 진행해야 한다.
# 1. WSL 완전 종료 (Docker Desktop 먼저 종료 후)
wsl --shutdown
# 2. 관리자 권한으로 PowerShell 실행 후 diskpart 진입
diskpart
DISKPART> select vdisk file="C:\Users\[사용자명]\AppData\Local\Docker\wsl\disk\docker_data.vhdx"
DISKPART> attach vdisk readonly
DISKPART> compact vdisk
DISKPART> detach vdisk
DISKPART> exit
compact vdisk 명령이 실행되면 vhdx 내부의 빈 블록을 실제로 압축해서 파일 크기를 줄여준다.
파일 크기에 따라 수십 분이 걸릴 수 있다.
결과: 164GB → 64GB (약 100GB 회수)
순수하게 Docker 데이터 정리 + vhdx 압축만으로 100GB를 돌려받았다.
vhdx가 메인 범인이었지만, 다른 것들도 정리했다.
# Gradle 캐시 정리 (9GB → 4.5GB)
Remove-Item "$env:USERPROFILE\.gradle\caches" -Recurse -Force
# Maven 캐시 전체 삭제 (3.5GB) - 필요하면 다시 받으면 됨
Remove-Item "$env:USERPROFILE\.m2\repository" -Recurse -Force
# 임시 파일 정리
Remove-Item "$env:TEMP\*" -Recurse -Force -ErrorAction SilentlyContinue
화면 녹화 파일들(45GB)도 발견했다.
아무 생각 없이 찍어놓고 잊어버린 것들이었다.
최종 결과: C 드라이브에서만 약 153GB 회수, 전체적으로 290GB 이상 정리
로컬 개발 환경에서 디스크 꽉 찬 건 "아 불편하네" 수준이지만, 운영 서버나 AWS EC2에서 같은 일이 발생하면 이야기가 달라진다.
| 상황 | 결과 |
|---|---|
| DB 볼륨 디스크 꽉 참 | INSERT/UPDATE 실패 → 데이터 유실 |
| 로그 디렉토리 꽉 참 | 로그 기록 불가 → 장애 원인 파악 불가 |
| 컨테이너 레이어 저장 실패 | 서비스 재시작 불가 → 서비스 다운 |
| CI/CD 파이프라인 디스크 부족 | 빌드/배포 실패 |
특히 "로그가 안 쌓이는 상황"은 개발자 입장에서 최악이다.
뭔가 잘못되고 있는데 원인을 전혀 알 수 없게 된다.
그 상태에서 장애 대응을 해야 하는 상황을 생각해보면 끔찍하다.
docker-compose.yml 또는 개별 컨테이너에 반드시 설정해두자.
services:
app:
image: my-app
logging:
driver: "json-file"
options:
max-size: "100m" # 로그 파일 최대 100MB
max-file: "3" # 파일 3개까지만 유지 (300MB 상한)
이 설정이 없으면 컨테이너 로그가 무한정 쌓인다. 오래 운영할수록 GB 단위가 된다.
Windows (작업 스케줄러에 PowerShell 스크립트 등록)
# weekly_docker_cleanup.ps1
Write-Host "Docker cleanup 시작..."
docker system prune -f
Write-Host "완료. 현재 Docker 사용 용량:"
docker system df
Linux/Mac (crontab)
# 매주 일요일 새벽 3시에 자동 실행
0 3 * * 0 docker system prune -f >> /var/log/docker-cleanup.log 2>&1
EC2를 운영한다면 반드시 설정해두자.
CloudWatch → 경보 생성 → disk_used_percent 지표 선택
70% 이상: 경고 알림 (Slack/Email)
85% 이상: 위험 알림 + 자동 정리 Lambda 트리거
Docker Desktop에서는 Settings → Resources → Advanced → Disk image location 에서 현재 vhdx 크기를 확인할 수 있다.
월 1회 정도는 아래 루틴을 실행하는 걸 권장한다
# 1. Docker Desktop 종료
# 2. WSL 셧다운
wsl --shutdown
# 3. diskpart로 압축
diskpart
# select vdisk file="경로\docker_data.vhdx"
# attach vdisk readonly
# compact vdisk
# detach vdisk
# exit
# 4. Docker Desktop 재시작
Docker Desktop → Settings → Resources → Virtual disk limit
기본값이 상당히 크게 설정되어 있을 수 있다.
본인 개발 환경에 맞게 명시적으로 상한선을 설정해두는 것을 추천한다.
개발하다 보면 어느 순간 "이런 건 당연히 알지"라는 착각에 빠진다.
그런데 "알고 있다"와 "제대로 관리하고 있다"는 전혀 다른 이야기다.
나는 vhdx가 뭔지 알고 있었다.
WSL2가 어떻게 동작하는지도 알고 있었다.
그런데 막상 그게 내 로컬 환경에서 조용히 수백 GB를 잡아먹고 있을 거라고는 생각하지 못했다.
아는 것과 신경 쓰는 것은 다르다.
주니어 때 선배들한테 자주 들었던 말이 있다.
"서버 디스크는 항상 여유를 두고 관리해야 한다."
그 말을 충분히 들었고, 충분히 이해했다고 생각했는데, 정작 내 로컬 환경은 전혀 신경 쓰지 않았다.
"로컬이니까 괜찮겠지" 라는 안일함이 540GB를 가득 채우는 데 기여했다.
경력이 쌓일수록 오히려 기본기에 더 신경 써야 한다.
그 기본기를 소홀히 하는 순간, 아무것도 안 되는 아침이 찾아온다.
이 글이 같은 실수를 겪지 않는 데 조금이라도 도움이 됐으면 한다.
docker_data.vhdx에 모든 데이터를 저장한다diskpart의 compact vdisk 명령으로 수동 압축이 필요하다