본문으로 건너뛰기

Azure Static Web Apps — 가이드 사이트 배포

docs-site/ 의 Docusaurus 빌드 결과물을 Azure Static Web Apps (ASWA) Free 티어에 배포합니다. 트레이딩 봇 인프라(VM + ACR)와는 별도의 리소스 그룹으로 운영해 비용·권한·라이프사이클을 분리합니다.

목표 토폴로지

┌──────────────────────────┐ ┌──────────────────────────┐
│ GitHub: genonai/quant-ai │ │ Azure: koreacentral │
│ │ │ │
│ docs-site/** ──push──▶ │ │ ┌──────────────────────┐ │
│ │ deploy │ │ Static Web App │ │
│ Actions: │ token │ │ (quantai-docs) │ │
│ docs-deploy.yml ────────┼────────▶│ │ Free tier │ │
│ │ │ │ defaultHostname: │ │
│ │ │ │ *.azurestaticapps.net│ │
│ │ │ └──────────────────────┘ │
└──────────────────────────┘ └──────────────────────────┘


┌──────────────────┐
│ Azure Front Door │
│ (글로벌 CDN, 자동) │
└──────────────────┘
항목
리소스 그룹quantai-docs-rg
리전 (control plane)koreacentral (CDN은 글로벌)
리소스 이름quantai-docs
SKUFree (월 $0, 100GB egress, 0.5GB storage)
태그Owner=ttagu99, Department=quant-ai, CostCenter=docs, Environment=production
Azure 리소스 태그 정책

GenOS 정책상 모든 Azure 리소스는 Owner, Department, CostCenter, Environment 4개 태그를 필수로 갖습니다. Bicep 템플릿( infra/azure/static_web_app.bicep)과 배포 스크립트( scripts/docs/deploy_static_web_app.sh)는 모두 이 정책을 자동 적용합니다. 직접 Portal에서 만들 경우 누락하면 정책 위반으로 거부됩니다.

1. 사전 요구 사항

  • Azure CLI (az login 완료, Static Web Apps 쿼터 보유 구독)
  • GitHub CLI (gh auth login, genonai/quant-ai repo의 repo scope)
  • Bicep CLI (최신 az에 번들). 검증은 az bicep build로 가능
  • 로컬에서 docs 빌드가 한 번 성공: cd docs-site && npm ci && npm run build

2. 첫 배포 (수동, 1회)

배포 스크립트 한 줄로 ① 리소스 그룹 생성 → ② Bicep 적용 → ③ 배포 토큰 추출 → ④ GitHub repo secret 등록까지 끝납니다.

chmod +x scripts/docs/deploy_static_web_app.sh
./scripts/docs/deploy_static_web_app.sh

스크립트 실행 후 출력에 다음이 보입니다.

✅ Done.
Default hostname : https://quantai-docs.azurestaticapps.net
GitHub secret : AZURE_STATIC_WEB_APPS_API_TOKEN (set on genonai/quant-ai)

수동으로 단계를 쪼개고 싶다면 다음 시퀀스와 동치입니다.

# (a) 리소스 그룹
az group create \
--name quantai-docs-rg \
--location koreacentral \
--tags Owner=ttagu99 Department=quant-ai CostCenter=docs Environment=production

# (b) Bicep 적용
az deployment group create \
--resource-group quantai-docs-rg \
--template-file infra/azure/static_web_app.bicep \
--parameters name=quantai-docs sku=Free

# (c) 배포 토큰
TOKEN=$(az staticwebapp secrets list \
--name quantai-docs \
--resource-group quantai-docs-rg \
--query properties.apiKey -o tsv)

# (d) GitHub secret 등록
printf '%s' "$TOKEN" | gh secret set AZURE_STATIC_WEB_APPS_API_TOKEN \
--repo genonai/quant-ai --body -
unset TOKEN
배포 토큰 보안
  • 토큰은 절대 커밋 금지. .env, 노트, 채팅 등 어디에도 저장하지 마세요.
  • 누출 의심 시 az staticwebapp secrets reset --name quantai-docs --resource-group quantai-docs-rg 로 즉시 재발급 후 GitHub secret을 갱신합니다.
  • 워크플로의 secrets.AZURE_STATIC_WEB_APPS_API_TOKEN 외에 다른 곳에서 참조하지 않습니다.

3. URL 확인 및 docusaurus.config 동기화

배포가 끝나면 기본 호스트네임이 https://<app-name>.azurestaticapps.net 형태로 발급됩니다. docs-site/docusaurus.config.tsurl 필드를 실제 값으로 갱신하세요(혹은 배포 시 DOCS_SITE_URL 환경변수로 주입).

url: process.env.DOCS_SITE_URL ?? 'https://quantai-docs.azurestaticapps.net',

이 값이 사이트맵·canonical·OG 메타데이터에 모두 반영됩니다.

4. 자동 배포 (GitHub Actions)

.github/workflows/docs-deploy.yml 가 다음을 처리합니다.

  • push to main + docs-site/** 변경 → 프로덕션 배포 (production environment의 manual approval rule이 있으면 게이트 적용)
  • pull_request + docs-site/** 변경 → PR preview URL 생성 (PR 댓글로 자동 게시). PR close/merge 시 자동 정리
  • workflow_dispatch → 수동 재배포 (토큰 회전 후 재시도 등)

빌드 단계는 다음 순서로 동작합니다.

  1. Node 22 setup + npm ci (cache key는 docs-site/package-lock.json)
  2. npm run build — Docusaurus 빌드 (onBrokenLinks=warn 기본)
  3. staticwebapp.config.jsonbuild/로 복사
  4. Azure/static-web-apps-deploy@v1 호출 (skip_app_build=true)
  5. 배포 결과를 GitHub step summary에 기록
Production 환경 게이트 활성화

Repo Settings → Environments → production 에서 "Required reviewers"를 설정하면 main에 머지된 docs-site 변경이 즉시 배포되지 않고 승인을 거칩니다. 첫 배포가 안정화될 때까지 권장합니다.

5. 라우팅·헤더·캐시 (staticwebapp.config.json)

docs-site/staticwebapp.config.json에서 다음을 관리합니다.

항목
/assets/* 캐시public, max-age=31536000, immutable (Docusaurus 해시 자산)
/img/* 캐시public, max-age=86400
검색 인덱스public, max-age=300, must-revalidate
navigationFallback/404.html rewrite (Docusaurus 404 페이지 활용)
보안 헤더HSTS, X-Frame-Options, Referrer-Policy, Permissions-Policy, CSP
MIME types.webmanifest, .woff2, .md, .mdx

CSP는 정적 사이트 기본값('self' + inline)으로 설정되어 있어 외부 위젯 (예: 구글 애널리틱스)을 추가하면 그에 맞춰 script-src / connect-src 를 확장해야 합니다.

6. 커스텀 도메인 (옵션)

기본 *.azurestaticapps.net 외에 사용자 도메인을 붙이려면 다음 순서를 따릅니다.

# (1) DNS 측 — CNAME 레코드
# docs.quant-ai.example.com CNAME quantai-docs.azurestaticapps.net

# (2) Azure 측 — 도메인 등록 + 검증
az staticwebapp hostname set \
--name quantai-docs \
--resource-group quantai-docs-rg \
--hostname docs.quant-ai.example.com

apex 도메인(quant-ai.example.com)을 쓰려면 CNAME 대신 TXT 검증으로 --validation-method dns-txt-token을 지정합니다. Bicep 템플릿에는 옵션 파라미터 customDomain이 준비되어 있어 IaC로도 등록 가능합니다.

7. 모니터링 (옵션)

기본 ASWA Free 티어는 Application Insights 통합을 지원하지 않습니다(Standard 이상에서 가능). 대안으로:

  • Azure Portal → Static Web Apps → Metrics: 요청 수, 에러율, 대역폭
  • Azure Monitor: 리소스 진단 설정에서 활동 로그를 Log Analytics로 전송
  • GitHub Actions step summary: 배포 성공/실패 즉시 확인
  • Cloudflare 등 외부 RUM: 이 프로젝트 범위에선 미사용

추후 트래픽이 증가하면 Standard로 업그레이드해 Application Insights 연결을 검토합니다(월 ~$9/app, 분당 ~100만 요청 무료 한도).

8. 트러블슈팅

증상점검
배포 워크플로 401 / 403토큰 만료 또는 회전 미반영. scripts/docs/deploy_static_web_app.sh 재실행 → secret 갱신
PR preview URL이 PR 댓글에 안 뜸permissions: pull-requests: write 누락 또는 fork PR (Azure SWA는 fork PR에 제한 적용)
정적 자산 404output_location 지정 오류. 워크플로에서 app_location: docs-site/build, skip_app_build: true 가 맞는지 확인
한국에서 첫 응답 지연ASWA는 글로벌 CDN을 자동 활용. 첫 cold cache miss는 정상이며 이후 지연 감소 확인
az bicep build 경고az upgrade && az bicep upgrade로 최신 컴파일러

관련 페이지