# Quickstart: CDN Image Serving

## Local development (no CDN)

No configuration change required. `S3_PUBLIC_BASE_URL` is unset by default.

```bash
docker compose up
```

Upload an image and inspect the API response:

```bash
curl -s http://localhost:8000/api/v1/images | jq '.items[0] | {file_url, thumbnail_url}'
```

Expected (local dev — relative proxy paths):
```json
{
  "file_url": "/api/v1/images/550e8400-.../file",
  "thumbnail_url": "/api/v1/images/550e8400-.../thumbnail"
}
```

The UI loads images via these relative paths, which hit the API proxy as before.

---

## Production (CDN configured)

Add `S3_PUBLIC_BASE_URL` to the Vault secret bundle at `reactbin/api/config`:

```
S3_PUBLIC_BASE_URL = https://cdn.reactbin.juggalol.com
```

Force VSO sync and restart:

```bash
kubectl annotate vaultstaticsecret api-secret -n reactbin \
  secrets.hashicorp.com/force-sync=$(date +%s) --overwrite

kubectl rollout restart deployment/api -n reactbin
```

Upload a test image and inspect the response:

```bash
curl -s https://reactbin.juggalol.com/api/v1/images | jq '.items[0] | {file_url, thumbnail_url}'
```

Expected (production — CDN URLs):
```json
{
  "file_url": "https://cdn.reactbin.juggalol.com/e3b0c44...",
  "thumbnail_url": "https://cdn.reactbin.juggalol.com/e3b0c44....thumb"
}
```

Open the browser network panel on the library page and confirm image requests go to `cdn.reactbin.juggalol.com`, not `/api/`.

---

## Verifying existing images after migration

All existing images were migrated to R2 with the same object keys before this feature was deployed. Once `S3_PUBLIC_BASE_URL` is configured, the API will return CDN URLs for all images immediately — no per-image migration step is needed.
