결과: 병합 (2026-10-16, seaweedfs/seaweedfs#11755). 사실은 GitHub 의 PR·리뷰 원문, SeaweedFS 소스(PR 의 바탕 커밋
590a75b9), TT Lab 저장소의 커밋·문서 기록에서 가져왔습니다. 시각은 한국 시간입니다. 2026-10-17 기준 이 변경이 들어간 릴리스는 아직 없습니다(최신 릴리스 4.48, 2026-09-28).
목차
- 한 줄 요약
- 1. 무엇이 문제였나: 우리가 겪은 증상
- 2. 원인: 소스의 어느 줄인가
- 3. 무엇을 바꿨나: diff 요지
- 4. 봇과 메인테이너는 어떻게 반응했나
- 5. 배운 것: 오픈소스 기여 요령
- 링크
한 줄 요약
| PR | seaweedfs/seaweedfs#11755 mini: note mini.options and Docker filer.toml pitfalls in help |
| 바꾼 것 | weed mini -h 도움말 끝에 Notes 11줄. 코드 동작은 그대로 |
| 반응 | 리뷰 봇 셋이 9분 안에 리뷰, 지적 셋. 메인테이너가 동작을 고치는 #11758 을 열어 먼저 병합 |
| 결과 | 메인테이너가 우리 브랜치에 Notes 수정 커밋을 얹어 한 커밋으로 병합(우리 계정이 저자, 메인테이너가 공동 저자) |
| 걸린 시간 | PR 공개 10-15 08:15 → 병합 10-16 10:44, 약 26시간 반 |
1. 무엇이 문제였나: 우리가 겪은 증상
weed mini 는 SeaweedFS 의 마스터·볼륨 서버·파일러·S3 게이트웨이를 한 프로세스로 띄우는 모드입니다. TT Lab 클러스터는 이것을
두 곳에 씁니다. 커뮤니티·블로그의 미디어 저장소, 그리고 운영 DB 의 백업 저장소입니다. 백업 저장소는 원래 MinIO 였는데, MinIO 가
바이너리·이미지 배포를 끝내면서 2026-09 에 SeaweedFS 로 옮겼습니다.
함정 하나: 지운 플래그가 되살아난다 (2026-09-19)
미디어 저장소에서 볼륨 증설이 멈췄고, 원인은 재시작을 거듭하며 이어 붙은 마스터의 raft 상태였습니다. 단일 마스터라 지킬 상태가
없으므로 -master.resumeState=false 를 붙여 매번 새로 시작하게 했습니다.
그런데 로컬에서 시험해 보니, 이 줄을 명령줄에서 지우고 다시 띄워도 한 번 더 false 로 떴습니다. mini 가 명령줄 플래그를
데이터 디렉터리의 mini.options 파일에 적어 두고 다음 기동에 다시 읽기 때문이었습니다. 매니페스트에는 「되돌릴 때 줄을 지우지
말라」는 주석을 남겼습니다. weed mini -h 어디에도 이 파일 이야기는 없었습니다.
함정 둘: 복원한 사본의 버킷이 비어 보인다 (2026-09-24)
백업은 되살려 봐야 백업입니다. 백업 저장소의 데이터 디렉터리를 NAS 로 복사한 사본에 같은 이미지로 mini 를 띄워 복원 시험을
했습니다. 사본을 컨테이너의 다른 경로에 붙이고 -dir 를 그 경로로 주었더니, 버킷 둘만 보이고 객체는 0개였습니다. 오류는
없었습니다. 사본을 /data 에 붙이자 MinIO 에서 옮겨 온 객체 10,004개가 키·크기·SHA-256 까지 복사 때와 같게 읽혔습니다.
두 번 다 「설정을 잘못 넣었다」가 아니라 「도구가 말해 주지 않는 규칙이 있었다」였습니다. 이런 것은 다음 사람도 똑같이 밟습니다.
2. 원인: 소스의 어느 줄인가
아래 줄 번호는 모두 PR 의 바탕 커밋 590a75b9 기준입니다.
TT Lab 이 쓰던 4.29 판도 같은 함수의 내용이 같았습니다(태그 4.29 의 mini.go 를 열어 대조).
mini.options: 「명령줄에 줬나」가 아니라 「기본값과 같은가」
- 저장:
saveMiniConfiguration은cmdMini.Flag.Visit으로 명령줄에서 준 플래그 전부(dir만 빼고)를<dir>/mini.options에 씁니다(1166–1179행). - 적용:
applyConfigFileOptions는 파일의 값마다, 그 플래그의 지금 값이 기본값과 같으면(flag.Value.String() == flag.DefValue, 1138행) 저장된 값으로 덮어씁니다. - 예외: 기동 직후 포트 플래그 여덟 개만 「명령줄에 줬는지」를 따로 기록해 두고, 준 것은 건너뜁니다(1130행).
그래서 -master.resumeState=false 를 한 번 주면 파일에 남고, 줄을 지운 다음 기동에는 값이 기본값 true 이므로 파일의 false 가
다시 적용됩니다. 명령줄에 =true 를 명시해도 기본값과 같으니 결과는 같습니다 — 포트 플래그만 예외입니다. 우리가 매니페스트에
남긴 「줄을 지우지 말고 =true 로 바꿀 것」이라는 주석도, 소스대로라면 통하지 않는 조언입니다(소스를 읽은 결과이고 실측하지는
않았습니다). 게다가 mini 는 기본 로그를 조용하게 줄이므로, 「저장된 옵션을 적용했다」는 메시지(V(2))는 기본 설정에서 보이지 않습니다.
filer.toml: 이미지가 메타데이터 자리를 못박아 둔다
- 공식 이미지는 저장소의
docker/filer.toml을/etc/seaweedfs/filer.toml로 복사합니다(Dockerfile.go_build82행). 내용은 세 줄,[leveldb2]저장소를 켜고dir = "/data/filerldb2"입니다. - 파일러는
filer_server.go254–264행 에서filer.toml을 찾으면 기본 저장소 자리를 쓰지 않고 경고 한 줄(skipping default store dir)만 남깁니다. mini 가-dir에서 끌어낸 기본 자리(1348행)는 이때 버려집니다.
결과적으로 볼륨 파일은 -dir 에, 파일러 메타데이터는 /data/filerldb2 에 갑니다. -dir 를 다른 곳으로 옮기고 그곳만 남겨 두면
메타데이터는 컨테이너와 함께 사라집니다. 우리 복원 시험에서 버킷 둘이 보였던 것은, 기동 플래그 -bucket 이 빈 메타데이터 위에
버킷을 새로 만들었기 때문으로 보입니다(소스의 버킷 생성 코드와 우리 매니페스트의 플래그로 본 해석).
3. 무엇을 바꿨나: diff 요지
코드는 건드리지 않고, cmdMini 의 Long 도움말 끝에 Notes 를 붙였습니다. 처음 보낸 판의 요지입니다.
+Notes:
+- Flags are saved to <dir>/mini.options and applied again on the next
+ start to every flag that is not given on the command line. Removing a
+ flag, or passing it with its default value, does not restore the
+ default on the next start. Edit or delete mini.options instead.
+- The official Docker image ships /etc/seaweedfs/filer.toml, which keeps
+ the filer metadata in /data/filerldb2 regardless of -dir. If you set
+ -dir to another path, keep /data on a persistent volume as well.
+ ...
도움말만 고친 이유는 둘입니다. 동작을 바꾸는 것은 메인테이너가 판단할 설계 문제이고, 외부 기여자의 첫 PR 은 작고 확인하기 쉬워야
받아들여지기 쉽습니다. SeaweedFS 의 PR 템플릿에는 「AI 로 만든 PR 은 모든 줄을 검토했고 최소한으로 유지했다」는 체크 항목이 있어
둘 다 채웠고, 본문 끝에 AI 도움을 받아 쓰고 직접 검토했다는 문장을 넣었습니다. 커밋에는 DCO 서명(Signed-off-by)과 SSH 서명을
붙였습니다. 시험은 gofmt 와 위 함수들을 소스로 대조한 것이 전부라고 본문에 그대로 적었습니다.
4. 봇과 메인테이너는 어떻게 반응했나
9분 안에 온 봇 셋
PR 을 연 직후(10-15 08:16–08:24) Devin, CodeRabbit, Greptile 세 리뷰 봇이 붙었습니다. 공개된 지적은 셋이었고 모두 첫 번째 Note 였습니다.
- CodeRabbit: 우리 문장은 「명령줄에 주지 않은 플래그」에 적용된다고 했지만, 실제 기준은 「지금 값이 기본값과 같은가」다. 그리고 포트 플래그는 기본값을 명시하면 저장값을 건너뛴다 — 예외를 적어라.
- Greptile: 같은 포트 예외. 포트 플래그는 기본값을 명시하는 것만으로 되돌릴 수 있으니 「파일을 지우라」는 안내가 너무 넓다.
2절의 소스를 다시 보면 봇이 맞았습니다. 우리 문장은 일반 플래그에는 맞지만 포트 여덟 개에는 틀렸습니다. 예외 목록(portFlagNames)을
읽고도 문장에 넣지 않은 것입니다.
우리가 답하기 전에 메인테이너가 움직였다
솔직히 적으면, 이 지적들에 우리는 하루 동안 답하지도 고치지도 않았습니다. 그사이(10-15 23:15) 메인테이너가 우리 PR 을 언급하며 #11758 을 열었습니다. 문제 정의는 우리 PR 이 적은 두 함정 그대로였고, 해법은 도움말이 아니라 동작이었습니다.
mini.options에 명령줄 플래그를 아예 저장하지 않는다. mini 가 스스로 계산한 값(현재는 볼륨 크기 상한)만 고정해 재시작해도 같게 한다. 예전 파일은 한 번 적용된 뒤 계산값만 남게 다시 쓰인다.- 파일의 값은 명령줄이나
WEED_*환경 변수로 준 플래그를 건너뛴다. 「기본값과 같은가」 비교를 버리고 「줬는가」로 본다. - 저장된 옵션을 적용하면 기동 때 한 줄로 알린다(비밀번호·토큰 값은 가린다).
filer.toml이 켠 로컬 저장소 자리가-dir밖이면 기동 때 경고한다(warnIfFilerStoreOutsideDir).
#11758 이 10-16 10:36 에 병합되고, 3분 뒤 메인테이너는 우리 브랜치에 Notes 를 새 동작에 맞게 고친 커밋을 얹었습니다. 첫 Note 는
「명령줄 플래그는 저장되지 않고 늘 저장값을 이긴다, 저장되는 것은 계산값뿐」으로, 둘째 Note 에는 「-dir 밖이면 기동 때 경고한다」가
더해졌습니다. 댓글로는 이 변경 덕분에 기본값 비교와 포트 예외를 짚은 봇 지적이 더는 해당하지 않는다고 정리했습니다.
봇의 두 번째 지적과 순서 설명
새 커밋에 Greptile 이 다시 지적 둘을 달았습니다. 「소스에는 명령줄 플래그를 저장하는 코드가 있다」, 「-dir 밖을 검사하는 코드는 없다」.
봇은 #11758 이전의 코드를 보고 있었습니다. 메인테이너는 두 줄 댓글마다 「이 PR 은 #11758 다음 순서이고, 그 PR 이 저장을 없애고 검사를
더한다」고 답했고, 봇은 1분이 안 돼 두 지적을 거둬들였습니다. 그리고 10:44 병합.
병합은 두 커밋을 하나로 합친 squash 였고, 커밋 저자는 우리 계정, 메인테이너는 Co-authored-by 로 들어갔습니다. 최종 도움말
13줄 중 우리가 쓴 문장이 그대로 남은 것은 두 번째 Note 의 대부분이고, 첫 Note 는 메인테이너가 새 동작에 맞춰 다시 썼습니다.
5. 배운 것: 오픈소스 기여 요령
- 문서 PR 은 가장 정중한 버그 보고가 될 수 있습니다. 「이 동작이 놀랍다」는 이슈는 논쟁이 되기 쉽지만, 「이 동작을 도움말에 적자」는 PR 은 메인테이너가 그 동작을 정면으로 보게 합니다. 이번에는 메인테이너가 적는 대신 고치는 쪽을 골랐고, 그 결과가 더 좋았습니다.
- 동작을 설명할 때는 예외 목록까지 읽습니다. 봇이 짚은 것은 정확히 우리가 읽고도 문장에 넣지 않은
portFlagNames였습니다. 「대체로 맞는」 도움말은 예외에 걸린 사람에게 틀린 도움말입니다. - 봇 지적에는 바로 답합니다. 맞으면 고쳐 다시 올리고, 틀리면 소스 줄로 답합니다. 이번에는 메인테이너가 먼저 풀어 주었지만, 하루 동안 지적이 열린 채로 있었던 것은 우리 쪽의 빈틈이었습니다. 지금은 올린 PR 의 봇 댓글을 날마다 훑어 대응하는 것을 규칙으로 둡니다.
- 봇은 PR 사이의 순서를 모릅니다. 의존하는 PR 이 있으면 본문이나 댓글에 「무엇 다음에 들어가야 한다」고 적어 두면 사람도 봇도 같은 그림을 봅니다. 메인테이너가 한 일이 그것이었습니다.
- 증상과 실측을 숫자로 적습니다. 「버킷이 비어 보인다」가 아니라 「버킷 둘, 객체 0개, 오류 없음,
/data에 붙이면 10,004개가 SHA-256 까지 같다」. 이런 문장은 메인테이너가 재현 없이도 문제의 크기를 가늠하게 합니다. - 프로젝트의 AI 규칙을 먼저 읽습니다. SeaweedFS 는 AI 로 만든 PR 을 받되 체크 항목으로 검토와 최소 범위를 확인합니다. 프로젝트마다 규칙이 다르고, AI 가 쓴 PR 을 아예 받지 않는 곳도 있습니다. 고지 문장 한 줄과 서명은 어느 프로젝트에서나 기본으로 둡니다.
티티 한마디. 도움말에 「여기 구멍 있어요」라고 써 붙였더니, 관리인이 와서 구멍을 메워 버렸어요! 그래도 표지판은 남겨 두었대요. 봇이 「표지판 글자가 조금 틀렸어요」라고 하면, 다음 날이 아니라 그날 바로 고쳐 쓰기로 했어요.
링크
모든 자료는 2026-10-17 에 열람했습니다.
- PR: seaweedfs/seaweedfs#11755 (병합 커밋
ee2d98f6) - 메인테이너의 동작 변경: seaweedfs/seaweedfs#11758
- 메인테이너의 Notes 수정 커밋:
3c675a57 - 소스(바탕 커밋):
weed/command/mini.go,weed/server/filer_server.go,docker/filer.toml - SeaweedFS 릴리스 목록: https://github.com/seaweedfs/seaweedfs/releases