Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/samgutentag/bcycle-map/llms.txt

Use this file to discover all available pages before exploring further.

BCycle Map runs entirely on Cloudflare’s free tier — three Workers, one KV namespace, and one R2 bucket. None of these resources exist in a fresh account until you provision them. This guide walks through every step exactly once, from authenticating Wrangler to verifying that the poller is writing live data. Each command must be run from the repository root unless stated otherwise.
Both the production KV id and the preview_id produced in Step 2 must be pasted into all three wrangler*.toml files (wrangler.toml, wrangler.read-api.toml, wrangler.smoke.toml). Every placeholder value PLACEHOLDER_REPLACE_AT_DEPLOY in those files must be replaced. Workers deployed with a placeholder ID will bind to the wrong namespace and either fail silently or read/write stale data.
1
Authenticate Wrangler
2
Log in with your Cloudflare account via browser OAuth, then capture your Account ID — you will need it for the GitHub Actions secrets in a later step.
3
npx wrangler login     # opens a browser window for OAuth
npx wrangler whoami    # prints your email and Account ID
4
Save the Account ID (a 32-character hex string). This becomes the CF_ACCOUNT_ID GitHub secret.
5
Create the KV namespace
6
The KV namespace stores both the latest GBFS snapshot (hot path, served by the read API) and the intra-hour buffer keys (sealed into parquet by the compaction job). You need a production namespace and a preview namespace for local wrangler dev runs.
7
npx wrangler kv namespace create GBFS_KV            # production
npx wrangler kv namespace create GBFS_KV --preview  # preview (local dev)
8
Each command prints an id. Open all three TOML files and replace every PLACEHOLDER_REPLACE_AT_DEPLOY with the appropriate value:
9
# In wrangler.toml, wrangler.read-api.toml, and wrangler.smoke.toml
[[kv_namespaces]]
binding    = "GBFS_KV"
id         = "<production-id-from-first-command>"
preview_id = "<preview-id-from-second-command>"
10
Save the production id — it becomes the CF_KV_NAMESPACE_ID GitHub secret used by the compaction workflow.
11
Create the R2 bucket
12
The R2 bucket (bcycle-map-archive) holds compacted parquet partitions written by the hourly GitHub Actions job. Create the bucket, then enable its public URL and add a CORS policy so the frontend can fetch parquet files directly from R2 in the browser.
13
Create the bucket:
14
npx wrangler r2 bucket create bcycle-map-archive
15
Enable the public development URL:
16
In the Cloudflare dashboard navigate to R2 → bcycle-map-archive → Settings → Public Development URL → Allow Access. Cloudflare assigns a https://pub-<hash>.r2.dev URL — copy it. This becomes VITE_R2_PUBLIC_URL in .env.local.
17
Add the CORS policy:
18
Still in Settings → CORS Policy → Add policy, paste:
19
[
  {
    "AllowedOrigins": ["*"],
    "AllowedMethods": ["GET"],
    "AllowedHeaders": ["*"]
  }
]
20
The wildcard AllowedOrigins is appropriate here. GBFS station data is publicly available information — BCycle publishes it openly — and R2 has no egress fees, so there is no cost or security exposure from allowing any origin to read the bucket. Tighten the policy to your production domain if your use case ever changes.
21
Create R2 API credentials for GitHub Actions:
22
In the dashboard: R2 → Manage API Tokens → Create API Token. Choose Object Read & Write and scope it to the bcycle-map-archive bucket. Save both the Access Key ID and the Secret Access Key — the secret is shown only once. These become the R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY GitHub secrets.
23
Deploy the three Workers
24
With the KV namespace IDs in place, deploy all three Workers. Each prints its *.workers.dev URL on success.
25
# Poller: scheduled every 5 minutes, writes GBFS snapshots to KV
npx wrangler deploy

# Read API: HTTP Worker serving /api/systems/:id/current (and more)
npx wrangler deploy --config wrangler.read-api.toml

# Smoke: daily cron at 09:00 UTC, files a GitHub Issue on data errors
npx wrangler deploy --config wrangler.smoke.toml
26
Save the read-API URL printed by the second command — it looks like https://bcycle-map-read-api.<your-account>.workers.dev. The frontend needs it in the next step.
27
You can tail live logs from any Worker to confirm the first cron tick fires correctly:
npx wrangler tail bcycle-map-poller
28
Configure the frontend
29
Copy the example environment file and set the read-API URL:
30
cp .env.example .env.local
31
Edit .env.local:
32
VITE_API_BASE=https://bcycle-map-read-api.<your-account>.workers.dev
VITE_R2_PUBLIC_URL=https://pub-<hash>.r2.dev
33
Replace both placeholders with the values captured in the previous steps. Now npm run dev:web fetches live data from your deployed Worker without needing any local Workers running.
34
Add GitHub Actions secrets
35
Open GitHub → Settings → Secrets and variables → Actions and add the following repository secrets so the compaction and deployment workflows have the credentials they need:
36
SecretValueCF_ACCOUNT_IDAccount ID from Step 1CLOUDFLARE_API_TOKENAPI token with Workers Scripts: Edit permissionCF_KV_API_TOKENAPI token with Workers KV Storage: Edit permissionCF_KV_NAMESPACE_IDProduction KV id from Step 2R2_ACCESS_KEY_IDR2 access key from Step 3R2_SECRET_ACCESS_KEYR2 secret from Step 3R2_BUCKETbcycle-map-archive
37
See the Environment Variables reference for full details on creating each token with the correct permission template.
38
Verify
39
Wait up to 5 minutes for the first poller cron tick to fire, then hit the read API directly:
40
curl https://bcycle-map-read-api.<your-account>.workers.dev/api/systems/bcycle_santabarbara/current
41
A successful response is a JSON object containing station information with roughly 85 stations for Santa Barbara. If you receive a not found error, the cron has not fired yet — wait one more polling interval and retry.
42
You can also trigger the compaction workflow manually to verify the GitHub Actions secrets are all correct:
43
gh workflow run compact.yml
44
Check the Actions tab for the run result. A green “Run compaction” step confirms all six compact.yml secrets are valid and the KV → R2 pipeline is operational.

Build docs developers (and LLMs) love