Files
obsidian/history/2026-04-21-ironclad-production-cutover.md
kaffa 3dfceb81b7 ironclad production cutover (2026-04-21): apex → Worker 전환
products/ironclad-website.md: 배포 표에 라우팅 방식 컬럼 추가.
production만 zone route 방식(custom_domain 대신 zone_name + /*)을 써서
기존 APISIX A record를 건드리지 않고 Cloudflare 엣지에서 Worker가
매칭 요청을 가로채는 구조. 전제 조건(crowdsec bouncer wildcard가
apex를 가로채지 않도록 *.ironclad.it.com/* 수정) 명시.

history/2026-04-21: 3차에 걸친 cutover 경로(DNS 충돌 → route 전환 →
crowdsec wildcard dot 누락 수정) + 현재 prod 상태 + 후속 정리 항목.
2026-04-21 17:13:33 +09:00

5.0 KiB

title, updated, tags
title updated tags
2026-04-21 Ironclad production cutover — apex 도메인 Worker 전환 2026-04-21
history
ironclad
website
cloudflare
production
crowdsec

요약

ironclad.it.com (apex) production이 이전 경로(Cloudflare → APISIX → Caddy 컨테이너, Stamp/Flux volume_shared) 에서 Cloudflare Worker ironclad-site (Next.js 16 + opennextjs-cloudflare) 로 전환됨. 고객이 보는 화면이 6주 묵은 영문 "Ironclad Corp — Managed Security Hosting" 에서 최신 한국어 "Ironclad — 올어라운드 호스팅 & 보안서비스" 로 즉시 교체.

진행 경로

1차 시도 — v2026.04.21 태그 push (실패)

  • deploy-production.yml 트리거, wrangler 빌드·업로드 성공
  • DNS 등록 단계에서 Cloudflare API 실패:
    code: 100117
    Hostname 'ironclad.it.com' already has externally managed DNS records (A, CNAME).
    Either delete them, try a different hostname, or use the option
    'override_existing_dns_record' to override.
    
  • 원인: 기존 ironclad.it.com A 172.233.93.180 (Proxied) 레코드가 먼저 있어 custom_domain: true 등록 거부

2차 시도 — custom_domain 제거하고 zone route로 전환 (성공)

  • wrangler.jsonc production env routes 변경:
    • Before: { pattern: "ironclad.it.com", custom_domain: true }
    • After: { pattern: "ironclad.it.com/*", zone_name: "ironclad.it.com" }
  • 로컬에서 CLOUDFLARE_API_TOKEN=... pnpm deploy:production 실행 → Worker 업로드 + route 등록 성공
  • 결과: Cloudflare에 ironclad.it.com/* → ironclad-site route binding 생성됨

3차 보정 — crowdsec bouncer wildcard route 버그 수정 (결정타)

  • 배포 후에도 prod 응답이 여전히 구 HTML. 원인 조사 결과 Cloudflare Workers Routes 상태:
    www.ironclad.it.com/*        -> ironclad-site
    ironclad.it.com/*            -> ironclad-site
    *ironclad.it.com/*           -> crowdsec-cloudflare-worker-bouncer  ← 문제
    
  • *ironclad.it.com/* 패턴이 의도는 "subdomain wildcard" 였으나 dot 누락으로 apex까지 포괄(prefix wildcard로 해석되어 ironclad.it.com/* 도 매칭). crowdsec bouncer Worker가 먼저 잡아서 origin(APISIX → Caddy)로 pass-through.
  • Cloudflare API로 zone route c148ae77ebb74f20b61ecd71d0e86b77*.ironclad.it.com/*로 변경:
    curl -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE/workers/routes/$ROUTE_ID" \
      -d '{"pattern":"*.ironclad.it.com/*","script":"crowdsec-cloudflare-worker-bouncer"}'
    
  • 수정 직후 ironclad.it.com 응답에 x-opennext: 1 + x-powered-by: Next.js 확인 → Worker가 정상 서빙

현재 prod 상태 (2026-04-21 post-cutover)

  • https://ironclad.it.com/ → Cloudflare → ironclad-site Worker (Next.js 16)
    • title: Ironclad — 올어라운드 호스팅 & 보안서비스 | Ironclad
    • x-opennext: 1, x-powered-by: Next.js
  • DNS A record 172.233.93.180은 건드리지 않음 (롤백 준비)
  • apex 도메인의 bot 차단은 Next.js Worker 내부의 CrowdSec middleware (KV binding CROWDSECCFBOUNCERNS = 9af0d1c1c14a4bc1a3835c2a5b22fd7a)가 담당. Edge Worker bouncer는 서브도메인(*.ironclad.it.com)만 커버.

후속 정리 필요

항목 담당 우선순위
APISIX 라우트 ironclad.it.com 제거 (volume_shared 모드) 낮음 (트래픽 안 감, 남아있어도 무해)
Stamp-Flux 파이프라인에서 ironclad.it.com 배포 경로 deprecate 헤임달 중 (혼선 방지)
openclaw/openclaw-agents.md volume_shared 모드 ironclad 관련 기록 정리 헤임달
Cloudflare DNS A record 변경 (172.233.93.180 → Cloudflare 기본) kappa 낮음 (zone route 방식이라 origin 무관)
v2026.04.21 태그는 deploy-production.yml에서 실패로 남음 → 재태깅 불필요 (로컬에서 직접 배포 완료)

커밋

  • hosting/ironclad:
    • v2026.04.21 (태그, f736487) — Header dark nav 승격 시점
    • 6f2e2cc fix(deploy): custom_domain → zone route로 전환 (DNS 충돌 회피)
  • Cloudflare API 변경: zone route c148ae77ebb74f20b61ecd71d0e86b77 pattern 업데이트 (wrangler 소스 외)

학습 포인트

  • apex 도메인에 custom_domain: true를 쓰려면 기존 DNS 레코드가 없어야 한다. Stamp/Flux 같이 기존 정적 배포 경로가 있는 도메인은 zone_name 기반 route 방식이 자연스럽다.
  • Cloudflare Worker Routes wildcard의 dot 누락은 apex까지 포괄. *example.com/* vs *.example.com/*는 전혀 다른 패턴. *example.com/*은 prefix wildcard로 apex 포함.
  • 기존 wildcard route가 apex로 해석되면 "내가 새로 만든 route가 우선" 될 거라 기대하기 어렵다. Cloudflare는 specificity tie-breaker가 있지만 명확히 의도한 대로 동작하지 않음. 가장 안전한 건 wildcard pattern이 apex를 포함하지 않게 수정.
  • x-opennext: 1 헤더는 OpenNext가 서빙하고 있음을 확인하는 가장 빠른 시그널.