fix(docker): 컨테이너만 지우고 볼륨·캐시는 안 지우고 있었다 — 누수 차단 + 정기 정리 - #314
Merged
Conversation
"정리가 코드에 되어 있나" 를 확인해 보니 <b>컨테이너까지만</b> 되어 있었다. 그 뒤에 남는 것들은 아무도 지우지 않는다. dev 실측(2026-09-08): 컨테이너 0 개인데 Local Volumes 10개 2.184GB (100% 회수 가능) Build Cache 108개 6.470GB 디스크 29G 중 19G 사용(67%)이었고, 손으로 지우니 11G(38%)가 됐다 — 절반 이상이 찌꺼기였다. 디스크가 차면 앱·MySQL·프리뷰 컨테이너가 한꺼번에 죽고, 그때는 원인이 "디스크" 라는 것조차 로그를 남길 자리가 없다. ## 원천: 익명 볼륨이 고아로 남았다 removeContainerCmd 세 곳이 전부 withForce(true) 만 쓰고 withRemoveVolumes 를 안 붙였다. 컨테이너는 사라지는데 그것이 만든 익명 볼륨은 남는다 — mysql:8.4 프리뷰 DB 가 /var/lib/mysql 용으로 만드는 볼륨이 그것이라 한 건당 200MB 넘게 쌓인다. DockerContainerService (2곳) · CodingAgentContainerRunner (1곳) → withRemoveVolumes(true) 명명 볼륨은 쓰지 않고 bind mount 는 이 옵션의 영향을 받지 않으므로 부작용이 없다. ## 안전망: DockerGarbageSweeper 원천을 막아도 이전에 쌓인 것과 비정상 종료로 새는 것이 남는다. 6시간마다 고아 볼륨 · dangling 이미지 · 오래된 빌드 캐시를 회수한다. - 도커의 prune 은 <b>실행 중이거나 정지 상태로 남아 있는 컨테이너가 참조하는 것을 건드리지 않는다</b> — 살아 있는 프리뷰 세션은 대상이 아니다. - 빌드 캐시는 until 이전 것만(기본 48시간). 방금 만든 캐시까지 날리면 다음 빌드가 통째로 느려진다. - 도커에 못 닿으면 경고만 남기고 넘어간다(이 앱은 도커 없이도 기동하는 것이 전제다). - 0 바이트 회수는 로그를 남기지 않는다 — 정상 상태가 대부분이라 그때마다 찍으면 정작 "얼마나 쌓였다가 지워졌나" 가 묻힌다. - 도커를 공유하는 환경을 위해 enabled 로 끌 수 있게 했다. 검증: DockerGarbageSweeperTest 3개 신규(보존 시간 전달 / 끔 / 도커 미도달), 전체 1329개 통과. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
실측 (dev, 2026-09-08)
컨테이너가 0 개인데:
디스크 29G 중 19G 사용(67%) 이었고, 손으로 지우니 11G(38%) 가 됐다 — 절반 이상이 찌꺼기였다.
디스크가 차면 앱·MySQL·프리뷰 컨테이너가 한꺼번에 죽는다. 그때는 원인이 "디스크" 라는 것조차 로그를 남길 자리가 없다. 같은 서버에서 pm2 로그가 6.6GB 까지 자라 89% 에 닿은 적도 있다(#302).
원천: 익명 볼륨이 고아로 남았다
removeContainerCmd세 곳이 전부withForce(true)만 쓰고withRemoveVolumes를 안 붙였다. 컨테이너는 사라지는데 그것이 만든 익명 볼륨은 남는다 —mysql:8.4프리뷰 DB 가/var/lib/mysql용으로 만드는 볼륨이 그것이라 한 건당 200MB 넘게 쌓인다.DockerContainerServiceCodingAgentContainerRunner명명 볼륨은 쓰지 않고(코드 전체에 없음) bind mount 는 이 옵션의 영향을 받지 않으므로 부작용이 없다.
안전망:
DockerGarbageSweeper원천을 막아도 이전에 쌓인 것과 비정상 종료로 새는 것이 남는다. 6시간마다 고아 볼륨 · dangling 이미지 · 오래된 빌드 캐시를 회수한다.
until이전 것만(기본 48시간). 방금 만든 캐시까지 날리면 다음 빌드가 통째로 느려진다enabled로 끌 수 있다검증
DockerGarbageSweeperTest3개 신규 — 보존 시간 전달 / 끔 / 도커 미도달dev 는 이미 손으로 정리해 38% 다. 배포 후 스위퍼가 도는지(회수할 게 없으면 조용한 것이 정상) 확인 필요.
🤖 Generated with Claude Code
https://claude.ai/code/session_013y8USoCXTsRTATAhy88M93