공간 부족 - Docker 이미지가 큰가요?

안녕하세요, 저는 25GB 클라우드 VM(Debian 13)에서 소규모 셀프호스팅 포럼을 운영 중입니다. ./launcher rebuild app 명령을 사용하여 2026.6.0-latest로 업데이트를 시도했는데, 디스크 공간이 부족하여 업데이트가 취소되었습니다. 안내에 따라 Docker 이미지를 정리했지만 문제가 해결되지 않았습니다. 현재 남은 공간은 3.9GB입니다. 포럼 업로드 파일은 138MB, 백업 파일은 448MB 정도입니다. 이 서버에는 Discourse 설치 외에는 다른 작업이 없었습니다.

du 명령으로 확인해 보니 /var/lib/containerd가 13GB, /var/docker가 5.1GB를 차지하고 있었습니다. 이 정도 용량을 차지하는 것이 정상적인가요? 해결할 수 있는 방법이 있을까요?

정상적인 현상이라면 추가 저장비를 지불해야 할 것 같습니다. 추가 비용 지출 전에 확인받고 싶었습니다. 감사합니다!

음… ./launcher cleanup을 시도해 보셨나요?

정리를 실행해 볼 가치가 있습니다. 무슨 일이 있었는지 세부 사항을 게시해 주세요. 이전에 제가 했던 작업의 예시입니다:

root@ubuntu-2gb-nbg1-1:/var/discourse# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        19G   12G  6.5G  65% /

root@ubuntu-2gb-nbg1-1:/var/discourse# ./launcher cleanup
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B

WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y

Deleted Images:
deleted: sha256:33ce56b3484175342191a344fe1aa9f330431de7bf6f0f0e14f75c5bd851a5b0
deleted: sha256:5e04a0411f813e8f2c1a50d84a7d7bb1b17a855ce041730cf8e3b2fb90144b19
untagged: discourse/base:2.0.20200512-1735
untagged: discourse/base@sha256:7f6c5be23a8e4237cecafaca9d041de5964f8237345b7b183cebdee1f73ed024
deleted: sha256:991acdba0b1f18141192f8682bc5ec1c3365dff0d4fa1c6504e6ce0e3ae6dd76
deleted: sha256:e1c41c8dbd697ae0a61ca612c61f085f69f5bf74c4269cf5c68b4de0fec723fa
deleted: sha256:c2adabaecedbda0af72b153c6499a0555f3a769d52370469d8f6bd6328af9b13
untagged: discourse/base:2.0.20200724-1815
untagged: discourse/base@sha256:1d5eb2f8eae84203b28d3c643648d0dd7d213c2055865cfa5132e30db9e365d5

Total reclaimed space: 2.591GB

# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        19G  8.7G  9.3G  49% /

디스크 사용량에 대한 상세한 정보를 확인하고 이를 여기에 게시하는 것도 좋습니다! 예를 들어 아래를 참고하세요.

시스템에 백업이 있다면, 그것들을 다운로드하고 테스트한 후 최신 것 하나를 제외한 나머지를 삭제해야 합니다. 극도로 공간이 부족하다면 최신 백업도 삭제하십시오. (제 경우에는, 다운로드한 사본이 제 개인 오프사이트 백업에도 포함되어 있는지 먼저 확인합니다. 항상 두 개 이상의 사본을 유지하세요.)

OS 레벨에서 질문에 답하는 du 외에도, docker 레벨에서 질문을 할 수 있습니다. 상세한 조사 결과를 게시해 주세요!

# docker volume ls -qf dangling=true
# docker images -a

25G 인스턴스에서 디스크 사용량을 관리하는 것은 어렵습니다 - 저는 오랜 시간 동안 시간을 들여 시스템 관리 경험을 활용하여 이것을 해왔습니다. 결국 제공업체를 변경하여 더 적은 비용으로 40G를 확보했고, 그것이 훨씬 낫었습니다.

이전에도 관련 글이 있습니다.
25G 드롭렛에서 디스크 공간 부족으로 Discourse 업그레이드 실패

매우 유용한 정보 감사합니다.

cleanup을 시도하기 전에, 복원(restore)을 수행하지 않고 백업 무결성을 확인할 수 있는 방법이 Discourse에 있을까요?

du -hx / | sort -h | tail -49의 결과입니다 (결과를 해석하기 쉬우므로 -h 옵션을 사용했습니다):

