본문으로 바로가기

SSR·Fly CMS 계약과 정적 빌드 profile

콘텐츠 서비스는 같은 화면을 두 가지 데이터 공급 경계에서 제공할 수 있다. Docker SSR은 PostgreSQL을 읽고, 정적 호스트는 배포 시점의 /api/export snapshot을 읽어 페이지를 만든다. 둘을 억지로 하나의 runtime으로 합치면 static build가 DB 자격 증명을 요구하거나, SS…

6회 조회약 3분 읽기
X에 공유 새 창에서 열림
목차

콘텐츠 서비스는 같은 화면을 두 가지 데이터 공급 경계에서 제공할 수 있다. Docker SSR은 PostgreSQL을 읽고, 정적 호스트는 배포 시점의 /api/export snapshot을 읽어 페이지를 만든다. 둘을 억지로 하나의 runtime으로 합치면 static build가 DB 자격 증명을 요구하거나, SSR 변경이 정적 mirror에 늦게 반영되는 모순이 생긴다.

공개 함수 계약

apps/web/src/lib/cms-contract.ts는 두 adapter가 반드시 제공해야 하는 최소 공개 함수를 고정한다. cms.ts와 cms.static.ts 모두 cmsAdapterContract를 컴파일 때 만족하므로 함수가 한쪽에서 빠지면 TypeScript 검증에서 즉시 실패한다.

이 계약은 데이터 공급자를 통합하지 않는다.

  • SSR: SQL의 필터·정렬·페이지네이션·pool timeout을 적용한다.
  • Fly: export payload를 한 번 읽고 메모리에서 동일한 조회 의미를 재현한다.
  • 쓰기: SSR에서만 가능하며 Fly adapter의 createInquiry는 의도적으로 실패한다.

정적 build profile

Next.js의 dynamic·dynamicParams는 정적 분석 대상이라 환경변수 하나로 안전하게 바꾸기 어렵다. scripts/prepare-fly-build.mjs는 이미지 build layer 안에서만 다음을 수행한다.

  1. 정적 전환 대상 route manifest를 읽고 예상한 literal export만 바꾼다.
  2. @/lib/cms와 @/lib/db import를 각각 export·stub provider로 바꾼다.
  3. 동적 export나 DB provider import가 남으면 build를 실패시킨다.
  4. working tree에는 어떠한 변환도 남기지 않는다.

따라서 새 route를 추가할 때 manifest를 갱신하지 않으면 Fly build가 조용히 오래된 계약을 제공하지 않고 실패한다.

콘텐츠 반영 순서

  1. courses/와 notes/의 UTF-8 원본을 수정한다.
  2. 인증된 Admin에서 schema migration과 idempotent seed/upsert를 실행한다.
  3. Docker SSR의 한국어·영어 route와 /api/export 내용을 확인한다.
  4. 정적 배포 명령으로 snapshot을 새로 만든다.
  5. 정적 호스트 health, 양언어 series/lesson/note route, canonical host를 확인한다.

DB seed만 성공하고 Fly를 재배포하지 않으면 사용자는 이전 snapshot을 보게 된다. 반대로 Fly build만 성공해도 DB export에 없는 series·note URL은 404가 되는 것이 정상적인 일관성 신호다.

완료 기준

검증 축 SSR 정적 미러 일치 증거
데이터 원본 PostgreSQL live read versioned export snapshot content field drift 0
검색·정렬 SQL memory adapter 같은 fixture 결과
쓰기 인증된 서버 경로 불가 fail-closed 오류
비밀값 runtime secret build-time fetch 후 폐기 최종 image 검사
갱신 DB upsert·revalidate 새 static release 양언어 공개 smoke
files → authenticated upsert → SSR/export drift 0 → static build → public route smoke

중간 단계 하나가 실패하면 뒤 단계를 성공으로 표시하지 않습니다. 특히 export가 오래된 상태에서 정적 build만 다시 하면 낡은 snapshot을 더 확실하게 배포할 뿐입니다.

  • SSR·Fly adapter 공개 함수 목록이 동일하다.
  • build profile 잔여물 검사가 통과한다.
  • secret이 Docker ARG·ENV·최종 image에 남지 않는다.
  • seed 후 Docker와 Fly가 같은 양언어 콘텐츠를 반환한다.

quality 카테고리의 다른 글

카테고리 전체 보기 →

이 글이 도움이 되었나요?