Docker로 개발하다 보면 누구나 한 번쯤 만나게 되는 골치 아픈 에러가 바로 “no space left on device”입니다. 어제까지 잘 동작하던 컨테이너가 갑자기 멈춰버리고, 새로운 이미지도 풀받을 수 없는 상황이 발생합니다. 분명 하드디스크에는 여유 공간이 충분한데 왜 이런 에러가 발생하는지 이해할 수 없을때가 종종 있곤 하죠. 하지만 Docker의 저장 구조를 이해한다면 문제의 원인을 파악하고 해결할 수 있습니다.

 

1. “no space left on device” 에러 발생 원인 파악하기

Docker의 “no space left on device” 에러는 주로 /var/lib/docker 디렉터리가 있는 파티션의 공간이 부족할 때 발생합니다. Docker는 기본적으로 이 위치에 모든 데이터를 저장하는데, 여기에는 다음과 같은 요소들이 포함됩니다:

  • Docker 이미지: 각 레이어별로 저장되어 용량이 큰 편
  • 컨테이너 데이터: 실행 중인 컨테이너의 쓰기 가능한 레이어
  • 볼륨: 영구 데이터 저장용
  • 빌드 캐시: 이미지 빌드 시 생성되는 임시 데이터
  • 컨테이너 로그: 시간이 지날수록 계속 누적됨

특히 로그 파일의 경우, Docker는 기본적으로 로그 회전(rotation)을 하지 않기 때문에 시간이 지나면서 GB 단위로 커질 수 있습니다.

 

 

2. 즉시 해결방법 (긴급 상황 대응)

현재 Docker 디스크 사용량 확인

먼저 어디서 용량을 많이 차지하고 있는지 확인해보겠습니다:

# Docker 전체 디스크 사용량 확인
docker system df

# 더 자세한 정보 보기
docker system df -v

결과는 다음과 같이 나타납니다:

TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          31        2         12.86GB   12.41GB (96%)
Containers      2         2         63B       0B (0%)
Local Volumes   27        2         4.404GB   4.355GB (98%)
Build Cache     244       0         6.249GB   6.249GB

긴급 정리 – 모든 미사용 리소스 제거

가장 빠른 해결책은 미사용 리소스를 모두 제거하는 것입니다:

# 중지된 컨테이너, 사용하지 않는 네트워크, 댕글링 이미지, 빌드 캐시 제거
docker system prune -f

# 더 철저한 정리 (사용하지 않는 이미지까지 모두 제거)
docker system prune -a -f

# 볼륨까지 포함한 완전 정리 (주의: 데이터 손실 가능)
docker system prune -a -f --volumes

컨테이너 로그 즉시 정리

로그 파일이 너무 클 때 즉시 해결하는 방법:

# 모든 컨테이너 로그 파일 비우기
sudo sh -c 'truncate -s 0 /var/lib/docker/containers/*/*-json.log'

# 특정 컨테이너 로그만 정리
truncate -s 0 /var/lib/docker/containers/[컨테이너ID]/[컨테이너ID]-json.log

 

 

3. 이미지, 컨테이너, 볼륨, 네트워크 리소스 정리하기!

Docker는 리소스 유형별로 정리할 수 있는 명령어를 제공합니다. 상황에 맞게 선택적으로 사용하면 더 안전합니다.

이미지 정리

# 댕글링 이미지만 제거 (태그가 없는 이미지)
docker image prune

# 사용하지 않는 모든 이미지 제거
docker image prune -a

# 특정 기간 이전 이미지 제거 (예: 24시간)
docker image prune -a --filter "until=24h"

컨테이너 정리

# 중지된 컨테이너 모두 제거
docker container prune

# 24시간 이전에 중지된 컨테이너만 제거
docker container prune --filter "until=24h"

# 실행 중인 컨테이너 확인 후 불필요한 것 중지
docker ps -a
docker stop [컨테이너ID]
docker rm [컨테이너ID]

볼륨 및 네트워크 정리

# 사용하지 않는 볼륨 제거
docker volume prune

# 사용하지 않는 네트워크 제거
docker network prune

# 빌드 캐시 정리
docker builder prune

 

 

4. 근본적 해결책 – Docker 저장소 위치 변경

디스크 용량이 제한적인 파티션에서 더 큰 공간으로 Docker 저장소를 이동하는 것이 가장 확실한 해결책입니다.

daemon.json을 이용한 설정 변경 (권장)

이 방법이 가장 안전하고 권장되는 방식입니다:

# 1. Docker 서비스 중지
sudo systemctl stop docker

