2026 OpenClaw 프로덕션 리버스 프록시와 TLS:
Nginx/Caddy에서 WebSocket·서브패스·Gateway 502/핸드셰이크 분기

약 16분 읽기 · MACCOME

컨테이너 안에서는 정상인데 Nginx/Caddy 뒤에 두면 502, WebSocket 핸드셰이크 실패, 끝없는 리다이렉트가 난다면? 이 글은 엣지 리버스 프록시 + TLS 종료 + WebSocket 업그레이드 층에 초점을 맞춘다. Docker 네트워크 분기와 짝을 이룬다: 그 글은 패킷 도달성, 여기서는 브라우저에서 Gateway까지의 HTTP/1.1 업그레이드 경로와 경로 정합성을 다룬다. 여섯 가지 흔한 함정, 토폴로지·증상 대조표, 복사 가능한 스니펫, 6단계 프로덕션 Runbook, 온콜 지표 세 가지를 제공한다. 읽은 뒤에는 Upgrade 헤더를 고칠지 업스트림 127.0.0.1:18789로 돌아갈지 판단할 수 있다.

리버스 프록시에서 흔한 여섯 가지 오해(curl은 통하는데 502가 나는 이유)

  1. proxy_pass만 있고 HTTP/1.1과 Upgrade가 없음: WebSocket 사용 시 엣지에서 400/502가 나고 로그는 Gateway 장애처럼 보인다.
  2. 서브패스 접두사 이중 적용: 프록시가 /openclaw를 제거해도 앱이 루트 기준 절대 URL을 보내 정적 자산과 WS 경로가 갈라진다.
  3. HTTP/2 리스너와 WS를 섞고 ALPN을 확인하지 않음: 일부 조합에서는 WS 전용 서버나 명시적 HTTP/1.1 폴백이 필요해 핸드셰이크가 간헐적으로 실패한다.
  4. proxy_read_timeout이 너무 짧음: 긴 추론이나 채널 트래픽 버스트 시 엣지가 조용히 끊어 재연결 폭풍이 업스트림을 때린다.
  5. 불완전한 인증서 체인을 브라우저 경고만으로 넘김: 자동화 클라이언트는 더 엄격해 데스크톱 CLI는 되고 Web UI만 실패할 수 있다.
  6. CDN 기본 캐시나 짧은 유휴 타임아웃: 제어 평면 WebSocket이 일반 GET처럼 캐시되거나 일찍 끊겨 무작위 끊김처럼 보인다.

아래 토폴로지 표로 동일 호스트/별도 호스트/서브도메인/서브패스 트레이드오프를 정리한 뒤 헤더 체크리스트와 증상 매트릭스로 넘어간다.

토폴로지 선택: 동일 호스트, 분리 호스트, 서브패스, 서브도메인이 분기에 미치는 영향

동일 호스트 리버스 프록시(Nginx/Caddy와 Gateway 공존)는 가장 짧은 경로로, curl -v http://127.0.0.1:18789로 업스트림을 검증할 수 있다. 별도 프록시 호스트는 홉이 늘어 보안 그룹, 내부 DNS, TLS SNI를 다시 확인한다. 서브도메인은 경로 제거와 Cookie Path 충돌을 피하기 쉽다. 서브패스는 단일 브랜드 진입 도메인에 맞지만 OpenClaw 베이스 URL과 프록시 양쪽에서 접두사는 한 번만 제거하고, 개발자 도구로 WS URL이 기대하는 wss:// 경로를 가리키는지 확인한다.

변경 요청에는 스크린샷 두 장을 필수로 첨부한다: 최종 주소창 URL과 Network 탭의 WebSocket 핸드셰이크 Request URL. 없으면 리뷰가 모델 타임아웃이나 채널 OAuth로 잘못 분류되어 릴리스 시간을 낭비한다. 기업 HTTPS 프록시가 있다면 사무실 브라우저(PAC 주입)와 데이터센터 프록시(대개 직결) 경로를 분리해 생각한다. 증상 불일치는 흔한 일이다.

2026년에도 엣지 HTTP/2와 업스트림 HTTP/1.1 WebSocket 조합은 흔하다. 어떤 홉에서 업그레이드가 허용되는지 확인한다. 패킷 캡처 없이 강제 H2와 사용자 정의 WS 재작성을 동시에 켜지 않는다.

