Environment variables
Every DS-CS variable — what it does, Essential or Optional, and how to get its value.
Copy .env.example to .env. Never commit .env. Same file works for Docker, from-source and Vercel (on Vercel you paste these values into the project's Environment Variables instead of a file).
Generate secrets with:
openssl rand -base64 32 # BETTER_AUTH_SECRET
openssl rand -hex 32 # API_KEY
npx web-push generate-vapid-keys # VAPID push keys
NEXT_PUBLIC_*variables are inlined into the client bundle at build time. On Docker and from-source they come from.env. On Vercel pull-only deploys (see Deploy on Vercel) they are baked into the Docker image — changing them means rebuilding and re-pushing the image.
Database
| Variable | Essential | How to get it |
|---|---|---|
DATABASE_URL | Essential | Bundled compose Postgres: postgresql://postgres:postgres@db:5432/ds_cs. Managed provider: copy its TLS URL, e.g. postgresql://user:pass@host:5432/db?sslmode=require. |
Admin + API auth
| Variable | Essential | How to get it |
|---|---|---|
ADMIN_EMAIL | Essential | Your email — bootstrap admin account + /os login. |
ADMIN_PASSWORD | Essential | A strong password you choose. |
API_KEY | Essential | Shared REST key, sent as Authorization: Bearer <API_KEY>. Generate: openssl rand -hex 32. |
API_KEY_RATE_LIMIT_MAX_REQUESTS | Optional | Max API requests per window. Default 30. |
API_KEY_RATE_LIMIT_WINDOW_MS | Optional | Rate-limit window in ms. Default 60000. |
MCP_API_KEY | Optional | Separate key for the standalone (stdio) MCP server. Falls back to API_KEY when empty. |
BETTER_AUTH_URL | Essential | Public app URL, e.g. https://your-domain.com. Must match what users open. |
BETTER_AUTH_SECRET | Essential | Long random session secret. Generate: openssl rand -base64 32. |
NEXT_PUBLIC_APP_URL | Essential | Same public URL — used for SEO, metadata, client links and rustfs CORS. |
S3 / media storage
| Variable | Essential | How to get it |
|---|---|---|
S3_ENDPOINT | Essential | Bundled rustfs: http://rustfs:9000. External provider: its endpoint URL. Empty for AWS S3. |
S3_REGION | Essential | Storage region, e.g. us-east-1. |
S3_ACCESS_KEY_ID | Essential | Bundled rustfs default 442c201224d92fbd5df5aa9d (must match RUSTFS_ACCESS_KEY in docker-compose.yml). External: your credentials. |
S3_SECRET_ACCESS_KEY | Essential | Bundled rustfs default ea8d22810ade922c73ada6bc0c446c5de465db49454c02b8 (must match RUSTFS_SECRET_KEY). External: your credentials. |
S3_BUCKET_NAME | Essential | Media bucket name. Bundled stack creates ds-cs automatically. |
S3_FORCE_PATH_STYLE | Essential | true for rustfs/MinIO/path-style endpoints, false for AWS standard endpoints. |
S3_PUBLIC_BASE_URL | Optional | Public base for serving files when it differs from the endpoint. Supabase: https://your-project.supabase.co/storage/v1/object/public. MinIO/R2: your domain. AWS: https://your-bucket.s3.amazonaws.com. Bundled rustfs: http://localhost:9000/ds-cs. |
MEDIA_MAX_IMAGE_SIZE_MB | Optional | Per-image cap. Default 10. |
MEDIA_MAX_VIDEO_SIZE_MB | Optional | Per-video cap. Default 100. |
MEDIA_MAX_AUDIO_SIZE_MB | Optional | Per-audio cap. Default 25. |
MEDIA_MAX_FILE_SIZE_MB | Optional | Per-file cap. Default 25. |
MEDIA_ALLOWED_MIME_TYPES | Optional | Comma allowlist override, e.g. image/jpeg,image/png,video/mp4. Empty = built-in allowlist. |
MEDIA_KEY_PREFIX | Optional | Storage key prefix. Default media. |
CORS is required — browser uploads PUT straight to the S3 endpoint (cross-origin). Bundled rustfs sets RUSTFS_CORS_ALLOWED_ORIGINS from NEXT_PUBLIC_APP_URL automatically; on external S3 allow your app origin on the bucket or uploads fail silently.
Push notifications (needs HTTPS)
| Variable | Essential | How to get it |
|---|---|---|
NEXT_PUBLIC_WEBPUSH_PUBLIC_KEY | Optional | VAPID public key — npx web-push generate-vapid-keys. Required only for push. |
WEBPUSH_PRIVATE_KEY | Optional | VAPID private key (must be the matching half). Required only for push. |
WEBPUSH_SUBJECT | Optional | Contact URI, e.g. mailto:you@example.com. Required only for push. |
Without these the UI shows a setup-required message instead of breaking.
App + integrations
| Variable | Essential | How to get it |
|---|---|---|
NEXT_PUBLIC_ANIMATED_EMOJIES | Optional | Animated .webp emoji overlays. Default false. |
DS_SH_URL | Optional | Your SH shortener URL — push links get shortened through it. Empty = skip. |
DS_SH_API_KEY | Optional | API key for that SH instance. Empty = skip. |
NEXT_PUBLIC_POSTHOG_PROJECT_TOKEN | Optional | PostHog browser token for analytics. Empty = no tracking. |
NEXT_PUBLIC_POSTHOG_HOST | Optional | PostHog host. Default https://us.i.posthog.com. |
DISABLE_DEV_TEAM_PH | Optional | true stops relaying server events to the team proxy. Default true. |
PH_PROJECT_ID | Optional | PostHog project id for bootstrap:posthog tooling. Default 581705. |
PH_PERSONAL_API_KEY | Optional | phx_ personal key with admin scope for PostHog bootstrap + sourcemap upload. Empty = skip. |
SEO + visibility
| Variable | Essential | How to get it |
|---|---|---|
NEXT_PUBLIC_ALLOW_INDEXING | Optional | true lets search engines index. Default false (blocked). Submit /sitemap.xml in Search Console after enabling. |
NEXT_PUBLIC_ENABLE_SEARCH_CONSOLE | Optional | true enables verification helpers. Default false. |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION | Optional | Meta-tag token from Search Console. |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_FILE | Optional | Verification filename Google gave you. |
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_FILE_CONTENT | Optional | Exact HTML content of that file. |
NEXT_PUBLIC_SHOW_INTERNAL_NAV | Optional | Shows internal nav links for admin previews. Default false. |
NEXT_PUBLIC_ADDITIONAL_IMAGE_DOMAINS | Optional | Comma domains for Next.js Image optimization, e.g. cdn.example.com. |
Operator switches
| Variable | Essential | How to get it |
|---|---|---|
DEMO_MODE | Optional | true disables all create/update/delete (reads, views, likes keep working). Operator-only, default false. |
Support: hey@dastyare.social.
Loading repository…