reference · ops
Environment variables
Updated Sun Aug 16 2026 00:00:00 GMT+0000 (Coordinated Universal Time)
Environment variables
Auth URL (common footgun)
- Local:
AUTH_URL=http://localhost:3000— if this is set tohttps://devhoard.me, OAuth and magic-link callbacks leave localhost for production. - Vercel Production:
AUTH_URL=https://devhoard.me
Also register localhost callbacks in GitHub/Google OAuth apps:
http://localhost:3000/api/auth/callback/githubhttp://localhost:3000/api/auth/callback/google
Core
| Variable | Role |
|---|---|
DATABASE_URL | Neon pooled URL (runtime + ideally Build) |
DIRECT_URL / DATABASE_URL_UNPOOLED | Migrations |
AUTH_SECRET | Auth.js session secret |
ITEM_ENCRYPTION_KEY | SECRET item AES key (base64 32 bytes) |
Soft-launch ops
| Variable | Role |
|---|---|
ADMIN_EMAILS | Comma-separated emails for Owner metrics (/app/admin/metrics). Case-insensitive match to session email. Does not grant Pro or IMAGE uploads. Local: .env.local + restart npm run dev. Prod: Vercel env + redeploy. |
R2_ACCOUNT_ID | Cloudflare R2 account |
R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY | R2 API token |
R2_BUCKET | Private bucket name |
R2_ENDPOINT | Optional; defaults to https://$R2_ACCOUNT_ID.r2.cloudflarestorage.com |
CRON_SECRET | Bearer for /api/cron/purge-trash |
Missing R2_* with a Pro user → 503 “Storage is not configured” on upload (not a Pro issue). CORS must allow your app origin (including http://localhost:3000 for local PUT).
See .env.example for the full list (OAuth, Resend, Upstash, Turnstile, Sentry).