fix(tiles): configure R2 CDN base URL build argument to resolve production basemap 404 #120

Closed
opened 2026-10-15 05:51:37 +00:00 by yuris · 0 comments
Owner

What to build

Resolve the production 404 error when loading indonesia.pmtiles by configuring NEXT_PUBLIC_TILES_BASE_URL in Docker image compilation and providing a production default fallback to Cloudflare R2.

Root Cause

  1. public/tiles/indonesia.pmtiles (81 MB) is deliberately gitignored to prevent committing large binary vector tile archives into git.
  2. The basemap vector tile archive is already compiled and hosted on Cloudflare R2 at https://tiles.gambut.nokopia.com/tiles/indonesia.pmtiles (HTTP 200 with byte-range request support).
  3. In Dockerfile and .forgejo/workflows/deploy.yml, NEXT_PUBLIC_TILES_BASE_URL is neither declared as a Docker build argument nor supplied during the image build.
  4. Next.js inlines "" for NEXT_PUBLIC_TILES_BASE_URL during pnpm build, causing resolveTileUrl() in src/lib/gis/tile-url.ts to fall back to pmtiles:///tiles/indonesia.pmtiles.
  5. The standalone container lacks public/tiles/indonesia.pmtiles, returning HTTP 404 when the client MapLibre instance attempts to fetch basemap tiles.

Technical specifications

  1. Target files:
    • Dockerfile: Declare ARG NEXT_PUBLIC_TILES_BASE_URL=https://tiles.gambut.nokopia.com/tiles and pass it to the builder stage as ENV NEXT_PUBLIC_TILES_BASE_URL=$NEXT_PUBLIC_TILES_BASE_URL.
    • .forgejo/workflows/deploy.yml: Add build-args: NEXT_PUBLIC_TILES_BASE_URL=https://tiles.gambut.nokopia.com/tiles to docker/build-push-action.
    • src/lib/gis/tile-url.ts: In production environments (process.env.NODE_ENV === "production"), default base to https://tiles.gambut.nokopia.com/tiles if NEXT_PUBLIC_TILES_BASE_URL is unset or empty, ensuring gitignored tile archives never fall back to the container in production.
    • src/lib/gis/__tests__/tile-url.test.ts: Add test cases validating production fallback behavior and local development fallback isolation.

Acceptance criteria

  • Dockerfile and deploy.yml accept and pass NEXT_PUBLIC_TILES_BASE_URL.
  • resolveTileUrl("indonesia") resolves to pmtiles://https://tiles.gambut.nokopia.com/tiles/indonesia.pmtiles when built in production mode without explicit local overrides.
  • Local offline development (pnpm dev) continues to resolve to local pmtiles:///tiles/... when NEXT_PUBLIC_TILES_BASE_URL is not provided.
  • Production web deployment successfully renders the dark Protomaps basemap without 404 errors.
  • Vitest test suite passes with 100% success.

Authoritative Specifications & Reference Documentation

### What to build Resolve the production 404 error when loading `indonesia.pmtiles` by configuring `NEXT_PUBLIC_TILES_BASE_URL` in Docker image compilation and providing a production default fallback to Cloudflare R2. ### Root Cause 1. `public/tiles/indonesia.pmtiles` (81 MB) is deliberately gitignored to prevent committing large binary vector tile archives into git. 2. The basemap vector tile archive is already compiled and hosted on Cloudflare R2 at `https://tiles.gambut.nokopia.com/tiles/indonesia.pmtiles` (HTTP 200 with byte-range request support). 3. In `Dockerfile` and `.forgejo/workflows/deploy.yml`, `NEXT_PUBLIC_TILES_BASE_URL` is neither declared as a Docker build argument nor supplied during the image build. 4. Next.js inlines `""` for `NEXT_PUBLIC_TILES_BASE_URL` during `pnpm build`, causing `resolveTileUrl()` in `src/lib/gis/tile-url.ts` to fall back to `pmtiles:///tiles/indonesia.pmtiles`. 5. The standalone container lacks `public/tiles/indonesia.pmtiles`, returning HTTP 404 when the client MapLibre instance attempts to fetch basemap tiles. ### Technical specifications 1. **Target files**: - `Dockerfile`: Declare `ARG NEXT_PUBLIC_TILES_BASE_URL=https://tiles.gambut.nokopia.com/tiles` and pass it to the `builder` stage as `ENV NEXT_PUBLIC_TILES_BASE_URL=$NEXT_PUBLIC_TILES_BASE_URL`. - `.forgejo/workflows/deploy.yml`: Add `build-args: NEXT_PUBLIC_TILES_BASE_URL=https://tiles.gambut.nokopia.com/tiles` to `docker/build-push-action`. - `src/lib/gis/tile-url.ts`: In production environments (`process.env.NODE_ENV === "production"`), default `base` to `https://tiles.gambut.nokopia.com/tiles` if `NEXT_PUBLIC_TILES_BASE_URL` is unset or empty, ensuring gitignored tile archives never fall back to the container in production. - `src/lib/gis/__tests__/tile-url.test.ts`: Add test cases validating production fallback behavior and local development fallback isolation. ### Acceptance criteria - [x] `Dockerfile` and `deploy.yml` accept and pass `NEXT_PUBLIC_TILES_BASE_URL`. - [x] `resolveTileUrl("indonesia")` resolves to `pmtiles://https://tiles.gambut.nokopia.com/tiles/indonesia.pmtiles` when built in production mode without explicit local overrides. - [x] Local offline development (`pnpm dev`) continues to resolve to local `pmtiles:///tiles/...` when `NEXT_PUBLIC_TILES_BASE_URL` is not provided. - [x] Production web deployment successfully renders the dark Protomaps basemap without 404 errors. - [x] Vitest test suite passes with 100% success. --- ### Authoritative Specifications & Reference Documentation - **Titik Gambut Architecture**: [`docs/ARCHITECTURE.md`](https://git.nokopia.com/yuris/titik-gambut-next/src/branch/main/docs/ARCHITECTURE.md) - **Cloudflare R2 Tiles Endpoint**: `https://tiles.gambut.nokopia.com/tiles/indonesia.pmtiles` - **Tile URL Resolver Implementation**: [`src/lib/gis/tile-url.ts`](https://git.nokopia.com/yuris/titik-gambut-next/src/branch/main/src/lib/gis/tile-url.ts)
yuris closed this issue 2026-10-15 06:27:36 +00:00
Sign in to join this conversation.
No labels
backend
frontend
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#120
No description provided.