diff --git a/services/cf-multisite.md b/services/cf-multisite.md new file mode 100644 index 0000000..8c86d07 --- /dev/null +++ b/services/cf-multisite.md @@ -0,0 +1,92 @@ +--- +title: CF Multisite (정적 사이트 호스팅) +updated: 2026-03-28 +tags: [service, hosting, cloudflare, r2] +--- + +## 개요 + +Cloudflare Workers + R2 기반 멀티테넌트 정적 사이트 호스팅 플랫폼. Gitea repo에 push하면 자동으로 R2에 업로드되고, Workers가 서브도메인으로 서빙. + +## 아키텍처 + +``` +hosting/{customer} repo (Gitea push) + → Gitea Actions Runner (jp1) + → rclone sync → R2 multisite-bucket/sites/{customer}/ + → Cloudflare Workers (cf-multisite) + → {customer}.actions.it.com +``` + +## 구성요소 + +| 항목 | 값 | +|------|-----| +| Worker | `cf-multisite` (Cloudflare Workers) | +| R2 버킷 | `multisite-bucket` | +| R2 API 키 | Vault `secret/cloud/r2-multisite` | +| DNS | `*.actions.it.com` → Cloudflare proxied | +| Worker 라우트 | `*.actions.it.com/*` | +| Gitea org | `hosting` (private) | +| 소스 코드 | `kaffa/cf-multisite` | +| 템플릿 | `kaffa/cf-multisite/template/.gitea/workflows/deploy.yml` | + +## Gitea org secrets (hosting) + +org-level secrets로 모든 고객 repo에 자동 적용: + +| Secret | 용도 | +|--------|------| +| R2_ACCESS_KEY | R2 S3 호환 액세스 키 | +| R2_SECRET_KEY | R2 S3 호환 시크릿 키 | +| R2_ENDPOINT | `https://d8e5997eb4040f8b489f09095c0f623c.r2.cloudflarestorage.com` | + +## 고객 사이트 추가 절차 + +```bash +# 1. hosting org에 repo 생성 +tea repo create --name {customer} --owner hosting --init + +# 2. deploy.yml 복사 (kaffa/cf-multisite 템플릿에서) +# template/.gitea/workflows/deploy.yml을 고객 repo에 추가 + +# 3. 정적 파일 push +git clone https://gitea.inouter.com/hosting/{customer}.git +cd {customer} +# index.html 등 추가 +git add . && git commit -m "initial site" && git push + +# 4. 자동 배포 → https://{customer}.actions.it.com +``` + +org secrets가 자동 상속되지 않으면 repo-level secrets를 수동 설정: +```bash +TOKEN="(Vault secret/apps/gitea api_token)" +for secret in R2_ACCESS_KEY R2_SECRET_KEY R2_ENDPOINT; do + curl -X PUT -H "Authorization: token $TOKEN" \ + "https://gitea.inouter.com/api/v1/repos/hosting/{customer}/actions/secrets/$secret" \ + -H "Content-Type: application/json" \ + -d "{\"data\":\"(Vault secret/cloud/r2-multisite $secret)\"}" +done +``` + +## Worker 기능 + +- **멀티테넌트**: 서브도메인 → R2 경로 매핑 (`{customer}.actions.it.com` → `/sites/{customer}/`) +- **캐시**: HTML 1시간, 정적파일(CSS/JS/이미지) 24시간 Edge 캐시 +- **Rate Limiting**: KV 기반 분당 요청 수 제한 (티어별) +- **Admin API**: 사용량/고객/통계 조회 (`/api/usage/:customer`, `/api/customers` 등) +- **MIME 자동감지**: 확장자 기반 Content-Type 매핑 + +## 배포 방식 + +rclone으로 R2 S3 호환 API 사용. AWS CLI 대비 설치 빠르고 경량. + +## 운영 중인 사이트 + +| 서브도메인 | repo | 상태 | +|-----------|------|------| +| demo.actions.it.com | kaffa/cf-multisite (sample-site) | ✅ | +| test-customer.actions.it.com | (직접 업로드) | ✅ | +| multisite-demo.actions.it.com | (직접 업로드) | ✅ | +| demo-site.actions.it.com | hosting/demo-site | ✅ |