833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle/ruby
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle/ruby/3.4.0
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www/discourse
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www/discourse/vendor
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www/discourse/vendor/bundle
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www/discourse/vendor/bundle/ruby
837M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs/var/www/discourse/vendor/bundle/ruby/3.4.0
839M	/var/discourse/shared
839M	/var/discourse/shared/standalone
840M	/var/discourse
863M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42
863M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs
868M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283
868M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/283/fs
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/284
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/284/fs
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs
908M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/263/fs/usr
925M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22/fs/usr
944M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/263
944M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/263/fs
961M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22
961M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22/fs
1.3G	/usr
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var/www
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var/www/discourse
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www/discourse
1.6G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227
1.6G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs
2.5G	/var/log
2.5G	/var/log/journal
2.5G	/var/log/journal/1d9299c9656046d6bd0e18d4a09c183c
2.7G	/var/lib/containerd/io.containerd.content.v1.content
2.7G	/var/lib/containerd/io.containerd.content.v1.content/blobs
2.7G	/var/lib/containerd/io.containerd.content.v1.content/blobs/sha256
9.8G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs
9.8G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots
13G	/var/lib
13G	/var/lib/containerd
17G	/var
20G	/

docker volume ls -qf dangling=true의 출력은 비어 있었습니다. 실제로 docker volume ls도 비어 있습니다.

docker images -a:

IMAGE                              ID             DISK USAGE   CONTENT SIZE   EXTRA
discourse/base:2.0.20260209-1300   50d2dae489a9       4.77GB         1.12GB        
discourse/base:2.0.20260521-0047   27373b823bbe       4.89GB         1.17GB        
local_discourse/app:latest         01527763be8d        6.9GB         1.63GB    U   

Docker에 대해 아는 것이 적어 이 출력을 진단하기 어렵지만, 로그만이라면 /var/log/가 다소 크고, 포럼을 하나만 운영하고 있는데 이미지가 3개 있는 것은 흥미롭습니다(아마도 이는 완전히 정상적인 상황일 수도 있겠지만요).

저장 공간에 대해 더 신경 써야 한다는 지적에 감사드립니다. 확장을 진행할 가능성이 높지만, 그렇게 하기 전에 좋은 학습 경험이 될 것 같습니다.

저널링(journalling)을 재구성하면 용량을 조금 절약할 수 있습니다:

저는 도커 컨테이너 관리에 대해 제대로 이해한 적이 없습니다. 때로는 정리(cleanup)가 도움이 되기도 합니다. 방금 이 명령어들을 실행해 보았습니다:

# cd /var/discourse/
# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        38G   24G   13G  67% /
# docker images -a
                                                                                             i Info →   U  In Use
IMAGE                              ID             DISK USAGE   CONTENT SIZE   EXTRA
discourse/base:2.0.20260209-1300   18ccefc73392        3.1GB             0B        
local_discourse/app:latest         810ac5579584       4.57GB             0B    U   
<untagged>                         d303cfc49c99       4.37GB             0B        
<untagged>                         a9d03385c205       4.34GB             0B        
# ./launcher cleanup
WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:d303cfc49c992b7fa0b0da65e38f3de79312c6e42eb99e5fd7b27bf4e237ab1d
deleted: sha256:829057c668fd2bd0f7b863c2589e5c3c27364285b39d6df31d38eb208e6410df
untagged: discourse/base:2.0.20260209-1300
untagged: discourse/base@sha256:50d2dae489a9c9916c3d50d880f7f1282fcbe179339b60a8947ab135c1f1f9bf
deleted: sha256:a9d03385c205f740e5f02db0c665a83688f7194d5386bd2d01772b8b5cd5dc65
deleted: sha256:70ec1b4b6cab7365b5f56b8187ef7631e6906fe13b5d3a2b1e39d3457d14514c

Total reclaimed space: 2.517GB
# docker images -a
                                                                                             i Info →   U  In Use
IMAGE                        ID             DISK USAGE   CONTENT SIZE   EXTRA
local_discourse/app:latest   810ac5579584       4.57GB             0B    U   
<untagged>                   18ccefc73392        3.1GB             0B        
# df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        38G   21G   15G  59% /

