여러분 안녕하세요. 저는 Lee이고, 2013년부터 간간이 Discourse를 셀프호스팅해 왔습니다. 시작하기만 해도 rbenv를 만져야 했던 기억이 납니다. Phusion Passenger를 포함해서 nginx를 컴파일해야만 시스템이 돌아가게 했던 기억도 납니다. 아마 10년 전쯤이었을까요, Docker로 전환하는 것은 개발자의 '내 홈 디렉터리에서는 잘 돌아가는데, 내 닷파일(dotfiles)은 악몽이다’라는 약점에 굴복하는 것이라고 @sam과 치열하게 논쟁했던 기억도 납니다. (그리고 저는 완전히 틀렸었죠!). '바이크 셰딩(bike-shedding)'이라는 말을 처음 들었을 때의 기억도 생생합니다. 그분의 말대로, 나는 모든 것을 기억합니다.
몇 년간 자리를 비운 후, 다시 Discourse 셀프호스팅으로 돌아온 이유는 휴스턴 지역 날씨 사이트의 네이티브 WordPress 댓글을 대체하기 위해서였습니다. 이 사이트는 평소에는 하루 약 1만 PV를 기록하지만, 허리케인 시에는 하루 약 200만 PV와 약 100만 명의 고유 방문자를 기록하기도 합니다. 우리는 수년간 WordPress의 네이티브 댓글 기능 때문에 고생해 왔지만, 지난 수요일부터 셀프호스팅된 Discourse로 전환하여 서비스 중입니다. (그것도 Graviton3 위에서요! 진심으로, 그냥 잘 돌아가고 훌륭합니다.)
제가 드디어 도달하려는 핵심은 이렇습니다. 2025년인 지금, 셀프호스터인 저는 여전히 수동으로 Docker 이미지 공간을 관리하고 있습니다. 프로덕션 환경에서 일주일도 채 안 된 시점에 /dev/root에 대한 이야기를 코드 스니펫으로 들려드리겠습니다:
[11:49:56] 0 ✓ (1.8ms)
root@discourse:/var/discourse # df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 30G 21G 9.6G 69% /
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 3.1G 1.1M 3.1G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
efivarfs 128K 3.6K 125K 3% /sys/firmware/efi/efivars
/dev/nvme1n1p16 891M 109M 720M 14% /boot
/dev/nvme1n1p15 98M 6.4M 92M 7% /boot/efi
/dev/nvme0n1 32G 346M 30G 2% /var/discourse
tmpfs 1.6G 12K 1.6G 1% /run/user/1001
overlay 30G 21G 9.6G 69% /var/lib/docker/overlay2/5a649418bbfc064f488e895572eec1ace487a3eaa324fe1d8e3b395e6c5e3645/merged
[11:49:59] 0 ✓ (4.8ms)
root@discourse:/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:
untagged: discourse/base@sha256:3696bdf18652b5455bd33795ec3b8e0f201c17a04f0e0126fc0317ed821373cd
....
[여기서 아주 많은 줄들이 생략되었습니다]
....
Total reclaimed space: 12.43GB
[11:50:34] 0 ✓ (27.8s)
root@discourse:/var/discourse # df -h
Filesystem Size Used Avail Use% Mounted on
/dev/root 30G 6.9G 24G 23% /
tmpfs 7.7G 0 7.7G 0% /dev/shm
tmpfs 3.1G 1.1M 3.1G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
efivarfs 128K 3.6K 125K 3% /sys/firmware/efi/efivars
/dev/nvme1n1p16 891M 109M 720M 14% /boot
/dev/nvme1n1p15 98M 6.4M 92M 7% /boot/efi
/dev/nvme0n1 32G 346M 30G 2% /var/discourse
tmpfs 1.6G 12K 1.6G 1% /run/user/1001
overlay 30G 6.9G 24G 23% /var/lib/docker/overlay2/5a649418bbfc064f488e895572eec1ace487a3eaa324fe1d8e3b395e6c5e3645/merged
[11:55:28] 0 ✓ (3.3ms)
root@discourse:/var/discourse #
여러분을 사랑합니다. Discourse를 사랑합니다. 저는 이 제품에 완전히 매료되었고, 앞으로도 영원히 계속 사용할 의향이 있습니다.
하지만, 음… 도대체 _왜_일까요. 2025년인데도 제가 직접 여전히launcher cleanup을 만지고 있어야 하는 이유는 무엇인가요? 왜 이미지 관리가 launcher의 내장 기능이 아닌가요?
다시 한번 말씀드리지만, 여러분을 사랑합니다. 저는 SCW에 Discourse를 선택한 이유는 여러분이 구축한 것에 대한 믿음과 그것을 사용하는 것을 사랑하기 때문입니다. 하지만… 제 가난한 AMI 부팅 볼륨의 절반이 기술적인 측면을 제가 제대로 이해하고 있다면 자동으로 관리될 수 있을 useless한 쓰레기로 가득 차 있다는 사실은 아쉬울 따름입니다.
불평하려는 의도는 아닙니다. 관리자 의자에서 몇 년간 떠나 있다가 다시 체크인을 해보는 것뿐입니다. AI 스팸 감지 기능과 AI 트리아지 기능을 정말 좋아합니다. 특히 기후 변화 관련 정치적 논쟁(지지 또는 반대)이 일상적인 날씨 포럼에서는 더더욱 그렇습니다. 모든 것에 감사드립니다 <3
일부 이유는 '충분히 괜찮아서’입니다. 우리는 내부 호스팅에서 이 기능을 사용하지 않습니다. 컨테이너와 이미지를 자주 교체하기 때문에, 자체 호스팅 사이트와 비교했을 때 업데이트 주기가 훨씬 다르기 때문입니다.
또 다른 설명은, 런처와 Docker 양쪽 모두 데이터 삭제 일정에 대한 전체적인 책임을 지려 하지 않는다는 점입니다. 사용자 데이터 삭제 일정에 대한 제어 권한은 사용자에게 전적으로 있어야 합니다.
자체 호스팅 사이트에서 몇 가지 문제를 겪어 본 적이 있습니다. 정리 작업이 새로 구축해야 할 discourse 기반 환경까지 함께 정리해 버려서, 악순환에 빠지는 문제가 발생했습니다. 이런 일이 자동으로 실행되는 과정에서 발견되지 않으면, 원인을 파악하는 데 상당한 장애물이 될 수 있습니다.
간단한 제안으로, 스스로의 책임 하에 docker system prune 또는 launcher clean을 cronjob으로 실행해 보시는 것이 좋겠습니다. 효과가 있을지도 모르겠습니다.
사실 제가 언급한 것은 ./launcher cleanup 명령을 실행할 때 나타나는 질문들입니다. 먼저 모든 중지된 컨테이너를 제거합니다. 그런 다음 적어도 하나의 컨테이너에 의해 사용되지 않는 모든 이미지를 삭제할지 여부를 제안하는데, 이 부분이 제 경우 공간을 확보해 주는 핵심입니다. 지난번에는 거의 40GB를 확보했습니다.
그래서 왜 jpg, png 같은 고아 이미지(orphan images)가 그렇게 많았는지 이해할 수 없어 꽤 혼란스러웠습니다. 하지만 여기서 말하는 이미지와 제가 언급한 이미지는 완전히 다른 종류이죠.
네, 저는 적어도 주 2회 재빌드(rebuild)를 수행합니다. 또는 최근 문제 있는 플러그인을 추적하던 당시에는 재빌드를 수십 번이나 수행하기도 했습니다.
아마도 나에게 도움이 될 잠재적인 우회책이 있을 것 같습니다. 다른 분들에게도 도움이 될 수 있을 것 같아 여기에 공유합니다.
/etc/docker/daemon.json에 data-root 설정을 추가하는 것을 고려하고 있습니다. 이렇게 하면 Docker가 이미지를 덜 중요한 위치에 배치하도록 강제할 수 있는지 확인해 보려는 것입니다. 이 서버에는 Discourse 이미지 외에 다른 것이 호스팅되지 않기 때문에, 부팅 볼륨이 터지는 것을 방지하기 위함입니다.
메타 사이트에서 이 주제에 대한 이전 스레드를 검색해 보면 몇 가지결과가 나오지만, 실질적인 정보를 제공하지는 않습니다. 내 프로덕션 Discourse 인스턴스가 불타는 잔불 더미로 붕괴하기 전에, 이 방법이 실행 가능한지 물어보고 싶었습니다
저는 다른 접근 방식을 취하여 /var/lib/docker에 별도의 파일 시스템을 마운트했습니다.
제 경우, 매우 사이트 특이적인 이유로 /var/discourse/shared, /var/discourse/shared/data, /var/discourse/shared/app/uploads/default/original, /var/lib/docker 각각에 대해 별도의 파일 시스템을 선택했습니다. 하지만 단순히 /var/discourse를 별도의 파일 시스템으로만 사용하길 원한다면, /var/discourse/share/docker 디렉토리를 생성하여 /var/lib/docker에 바인드 마운트하는 것이 가능할 것입니다(물론 시스템이 안정된 상태에서 수행하고 필요한 경우 파일을 이동해야 합니다).