2026-04-28 OpenClaw, launchd KeepAlive, 종료 코드, ThrottleInterval, 임대 헤드리스 클라우드 Mac에서 재시작·크래시 루프 트리아지(HK / JP / KR / SG / US)
대부분의 OpenClaw 프로덕션은 Mac mini M4에 SSH만 두고 127.0.0.1 리버스 프록시와 구조화 로그 JSON 테일을 함께 둡니다. 게이트웨이가 launchd로 관리될 때 결국 맞닥뜨리는 실패는 정체불명 LLM 버그가 아니라 종료 직후의 빠른 재시작입니다—때로는 launchd에 항상 돌리라고 했기에 양호하고, 때로는 잘못된 설정·없는 PATH·첫 바인드 전 크래시로 치명적입니다. 이 2026-04-28 글은 업스트림 HTTP 압력과 웹훅 백프레셔를 로컬 프로세스 감독자와 잇습니다—KeepAlive와 ThrottleInterval의 상호작용, 재시작이 시끄러울 때 StandardError에서 첫 실패 줄을 읽는 법, 대화형 셸에서 재현하려고 LaunchAgent를 unload할 타이밍. 환경 + launchd 비밀 이야기와 openclaw doctor·허용 목록 업그레이드 흐름을 보완합니다.
헤드리스 클라우드 Mac에서는 launchd가 init
랩톱과 달리 npm이나 openclaw gateway가 나갈 때 터미널 앞에 사람이 없습니다. 오래 버티는 패턴: 전용 서비스 계정, 로테이션 파일 로그, launchd가 생애주기를 소유. 2026에 흔한 실수는 macOS와 Linux systemd를 1:1로 대입하는 일—KeepAlive와 RunAtLoad 같은 키는 강하지만 명시 스로틀이 필요하고, 2초짜리 오타를 시간당 execve 수천 건으로 키울 수 있어 ~/Library/Logs와 원격 로그 전달기를 채웁니다. 프로세스 종료를 1급 신호로 다루세요.
- User LaunchAgents — 사용자별 장수 서비스는
~/Library/LaunchAgents; 대부분 OpenClaw는 최소 권한으로 여기에 둡니다. - System LaunchDaemons — 관리자 쓰기·파급이 큼; 루트 문맥이 진짜 필요할 때만.
KeepAlive: 어떤 맛을 켰나?
Apple의 KeepAlive plist는 불리언이거나 네트워크·경로 등 조건부 사전을 담은 딕셔너리일 수 있습니다. 불리언 true는 망치: 이유 불문 종료 시마다 재시작—24/7 네트워크 데몬엔 맞고 일회성 마이그레이션엔 틀립니다. 더 섬세한 것은 NetworkState나 존재해야 할 경로입니다. “왜 재시작하지?”를 볼 때 첫 질문: launchd에 살려 달라고 했는가, 앱이 스스로 나가는가(종료 ≠ 크래시)? KeepAlive true 세계에서 깨끗한 0도 재시작을 유발합니다—래퍼가 자식을 잘못 분리한 뒤 스스로 종료할 때 보는 바로 그 현상입니다.
ThrottleInterval과 초 단위로 맞거나 그 이상이면 감독자가 망치입니다. 고정 박자 없이 흔들리면 처리 안 된 Promise 거절이나 포트 바인드 경합을 의심하세요—LLM이 아닙니다.
StandardOut / StandardError 경로: 실제 파일로
헤드리스 SSH는 TTY가 아닙니다. stdio를 “어디로도” 보내면 크래시 첫 200ms를 잃습니다. StandardOutPath와 StandardErrorPath를 서비스 사용자가 쓸 수 있는 디렉터리로, macOS newsyslog나 일일 cron으로 돌리고 대화형 셸 스크롤백에 절대 의지하지 마세요. 이그레스·TLS 사고와 맞춰 볼 때 stdout, nginx 액세스, 게이트웨이 JSON이 같은 타임스탬프 슬라이스를 갖는 것이 예쁜 Grafana보다 낫습니다.
ThrottleInterval: 재시작의 브레이크
ThrottleInterval은 launchd가 재시작을 몰 때 종료 후 잡이 다시 뜨기 전 최소 대기 초입니다. 초기 기동에 조용한 로그가 필요하면 10, 일정 상태에 일시적 파일 잠금에서 빠르게 회복하려면 1–2. launchctl print gui/$(id -u)/com.example.openclaw(사용자 도메인, 레이블 조정)로 상태와 마지막 종료를 읽으세요. 온콜 문서에 그 숫자를: “Throttle=10이면 최악에도 10초에 최대 한 번 재시작.” 소프트웨어에 MTTR < 1분을 묻는 기대를 잡을 때 인프라와 구분하는 방식입니다.
openclaw doctor는 launchd가 크래시 루프여도 통과할 수 있습니다—doctor는 전체 로그인 환경의 대화형 단발 바이너리이기 때문이고 plist는 node용 PATH나 전역 npm 접두어를 빠뜨릴 수 있습니다. 항상 env | sort와 doctor 출력을 diff하세요.
티켓에서 실제로 보는 종료 코드
| 종료 / 증상 | OpenClaw 쪽 가능성 | 먼저 할 일 |
|---|---|---|
1 (일반) + stderr에 스택 한 번 |
설정 파싱, 빠진 OPENCLAW_ 변수, 잘못된 cwd |
시크릿 패턴대로 SSH에서 같은 ProgramArguments를 set -a; source your.env; set +a로 실행. |
셸 래퍼의 2 (misuse) |
옵션 파싱 또는 Mac 경로 인용 | 래퍼에 원시 argv 로그, 글로브 주의, arm64를 원하면 Node가 Rosetta 아닌지 확인(SSH 셸 프로파일). |
126 / 127 |
실행 불가 또는 plist PATH에 node 없음 |
바이너리 절대 경로, 서비스 맥락에서 which -a node. |
| 시그널 9 / exit 137(리눅스 말법)—macOS에선 흔히 단순 kill | OOM, 수동 kill, 워치독(드묾)—M4에선 LLM+게이트웨이 메모리 함께 확인 | Console의 memory pressure 또는 제공자 셰이핑으로 동시성 축소. |
크래시 루프 트리아지: 모델을 바꾸기 전 여섯 질문
- 포트 사용 중? 길 잃은 게이트웨이나 좀비 리스너가 바인드를 막을 수 있음—nginx 리버스 프록시와 포트 정렬을 보세요.
- 루프인데 종료 0? 자식에
exec하지 않은 래퍼가 0으로 나가도KeepAlive를 건드릴 수 있습니다. - stderr가 매번 같나? 한 줄 오류가 같으면 결정적 설정. 스택이 바뀌면 경쟁·네트워크 플레이크.
- 마지막에 뭐가 바뀌었나? git 태그나
npmshrinkwrap에 묶으세요—비 App Store 서비스에도 릴리스 규율 문화가 도움이 됩니다. - 업스트림이 401인데 재시도 루프가 안 멈추나? 회로 차단기가 필요할 수 있고 더 강한
KeepAlive가 아닙니다—429/503은 LLM 속도 제한을 보세요. - 망치를 스로틀했나? 아니면 첫 “수정”은 로그를 읽기 위한
ThrottleInterval일 때가 많고 그다음 진짜 코드/설정 수정입니다.
log stream --style compact --predicate 'process == "openclaw"'를 권합니다. 안 그러면 잡음이 필요한 첫 신호 줄을 가립니다.
Plist 운영 체크리스트(Confluence/Notion에 복사)
- Label — 고유 reverse-DNS, 같은
UID에서 다른 팀com.접두어 재사용 금지. - ProgramArguments[0] — 전체 경로, 로그인 셸의 “착한” 깜짝 없음.
- WorkingDirectory — 설정 상대 경로용 리포 루트;
openclaw doctor가정과 일치. - EnvironmentVariables —
HOME,PATH, 꼭 필요하면NODE_OPTIONS—시크릿 문서와 맞출 것. - KeepAlive + ThrottleInterval — 공격적 재시작과 로테이션 없는 작은 stderr 한도를 동시에 두지 말 것.
plutil -lint ~/Library/LaunchAgents/com.yourorg.openclaw.plist
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.yourorg.openclaw.plist
페이지가 「SG에서 OpenClaw 다운」일 때 운영 7단계
- 엣지 건강(nginx)—502 vs 504는 업스트림 vs 게이트웨이; 아웃바운드 실패면 DNS/TLS 교차 확인.
- launchd 상태—해당 레이블에
launchctl print; 마지막 종료·스로틀 창 읽기. - 로그 안정화—아직 플래핑이면
ThrottleInterval. - 같은
UID로launchd없이 대화형 재현. - 설정 diff와 2인 리뷰 시크릿 로테이션.
- 롤 포워드를 알려진 좋은
npm버전으로—프로드의 미스터리 패치가 아니라. - 사후—티켓에 한 단락: 근본 원인, 탐지 공백, 가드(예: 1분 창 비영 종료 알림).
FAQ: launchd vs OpenClaw 게이트웨이 자체
| 질문 | 2026-04-28 답 |
|---|---|
ProcessType을 Interactive로? |
서버 데몬에선 보통 아니요; Interactive는 스케줄링 우선순위를 바꿉니다. 워크로드 클래스에 맞게 Apple 문서를 보지 않는 한 표준 배경 동작을 선호하세요. |
caffeinate가 필요한가요? |
데이터홀 24/7 임대 Mac mini M4는 전원 정책에서 슬립이 보통 꺼짐; 랩톱형 호스트(MacXCode는 아님)여도 재개 시 크래시가 진짜 버그면 caffeinate로 플래핑을 “고치지” 마세요. |
이 런북에 Apple Silicon Mac mini M4가 나오는 이유
launchd는 아래 하드웨어만큼 정직합니다. 홍콩·도쿄·서울·싱가포르·미국의 베어메탈 Mac mini M4, 1–2 TB, 예측 가능한 CPU 스케줄링이 있으면 “툴 호출을 너무 많이 해 게이트웨이 OOM인가?”가 측정 가능한 질문이 됩니다. 로컬 ML 실험에 좋은 MPS 친화 코어는 구조화 로그 전달기·리버스 프록시·OpenClaw 스택을 한 과금 단위에 얹을 여유를 주고, 팀은 노트북 한 대 주인에게 묶이기 전에 리전 노드 요금과 접근 가이드로 이 글들을 짝짓습니다.