infra(r2): configure Cloudflare R2 bucket with CORS rules and custom domain for PMTiles delivery #101

Closed
opened 2026-10-15 00:35:21 +00:00 by yuris · 0 comments
Owner

This was generated by AI during triage.
State: ready-for-human (Manual infrastructure setup: Do NOT trigger autonomous implementers)

Context & Purpose

As mandated in docs/ARCHITECTURE.md §1.1, §3, and §4, all multi-megabyte spatial vector tile archives (concessions.pmtiles, peat_soil.pmtiles, khg.pmtiles, terrain.pmtiles) are static binary assets that must be served directly from edge object storage (Cloudflare R2) via Anycast CDN points of presence rather than tracked inside Git or served from VPS memory.

Cloudflare R2 provides zero-dollar egress fees and native HTTP 206 Partial Content byte-range support.

Required Infrastructure Steps (Human Maintainer)

  1. Create Cloudflare R2 Bucket:

    • Bucket name: titik-gambut-tiles (or nokopia-gambut-tiles).
    • Location hint: Asia Pacific / Singapore (APAC).
  2. Configure CORS Rules on R2 Bucket:
    Allow MapLibre GL JS clients to issue byte-range queries with range headers:

    [
      {
        "AllowedOrigins": [
          "https://gambut.nokopia.com",
          "http://localhost:3000"
        ],
        "AllowedMethods": ["GET", "HEAD"],
        "AllowedHeaders": ["Range"],
        "ExposeHeaders": ["Content-Range", "Content-Length", "Accept-Ranges"],
        "MaxAgeSeconds": 86400
      }
    ]
    
  3. Bind Custom Domain:

    • Attach custom domain tiles.gambut.nokopia.com (or route under cdn.nokopia.com/tiles/).
    • Ensure Cloudflare Cache Rules enable edge caching for .pmtiles and .png extensions.
  4. Generate S3-Compatible API Credentials:

    • Create R2 API token with Object Read & Write permissions.
    • Record R2_ACCOUNT_ID, R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, and R2_BUCKET_NAME for repository secrets.
  5. Local / CI Upload Utility:

    • Add scripts/upload-tiles-r2.mjs using @aws-sdk/client-s3 for uploading compiled archives.

Acceptance Criteria

  • R2 bucket provisioned and CORS rules active.
  • Custom domain or public endpoint returns HTTP 200/206 for sample range requests.
  • Secrets added to repository / deployment environment.
> *This was generated by AI during triage.* > **State:** `ready-for-human` (Manual infrastructure setup: Do NOT trigger autonomous implementers) ## Context & Purpose As mandated in `docs/ARCHITECTURE.md §1.1`, `§3`, and `§4`, all multi-megabyte spatial vector tile archives (`concessions.pmtiles`, `peat_soil.pmtiles`, `khg.pmtiles`, `terrain.pmtiles`) are static binary assets that must be served directly from edge object storage (Cloudflare R2) via Anycast CDN points of presence rather than tracked inside Git or served from VPS memory. Cloudflare R2 provides zero-dollar egress fees and native HTTP 206 Partial Content byte-range support. ## Required Infrastructure Steps (Human Maintainer) 1. **Create Cloudflare R2 Bucket**: - Bucket name: `titik-gambut-tiles` (or `nokopia-gambut-tiles`). - Location hint: Asia Pacific / Singapore (`APAC`). 2. **Configure CORS Rules on R2 Bucket**: Allow MapLibre GL JS clients to issue byte-range queries with range headers: ```json [ { "AllowedOrigins": [ "https://gambut.nokopia.com", "http://localhost:3000" ], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["Range"], "ExposeHeaders": ["Content-Range", "Content-Length", "Accept-Ranges"], "MaxAgeSeconds": 86400 } ] ``` 3. **Bind Custom Domain**: - Attach custom domain `tiles.gambut.nokopia.com` (or route under `cdn.nokopia.com/tiles/`). - Ensure Cloudflare Cache Rules enable edge caching for `.pmtiles` and `.png` extensions. 4. **Generate S3-Compatible API Credentials**: - Create R2 API token with Object Read & Write permissions. - Record `R2_ACCOUNT_ID`, `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, and `R2_BUCKET_NAME` for repository secrets. 5. **Local / CI Upload Utility**: - Add `scripts/upload-tiles-r2.mjs` using `@aws-sdk/client-s3` for uploading compiled archives. ## Acceptance Criteria - [x] R2 bucket provisioned and CORS rules active. - [x] Custom domain or public endpoint returns HTTP 200/206 for sample range requests. - [x] Secrets added to repository / deployment environment.
yuris closed this issue 2026-10-15 01:21:37 +00:00
Sign in to join this conversation.
No labels
backend
frontend
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/titik-gambut-next#101
No description provided.