토폴로지적합운영 이점전형적 함정
동일 호스트 + 루프백 업스트림단일 VPS / 상시 원격 Mac로컬 curl 분기, TLS와 프로세스가 같은 로그0.0.0.0 바인딩으로 노출 확대, 방화벽 필요
전용 프록시 호스트다중 백엔드, 블루/그린, WAF 전방엣지와 컴퓨트 풀 분리, 인증서 갱신 집중내부 라우팅, SNI, 헬스 체크 대상 드리프트
서브도메인WS를 메인 사이트와 분리경로 의미가 분명, CDN 규칙 작성 용이다중 인증서, HSTS는 별도 검토
서브패스단일 브랜드 진입 도메인사용자 기억 부담 낮음접두사 제거, 리다이렉트 루프, 자산 루트 불일치

Nginx와 Caddy: WebSocket에 필요한 헤더와 타임아웃 대조

구현과 관계없이 엣지는 HTTP/1.1로 업그레이드하고, Connection: upgradeUpgrade: websocket을 통과 또는 재구성하며, 모델 최저 백분위보다 긴 읽기 타임아웃을 둔다. 표는 코드 리뷰 체크리스트다.

놓치기 쉬운 것은 프록시 버퍼링이다. 일반 API에서는 proxy_buffering이 처리량에 도움이 될 수 있지만 스트리밍이나 장수명 연결에서는 지연과 끊김 인상을 줄 수 있다. 스트림형 채널이나 SSE 유사 동작이 있으면 스테이징에서 실부하로 검증한 뒤 기본 버퍼를 켠다.

점검 항목Nginx 요점Caddy 요점
프로토콜 버전proxy_http_version 1.1;reverse_proxy 기본 HTTP/1.1, 명시 transport 주의
Upgrade 체인Upgrade $http_upgrade; Connection "upgrade";대부분 자동, 사용자 정의는 header_up
Host와 클라이언트 IPproxy_set_header Host $host;, X-Forwarded-*header_up Host {host}, 프록시 홉 신뢰
장수명 연결proxy_read_timeout / send_timeouttransport http { read_timeout ... }(버전별 문법은 문서 참고)
큰 본문client_max_body_size본문 제한 지시문(Caddy 문서 참고)
nginx
# 스니펫: 로컬 Gateway로 리버스 프록시(포트는 배포에 맞게, 예 18789)
location / {
  proxy_pass http://127.0.0.1:18789;
  proxy_http_version 1.1;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_read_timeout 3600s;
  proxy_send_timeout 3600s;
}
Caddyfile
# 스니펫: 자동 TLS + WebSocket 업스트림
openclaw.example.com {
    reverse_proxy 127.0.0.1:18789 {
        header_up Host {host}
        header_up X-Forwarded-For {remote_host}
        header_up X-Forwarded-Proto {scheme}
    }
}
info

팁: 변경 후에는 먼저 업스트림에서 curl -v -H "Connection: Upgrade" -H "Upgrade: websocket" http://127.0.0.1:18789/로 핸드셰이크 의미를 검증하고, 그다음 공개 wss://를 시험한다. 그렇지 않으면 TLS와 프록시 사이에서 책임이 오간다.

증상 매트릭스: 502, 413, 101이 아님, 리다이렉트, 인증서

증상을 엣지·업스트림·앱 설정에 매핑한 뒤 컨테이너를 재구성한다. 표가 컨테이너 네트워크를 가리키면 Docker 네트워크 분기로, 채널은 연결됐는데 Slack/Telegram이 침묵이면 채널 연결 문제 해결을 본다.

프로덕션에서만 재현되고 스테이징은 정상이면 인증서 체인 CA, CDN/WAF 규칙 버전, 프록시 map/if가 특정 User-Agent로 분기하는지 차이를 비교한다. 많은 502는 엣지 규칙 오탐이며 OpenClaw 버전과 무관하다.

현상우선 의심검증
502 Bad Gateway업스트림 미리슨, 방화벽, 잘못된 소켓 패밀리프록시에서 업스트림 curl, error.log의 upstream timed out / refused
413 Request Entity Too Large엣지 client_max_body_size 과소값 상향 후 reload, CDN/WAF 한도 동기화
WS가 101이 아님Upgrade 누락, 경로 재작성, http→https 리다이렉트가 핸드셰이크 파손브라우저 Network에서 핸드셰이크 상태, location 순서와 return 301
리다이렉트 루프X-Forwarded-Proto 없이 HTTPS 강제테스트 시 엣지 HSTS 완화, forwarded 헤더 보강
인증서 경고 / 일부 클라이언트만 실패체인 불완전, 잘못된 SNI, IP 인증서 혼용openssl s_client -servername로 체인 확인, NTP

