docs: screenshot sandbox setup

Document SCREENSHOT_SANDBOX_IMAGE in .env.example and the optional-services table, and update the project structure and degrade-gracefully notes.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
jakeandClaude Sonnet 5.5 committed 2026-10-01 22:27:42 -04:00
1 parent a5ba5e9833
commit 7da668cce0
3 files changed
+9 -2

No files matched your search

+2 -2
View File
@@ -33,7 +33,7 @@ Runs without OAuth apps or third-party keys (full walkthrough: README "Developme
4. `pnpm dev`, then use the **Dev sign-in** form at `/login` (exists only when `NODE_ENV=development`)
5. Crons by hand: `curl -H "Authorization: Bearer dev" http://localhost:3000/api/cron/<name>`
Unset services degrade instead of failing (Blob → `apps/web/public/_dev-blob/`, no Redis → no rate limits or monitor locks, no Resend → sends throw). Code that adds a new external service must keep `pnpm dev` working without its credentials (pattern: `packages/blob/src/files.ts`, `getRedis()`) and add a row to the README's optional-services table.
Unset services degrade instead of failing (Blob → `apps/web/public/_dev-blob/`, no Redis → no rate limits or monitor locks, no Resend → sends throw, no `SCREENSHOT_SANDBOX_IMAGE` → no screenshots). Code that adds a new external service must keep `pnpm dev` working without its credentials (pattern: `packages/blob/src/files.ts`, `getRedis()`) and add a row to the README's optional-services table.
### Development
@@ -213,7 +213,7 @@ domainstack.io/
│ ├── polar/ # Polar billing SDK, webhooks, reconciliation
│ ├── redis/ # Upstash Redis client + rate limiter
│ ├── safe-fetch/ # SSRF-hardened fetch (DNS pinning, private-IP blocks)
│ ├── screenshot/ # Puppeteer screenshot capture
│ ├── screenshot/ # Screenshot capture in a single-use Vercel Sandbox (client, network denylist, error classes)
│ ├── screenshot-runner/ # Chromium runner image for Vercel Sandbox (published to VCR by GitHub Actions)
│ ├── types/ # Shared TypeScript types (@domainstack/types)
│ │ └── src/
+1
View File
@@ -107,6 +107,7 @@ Every other variable in `.env.example` is optional locally:
| OAuth (GitHub, GitLab, Google, Vercel) | Sign in as a seeded user with email/password |
| Resend | Emails are not sent: each send fails with "Resend is not configured" |
| Vercel Blob | Favicons, screenshots and OG images are stored in `apps/web/public/_dev-blob/` |
| Vercel Sandbox | Screenshots are skipped (not cached), so the screenshot slot stays empty |
| Upstash Redis | Rate limiting, session caching and monitor locks are skipped |
| Polar | Billing is disabled. When a token is set, Polar runs in sandbox outside production |
| Global Config | Provider detection falls back to "unknown" |
+6
View File
@@ -77,6 +77,12 @@ BLOB_READ_WRITE_TOKEN=
# Blob key hashing secret (required outside development)
BLOB_SIGNING_SECRET=
# Screenshot runner image for Vercel Sandbox: the immutable digest printed by the
# "Screenshot runner image" workflow (vcr.vercel.com/<team>/<project>/domainstack-screenshot@sha256:…).
# Deployments authenticate to Sandbox with Vercel OIDC; locally, `vercel env pull` provides both.
# Leave unset to skip screenshots.
SCREENSHOT_SANDBOX_IMAGE=
# Optional: override user agent sent with upstream requests
EXTERNAL_USER_AGENT=