백업을 완전히 테스트하려면 이를 복원(어딘가에)해야 합니다. 저는 보통 크기만 확인하고,
gunzip -tv filename
을 사용하여 파일이 온전한지 테스트합니다. 또한
tar tvzf filename | less
을 사용하여 내용을 확인하기도 합니다: 압축된 데이터베이스 백업과 제 경우에는 여러 업로드 파일들이 포함되어 있습니다.

./launcher cleanup의 출력 결과:

WARNING! This will remove all stopped containers.
Are you sure you want to continue? [y/N] y
Total reclaimed space: 0B
WARNING! This will remove all images without at least one container associated to them.
Are you sure you want to continue? [y/N] y
Deleted Images:
untagged: discourse/base:2.0.20260209-1300
deleted: sha256:50d2dae489a9c9916c3d50d880f7f1282fcbe179339b60a8947ab135c1f1f9bf
deleted: sha256:1bb6f08ca8363e7e002eaf8bafc76b7742d8baa429f816cde77d3d38d234c98a
deleted: sha256:07596c600885cf3f0647c4b41959c5631328ee37af14913b9f2b1b1771ad4f45
untagged: discourse/base:2.0.20260521-0047
deleted: sha256:27373b823bbeca526dd006cefe1c58e7eeca1e5670ab6e619fcd2138f7d50420
deleted: sha256:ab90467600edc09bae8ac2f43420b7c771f87d357aa15646cd40025ec0774fda
deleted: sha256:053438a5cf1727f724f96a4d7af0b135929f633afd8ee05edcddeaf99232b636

Total reclaimed space: 1.17GB

다만 이상한 점은 이렇습니다: 제 Discourse 포럼의 여유 공간이 3.9GB에서 8.5GB로 증가했습니다. du -hx / | sort -h | tail -49를 다시 실행하면 이전 결과와 비교할 수 있는데, /var/lib의 크기가 8GB 줄었습니다:

628M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www/discourse/vendor/bundle/ruby
628M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www/discourse/vendor/bundle/ruby/3.4.0
629M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www/discourse/vendor
733M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle/ruby/3.4.0/gems
792M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs/var/www/discourse/node_modules/.pnpm
793M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs/var/www/discourse/node_modules
794M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs/var
794M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs/var/www
794M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs/var/www/discourse
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle/ruby
833M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs/var/www/discourse/vendor/bundle/ruby/3.4.0
839M	/var/discourse/shared
839M	/var/discourse/shared/standalone
841M	/var/discourse
863M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42
863M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/42/fs
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43
874M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/43/fs
925M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22/fs/usr
961M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22
961M	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/22/fs
1.3G	/usr
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var/www
1.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/251/fs/var/www/discourse
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www
1.5G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs/var/www/discourse
1.6G	/var/lib/containerd/io.containerd.content.v1.content
1.6G	/var/lib/containerd/io.containerd.content.v1.content/blobs
1.6G	/var/lib/containerd/io.containerd.content.v1.content/blobs/sha256
1.6G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227
1.6G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/227/fs
2.5G	/var/log
2.5G	/var/log/journal
2.5G	/var/log/journal/1d9299c9656046d6bd0e18d4a09c183c
6.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs
6.4G	/var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots
7.9G	/var/lib/containerd
8.0G	/var/lib
12G	/var
15G	/

그리고 docker images -a의 출력도 눈에 띄게 다릅니다:

IMAGE                        ID             DISK USAGE   CONTENT SIZE   EXTRA
local_discourse/app:latest   01527763be8d        6.9GB         1.63GB    U   

./launcher cleanup가 재사용된 공간의 양을 과소평가하는 것 같습니다.

이제 업데이트를 수행할 충분한 공간이 있을 것입니다. 업데이트 후 cleanup을 실행하는 것이 좋은 습관인 것 같습니다.

도움 주셔서 감사합니다!

방금 두 개의 기본 이미지를 정리하고 로컬에서 빌드된 이미지를 남겨 두었습니다.

베이스 이미지는 원래 설치 과정의 잔재일 뿐인가요? 아니면 rebuild app 실행 시에도 다운로드되나요?

네. 이미지가 없으면 최신 이미지가 다운로드되며, 이를 기반으로 로컬 이미지를 빌드하게 됩니다.

기본 이미지를 하나 이상 유지하려는 이유가 무엇인지 떠오르지 않습니다…

여기서도 여전히 상당한 절감이 가능합니다.