6단계 Runbook: 파일럿 호스트명에서 온콜 가능한 프로덕션 입구까지

  1. URL 계획 고정: 공개 https:// 베이스, 서브패스 여부, WS가 HTTP와 동일 host인지 문서화.
  2. 로컬 프로브: 프록시 호스트에서 루프백 업스트림에 직접 연결해 OpenClaw 프로세스/포트가 문서와 일치하는지 확인(예 18789).
  3. 최소 Nginx/Caddy 조각: 먼저 헬스 경로만 프록시한 뒤 전체 사이트로 확장, 단계마다 롤백 가능하게.
  4. 완전한 WS 세션 하나 캡처: 브라우저와 CLI 모두 검증, request_id가 있으면 로그 정렬.
  5. 보안 레이어: IP 허용 목록, 속도 제한, 사용자 정의 WAF. 토큰 정책은 Docker 프로덕션 Runbook과 맞춘다.
  6. 관측 기준선: 업스트림 P95, 분당 WS 재연결, 인증서 잔여 일수를 기록해 알림 임계값에 반영.
  7. 배포 롤백 연습: 유지보수 창에서 이미지는 그대로 두고 프록시 설정만 되돌리는 연습으로 실행 가능한 명령 시퀀스를 문서에 남긴다.

Grafana와 온콜 가이드에 넣을 단단한 지표 세 가지

  1. 업스트림 RTT P95: 프록시 워커에서 127.0.0.1:18789 또는 내부 VIP까지. 공용 지연과 분리해 느림이 엣지인지 Gateway인지 판단하기 쉽다.
  2. WebSocket 비정상 종료율: 분 단위 집계. 급증은 타임아웃, 릴리스, 모델 측 429와 연관되기 쉬우며 프로바이더 라우팅 글과 대조한다.
  3. 인증서 잔여 유효기간: 14일 미만이면 티켓. Let's Encrypt와 상용 CA 갱신 실패는 스테이징에서 먼저 연습한다.

중앙 로그가 있다면 프록시 access 5xx 비율Gateway 애플리케이션 오류율을 이중 축으로 맞춘다. 한쪽만 치솟을 때 책임 경계가 분명하고 사후 분석이 감이 아니라 데이터로 말한다.

노트북에서만 Gateway를 돌리면 프로덕션 입구와 장기 자동화를 감당하기 어려운 이유

노트북 리버스 프록시 실험은 스니펫 검증에는 빠르지만, 절전, VPN 전환, 불안정한 가정용 업링크는 TLS와 갱신을 수작업으로 만든다. 502 SLO를 계약으로 내리기 어렵다. 리버스 프록시 + 상시 Gateway를 24/7 전용 호스트(예: 임대 Apple Silicon 클라우드 Mac 또는 관리형 VPS)에 두면 속도 제한, 인증서, 로그 보존이 표준 변경이 된다. 입구가 안정돼야 OpenClaw와 CI, 서명 파이프라인 연동이 감사와 인수인계에 견딘다.

자체 리버스 프록시 스택은 OpenSSL, Nginx, OS CVE 추적도 필요하다. OpenClaw를 CI, 서명, 다채널 봇에 장기적으로 묶는 팀에게 예측 가능한 전용 연산과 명확한 리전·임대 기간이 가정용 출구 실험보다 총비용에서 유리한 경우가 많다. MACCOME 클라우드 Mac은 다중 리전과 명확한 렌탈 구간을 제공해 TLS 종단 뒤의 깨끗한 상시 머신으로 적합하다. 먼저 3플랫폼 설치·선택 가이드로 디렉터리와 권한 경계를 고정하고, Mac mini 대여 가격과 지역 페이지——싱가포르, 도쿄, 서울, 홍콩, 버지니아, 실리콘밸리——로 실행층을 계약 가능한 환경에 두고, 엣지 프록시는 정책과 관측만 담당한다.

연결, 세션, 채널 이슈는 고객 센터에서 키워드로 검색하고, 시각적 분기에는 원격 데스크톱과 SSH/VNC 글을 함께 쓴다.

자주 묻는 질문

502일 때 프록시와 Docker 중 무엇을 먼저 보나요?

프록시 호스트에서 루프백 업스트림을 curl한다. 안 되면 Docker 네트워크 분기로. 플랜 비교는 Mac mini 대여 가격.

서브패스와 서브도메인은 어떻게 고르나요?

서브도메인이 제거 이슈를 덜 밟는다. 서브패스는 양쪽 베이스 URL을 맞춘다. 설치는 3플랫폼 설치 가이드로 버전을 맞춘다.

CDN 뒤에서 WS가 끊깁니다.

캐시 끄기, 유휴 타임아웃 연장, 제어용 서브도메인으로 CDN 우회. 채널 쪽은 Slack/Discord/Telegram 분기 글을 본다.

로그와 티켓은 어디로?

엔터프라이즈 변경은 고객 센터 티켓으로. 프로덕션 채팅에 Nginx 설정 절반만 흘리지 않는다.