Guide Center — Coolify 배포 가이드
GitHub 자동 배포(Coolify)로 운영한다. 이전 배포 플랫폼의 설정 파일은 제거했다.
배포 트리거
main브랜치에 push 하면 Coolify 가 자동 배포한다.
빌드 / 시작 / 헬스체크
| 항목 | 값 |
|---|---|
| Build Command | pnpm install --no-frozen-lockfile && pnpm db:ensure-i18n && pnpm build |
| Start Command | pnpm start |
| Health Check | /healthz |
| Node | >=22 <25 (package.json engines) |
pnpm db:ensure-i18n(=scripts/ensure-i18n-schema.mjs)이 다국어·공통 UI·용어 outbox(term_extraction_jobs) 테이블을 멱등으로 만든다.- Coolify 빌드 컨테이너가 DB에 닿지 못해 이 단계가 실패해도 앱은 뜬다 — 서버 시작 시
server/ensureSchema.ts가 outbox 를 다시 보강한다. @hohyun94의존성은 모두file:vendor/*.tgz라 GitHub Packages 토큰(NPM_TOKEN) 없이 설치된다. 기존.npmrc설정은 무해하니 그대로 두어도 된다.
환경변수
| 키 | 필수 | 설명 |
|---|---|---|
NODE_ENV | ✔ | production |
AIVEN_DATABASE_URL (또는 DATABASE_URL) | ✔ | MySQL 연결 문자열 |
R2_ENDPOINT / R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY / R2_BUCKET_NAME | ✔ | 첨부 파일 스토리지 |
DIRECTORY_PORTAL_API_KEY | ✔(권장) | 원장(PortalConsole) 호출 키 — glossary:read/glossary:write/translation:invoke(번역은 중앙 서비스가 기본) |
PORTAL_JWT_SECRET / PORTAL_JWT_ISSUER / PORTAL_JWT_AUDIENCE | ✔ | DirectoryService 인증 |
TERM_LINK_SYNC_INTERVAL_MS | 용어 추출 주기(기본 5분, 최소 30초) | |
DISABLE_TERM_LINK_SYNC | true 면 용어 추출 스케줄러 비활성 | |
EXPLORE_GATEWAY_URL | ExploreGateway 오리진. 설정하면 셸 상단 검색의 질문이 게이트웨이 → 중앙 RAG 로 간다(정본). 미설정이면 질문 버튼을 켜지 않는다 | |
EXPLORE_GATEWAY_AUDIENCE | 위임 토큰 audience(기본 explore-gateway). 원장 소비자 등록의 delegationAudiences 와 일치해야 한다 | |
GUIDE_CENTER_SERVICE_CLIENT_SECRET | 원장이 발급한 이 포털의 소비자 시크릿(위임 토큰 경로 B). 브라우저에 내려가지 않는다 | |
EXPLORE_SERVICE_TOKEN | (어댑터 노출 시) 게이트웨이가 이 포털 매뉴얼을 검색할 때 쓰는 서비스 토큰 — ExploreGateway PORTAL_SERVICE_TOKENS_JSON["guide-center"] 와 같은 값 |
공통 용어 연결 파이프라인(핸드오버 §16)
- 스키마: 시작 시
server/ensureSchema.ts가 outbox(term_extraction_jobs)를 멱등 보강한다(배포 설정과 무관). - 적재: 매뉴얼 저장/삭제·에디터 저장·번역 저장·패키지 퍼블리시·버전 원복 뒤
/api/manuals·/api/editor/*훅이 큐에 적재한다. - 반영: 스케줄러(
startTermExtractionScheduler) 또는POST /api/scheduled/term-links(포털 키 필요)가 원장에 연결/해제를 push 한다. - 표시/검색:
manuals.terms(상세 용어)와manuals.searchTerms(용어 검색) — 클라이언트는client/src/components/PortalTermList.tsx. DIRECTORY_PORTAL_API_KEY가 없으면 스케줄러·연결은 조용히 비활성이다(저장·표시는 정상).- 번역은 중앙 서비스가 기본이다 — 콘솔이 원장 용어(번역 팩)를 붙여 실행하므로
DIRECTORY_...키에translation:invoke가 있어야 한다. 중앙이 미설정이거나 답하지 않으면 로컬 모델로 자동 폴백하고(경고 로그), 로컬을 강제하려면GUIDE_TRANSLATION_PROVIDER=local을 둔다. 계약은PortalConsole/docs/TRANSLATION_PACK.md.
통합 탐색·답변(§14) 연계
- 검색은 이 포털이 소유한다: 셸 결과는 매뉴얼 카탈로그에서 만든다(
client/src/features/explore/useShellExplore.ts) — 화면 목록과 같은 규칙을 쓴다. - 답변은 중앙이 정본이다:
trpc.explore.ask→ 서버(server/exploreGateway.ts) → ExploreGateway → RagService. 이 포털은 답을 만들지 않는다. - 구성 여부는
trpc.explore.capabilities가 알려준다 — 미구성이거나 Directory 사용자 주체가 없는 세션(directoryUserId없음)이면 질문 버튼을 켜지 않는다. - 위임 토큰은 세션의
directoryUserId로만 발급하므로 중앙 인증 로그인 사용자에게만 동작한다. - 원장 등록:
PORTAL_CONSOLE_TOKEN_CONSUMERS_JSON에clientId: "guide-center",delegationAudiences: ["explore-gateway"],delegationScopes: ["search:read"]. - 남은 항목: 원장 소비자 등록과 ExploreGateway
PORTAL_SERVICE_TOKENS_JSON["guide-center"](어댑터용 서비스 토큰) 등록(docs/EXPLORE_ANSWER_INTEGRATION.md). - 매뉴얼은 게이트웨이 색인에도 합류한다:
POST /api/explore/v1/search(서비스 토큰)로 노출 판정을 통과한 노드를kind=document로 제공하고, 결과 링크는/?page=<pageId>다.
배포 후 확인
GET /healthz가{"status":"ok"}.- 매뉴얼을 저장하고 잠시 뒤
term_extraction_jobs에 작업이 쌓였다가done으로 바뀌는지 확인. - 매뉴얼 상세 화면에서
공통 용어섹션이 뜨는지 확인(원장에 연결이 있을 때만).