# 2. daemon.json 파일 생성/편집
sudo mkdir -p /etc/docker
sudo nano /etc/docker/daemon.json

daemon.json 파일 내용:

{
  "data-root": "/new/path/to/docker"
}
# 3. 새 디렉터리 생성
sudo mkdir -p /new/path/to/docker

# 4. 기존 데이터 복사
sudo rsync -aP /var/lib/docker/ /new/path/to/docker/

# 5. Docker 서비스 재시작
sudo systemctl start docker

# 6. 정상 동작 확인
docker info | grep "Docker Root Dir"

systemd 오버라이드를 이용한 방법

# 1. 오버라이드 디렉터리 생성
sudo mkdir -p /etc/systemd/system/docker.service.d

# 2. 오버라이드 파일 생성
sudo nano /etc/systemd/system/docker.service.d/docker-storage.conf

파일 내용:

[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --data-root /new/path/to/docker -H fd:// --containerd=/run/containerd/containerd.sock
# 3. systemd 리로드 및 재시작
sudo systemctl daemon-reload
sudo systemctl restart docker

 

 

5. 로그 관리, 로그 로테이션 설정

전역 로그 회전 설정

daemon.json에 로그 설정을 추가하여 모든 컨테이너에 적용:

{
  "data-root": "/new/path/to/docker",
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

이 설정은 각 컨테이너의 로그 파일을 최대 10MB로 제한하고, 최대 5개 파일까지 보관합니다.

개별 컨테이너 로그 설정

# 컨테이너 실행 시 로그 옵션 지정
docker run -d \
  --name my-app \
  --log-driver json-file \
  --log-opt max-size=10m \
  --log-opt max-file=3 \
  nginx:latest

Docker Compose에서 로그 설정

version: '3.8'
services:
  web:
    image: nginx:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"

logrotate를 이용한 로그 관리

시스템 차원에서 로그를 관리하려면 logrotate를 설정할 수 있습니다:

# logrotate 설정 파일 생성
sudo nano /etc/logrotate.d/docker

설정 내용:

/var/lib/docker/containers/*/*.log {
    rotate 7
    daily
    compress
    missingok
    delaycompress
    copytruncate
    notifempty
    create 0640 root root
}

 

 

6. no space left on device : 디스크 용량 부족 에러를 예방하고 평소에 모니터링하는 방법

정기적인 정리 자동화

cron을 이용해 주기적으로 정리 작업을 수행합니다:

# crontab 편집
crontab -e

# 매주 일요일 자정에 정리 수행
0 0 * * 0 /usr/bin/docker system prune -f

디스크 사용량 모니터링 스크립트

#!/bin/bash
# docker-monitor.sh

THRESHOLD=80
USAGE=$(df /var/lib/docker | awk 'NR==2 {print $5}' | sed 's/%//')

if [ $USAGE -gt $THRESHOLD ]; then
    echo "Docker 디스크 사용량이 ${USAGE}%입니다. 정리가 필요합니다."
    docker system prune -f
    echo "정리 완료"
fi

Docker 이벤트 모니터링

# Docker 이벤트 실시간 모니터링
docker events --filter type=container

# 특정 시간 범위의 이벤트 확인
docker events --since="2024-01-01" --until="2024-01-31"

 

 

7. 자주 발생하는 문제 (FAQ)

자주 발생하는 문제들

Q: system prune을 했는데도 용량이 줄어들지 않습니다.

A: 다음을 확인해보세요:

# 실행 중인 컨테이너 확인
docker ps

# 큰 용량의 볼륨 확인
docker volume ls
du -sh /var/lib/docker/volumes/*

# 로그 파일 크기 확인
sudo du -sh /var/lib/docker/containers/*/

Q: daemon.json 설정 후 Docker가 시작되지 않습니다.

A: JSON 문법 오류일 가능성이 높습니다:

# JSON 문법 검사
python -m json.tool /etc/docker/daemon.json

# Docker 로그 확인
sudo journalctl -u docker.service

Q: 데이터 이동 중 권한 문제가 발생합니다.

A: rsync 옵션을 다음과 같이 수정하세요:

sudo rsync -aXSvP /var/lib/docker/ /new/path/to/docker/

 

 

이 포스트에서 소개한 방법들을 단계적으로 적용하면 Docker 디스크 용량 문제를 효과적으로 해결할 수 있습니다. 특히 예방적 관리가 가장 중요하니, 정기적인 모니터링과 정리를 습관화하시걸 추천드립니다. 🙂

 

댓글 남기기