Docker VHDX 파일 압축으로 150GB 확보하기

궁금하면 500원·2026년 2월 20일

데브옵스

목록 보기
39/39

개발자가 C 드라이브 꽉 차서 멘붕이 온 날

Docker vhdx 파일의 배신

"이런 건 주니어 때나 겪는 거 아닌가?"
나는 그렇게 생각했다. 그리고 틀렸다.


아무것도 안 되는 그날

오전에 아무 생각 없이 Spring Boot 프로젝트를 빌드하려는데 갑자기 IDE가 멈췄다.
docker pull도 안 되고, 로그도 안 쌓이고, 심지어 새 파일 하나 저장도 안 됐다.

탐색기를 켰더니 C 드라이브: 540GB / 540GB

지금까지 개발하면서 처음 보는 숫자였다.

맥북도 아니고, 스펙 좋은 윈도우 개발 머신에서 이런 일이 생길 거라고 전혀 예상하지 못했다.
순간 "내가 뭔가 이상한 짓을 한 게 있나?" 싶어서 최근 작업을 되짚어봤다.

특별한 게 없었다. 그냥 평소처럼 Docker 쓰고, 코딩하고, 컨테이너 띄우고 내리고…

그런데 왜?


WinDirStat이 보여준 충격적인 현실

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가 뭔지 알면서도 몰랐던 것

나는 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는 전혀 줄어들지 않았던 것이다.

이걸 몰랐다는 게 창피하기보다, 알면서도 "설마 이렇게까지 커지겠어?" 했던 안일함이 더 부끄러웠다.


생각보다 까다로웠다

1단계: Docker 데이터 정리

일단 Docker 내부부터 정리했다.

# 사용하지 않는 이미지, 컨테이너, 네트워크, 빌드 캐시 전부 삭제
docker system prune -a

# 결과: ~30GB 정리

그런데 여기서 함정이 있다. docker system prune -a를 실행해도 vhdx 파일 크기는 그대로다. 내부 데이터를 정리했을 뿐, 윈도우가 인식하는 파일 크기는 변하지 않는다.

2단계: vhdx 파일 압축 — diskpart 사용

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 파이프라인 디스크 부족빌드/배포 실패

특히 "로그가 안 쌓이는 상황"은 개발자 입장에서 최악이다.
뭔가 잘못되고 있는데 원인을 전혀 알 수 없게 된다.
그 상태에서 장애 대응을 해야 하는 상황을 생각해보면 끔찍하다.


이것만 해두면 같은 실수 안 한다

1. Docker 로그 사이즈 제한 설정

docker-compose.yml 또는 개별 컨테이너에 반드시 설정해두자.

services:
  app:
    image: my-app
    logging:
      driver: "json-file"
      options:
        max-size: "100m"   # 로그 파일 최대 100MB
        max-file: "3"      # 파일 3개까지만 유지 (300MB 상한)

이 설정이 없으면 컨테이너 로그가 무한정 쌓인다. 오래 운영할수록 GB 단위가 된다.

2. 정기 정리 자동화

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

3. AWS CloudWatch 디스크 알람

EC2를 운영한다면 반드시 설정해두자.

CloudWatch → 경보 생성 → disk_used_percent 지표 선택

70% 이상: 경고 알림 (Slack/Email)
85% 이상: 위험 알림 + 자동 정리 Lambda 트리거

4. vhdx 주기적 압축

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 재시작

5. Docker Desktop 설정에서 디스크 사이즈 제한

Docker Desktop → Settings → Resources → Virtual disk limit

기본값이 상당히 크게 설정되어 있을 수 있다.
본인 개발 환경에 맞게 명시적으로 상한선을 설정해두는 것을 추천한다.


기본기를 우습게 보지 마라

개발하다 보면 어느 순간 "이런 건 당연히 알지"라는 착각에 빠진다.
그런데 "알고 있다"와 "제대로 관리하고 있다"는 전혀 다른 이야기다.

나는 vhdx가 뭔지 알고 있었다.
WSL2가 어떻게 동작하는지도 알고 있었다.
그런데 막상 그게 내 로컬 환경에서 조용히 수백 GB를 잡아먹고 있을 거라고는 생각하지 못했다.

아는 것과 신경 쓰는 것은 다르다.

주니어 때 선배들한테 자주 들었던 말이 있다.

"서버 디스크는 항상 여유를 두고 관리해야 한다."

그 말을 충분히 들었고, 충분히 이해했다고 생각했는데, 정작 내 로컬 환경은 전혀 신경 쓰지 않았다.

"로컬이니까 괜찮겠지" 라는 안일함이 540GB를 가득 채우는 데 기여했다.

경력이 쌓일수록 오히려 기본기에 더 신경 써야 한다.

그 기본기를 소홀히 하는 순간, 아무것도 안 되는 아침이 찾아온다.

이 글이 같은 실수를 겪지 않는 데 조금이라도 도움이 됐으면 한다.


핵심 요약

  • Docker on Windows는 docker_data.vhdx에 모든 데이터를 저장한다
  • 데이터를 삭제해도 vhdx 파일 크기는 자동으로 줄지 않는다
  • diskpartcompact vdisk 명령으로 수동 압축이 필요하다
  • 로그 사이즈 제한, 정기 prune, 디스크 알람은 운영 환경에서 필수다
  • "알고 있다"는 착각이 가장 위험하다

profile
그냥 코딩할래요 재미있어요

0개의 댓글