2026년 OpenClaw 게이트웨이·대시보드·다채널 알림이 한 축으로 묶이는 흐름 위에서, Bundler 프리체크HTTP Webhook만 최소 명령으로 고정합니다.

트리거 → 게이트웨이(원격 Mac)WORK_ROOT에서 bundle check·bundle outdated·lock diffJSON Webhook. 참고: CircleCI·Jenkins·헬스·LaunchAgent·Bundler 매트릭스. 구매·도움말.

1단계: 설치·게이트웨이 daemon·토큰·헬스

Node LTS·openclaw CLI·openclaw doctor로 TLS·PATH를 확인합니다. 게이트웨이는 127.0.0.1, 토큰은 chmod 600. 외부 수신은 SSH 터널 또는 승인된 프록시 한 경로만.

# 예: 헬스 확인 (포트·경로는 환경에 맞게) curl -fsS "http://127.0.0.1:18789/health" # doctor (PATH·인증서) openclaw doctor

plist에 NODE_BINARY(·CA) 명시: LaunchAgent·헬스.

이 단계 점검
  • which node가 에이전트·수동 SSH 세션에서 동일
  • /health가 모니터링 간격마다 2xx
  • 토큰이 저장소·로그에 노출되지 않음

2단계: 작업 디렉터리 샌드박스(WORK_ROOT)

WORK_ROOT/<job_id>/repoumask 027·git clone --depth 1·동시 클론 상한으로 격리합니다.

export WORK_ROOT="/var/lib/openclaw/work" JOB_ID="${JOB_ID:-manual-$(date +%s)}" REPO_DIR="${WORK_ROOT}/${JOB_ID}/repo" mkdir -p "$REPO_DIR" git clone --depth 1 "https://github.com/org/app.git" "$REPO_DIR"

CI와 동일 BUNDLE_*·미러·Git 토큰: 매트릭스.

3단계: 스크립트 템플릿 — bundle check / outdated / lock diff

bundle check·bundle outdated --parseable·git diff origin/main -- Gemfile.lock로 요약 필드를 채우고 스킬에서 JSON으로 넘깁니다.

cd "$REPO_DIR" export BUNDLE_JOBS="${BUNDLE_JOBS:-4}" export BUNDLE_RETRY="${BUNDLE_RETRY:-3}" LOG="${WORK_ROOT}/${JOB_ID}/bundler-precheck.log" : > "$LOG" bundle check >>"$LOG" 2>&1 CHECK_RC=$? bundle outdated --parseable >"${WORK_ROOT}/${JOB_ID}/outdated.txt" 2>>"$LOG" || true OUTDATED_LINES=$(wc -l < "${WORK_ROOT}/${JOB_ID}/outdated.txt" | tr -d ' ') git fetch origin main --depth 1 2>>"$LOG" || true git diff origin/main -- Gemfile.lock >"${WORK_ROOT}/${JOB_ID}/lock.diff" 2>>"$LOG" || true

CHECK_RC·outdated_lines·lock 변경 여부를 status와 함께 실어 알림 규칙을 단순화합니다.

4단계: 실패 재시도·로그 아카이브

플레이크는 2·4·8초·최대 3회; 401·lock 문제는 실패 분류로 분리. 로그는 타임스탬프 파일·gzip 보관.

attempt=1 max=3 delay=2 while [ "$attempt" -le "$max" ]; do bundle check >>"$LOG" 2>&1 && break [ "$attempt" -eq "$max" ] && exit 1 sleep "$delay" delay=$((delay * 2)) attempt=$((attempt + 1)) done gzip -k "${WORK_ROOT}/${JOB_ID}/bundler-precheck.log" 2>/dev/null || true

5단계: 범용 HTTP Webhook으로 요약 회송

application/json으로 status·job_id·revision·check_rc·outdated_lines·log_tail 등 최소 필드만. HMAC·Retry-After·502 시 짧은 백오프 POST.

# python으로 JSON 이스케이프 안전하게 생성 후 POST export ALERT_WEBHOOK_URL="https://hooks.example.com/bundler-precheck" export JOB_ID REVISION CHECK_RC OUTDATED_LINES LOG_PATH # LOG_PATH=bundler-precheck.log 절대경로 python3 <<'PY' | curl -fsS -X POST "$ALERT_WEBHOOK_URL" \ -H "Content-Type: application/json" \ --data-binary @- import json, os, subprocess log_path = os.environ.get("LOG_PATH", "") tail = "" if log_path: try: tail = subprocess.check_output(["tail", "-c", "1600", log_path], text=True, stderr=subprocess.DEVNULL) except Exception: pass body = { "status": "ok" if os.environ.get("CHECK_RC") == "0" else "fail", "job_id": os.environ.get("JOB_ID", ""), "revision": os.environ.get("REVISION", ""), "check_rc": int(os.environ.get("CHECK_RC", "1")), "outdated_lines": int(os.environ.get("OUTDATED_LINES", "0")), "log_tail": tail, } print(json.dumps(body)) PY

핸들러는 즉시 2xx 후 워커에서 Bundler 실행(CircleCI 예시와 동일).

FAQ

bundle outdated가 느립니다.

BUNDLE_USER_HOME 고정·이벤트당 1회·동시 잡 상한.

lock diff는 있는데 CI --frozen만 실패.

Ruby·Bundler·미러·플랫폼 블록을 CI와 동일하게.

204인데 대시보드에 없음.

스키마·필수 키를 수신측과 맞추고 스테이징 curl로 검증.

정리: 헬스·샌드박스·프리체크·재시도·Webhook 순으로 고정하면 Ruby CI 사고를 앞당겨 잡을 수 있습니다. 구매·도움말·요금·고객 지원·블로그는 로그인 없이 이용 가능합니다.

OpenClaw·Bundler 게이트웨이

원격 Mac에서 프리체크·Webhook을 24시간 유지

MacPull 전용 Apple Silicon에 게이트웨이와 Bundler 스크립트를 두고 팀과 동일한 풀 경로를 재현하세요. 요금·구매·도움말(SSH)·고객 지원·기술 블로그는 로그인 없이 이용할 수 있습니다.

전용 노드
SSH
헬스
지원