diff --git a/.env.example b/.env.example index d5c3312..e850160 100644 --- a/.env.example +++ b/.env.example @@ -1,154 +1,119 @@ # ============================================================================= -# Trading Room SaaS - Environment Variables +# Trading Room โ€” Environment Variables # ============================================================================= -# Copy this file to .env and fill in the values -# ============================================================================= -# NOTE: These are DEVELOPMENT defaults. For production deployment, -# see DEPLOYMENT_GUIDE.md for proper production configuration. +# Copy to `.env` and fill in the values. See SETUP_KEYS.md for a step-by-step +# walkthrough of where every value comes from, and DEPLOYMENT_GUIDE.md for prod. +# +# Legend: ๐Ÿ” generate yourself (openssl) ๐Ÿงฉ from a provider ๐Ÿ–ฅ๏ธ from a server # ============================================================================= -# Application -APP_ENV=development -APP_DEBUG=true -APP_URL=http://localhost:8000 -APP_KEY= - -# Node Environment +# --- Runtime ---------------------------------------------------------------- NODE_ENV=development +RUST_LOG=info,api=debug +APP_URL=http://localhost:5173 # public base URL of the frontend # ============================================================================= -# Database Configuration (Neon Serverless PostgreSQL) -# ============================================================================= -# Sign up at: https://neon.tech -# Neon provides serverless Postgres with branching, scale-to-zero, and auto-scaling -# -# Get your connection string from Neon Console โ†’ Connection Details +# Rust API (backend-rs) # ============================================================================= +API_HOST=0.0.0.0 +API_PORT=8080 + +# Postgres connection string (๐Ÿงฉ Neon, or the local compose Postgres). +# Local compose example: postgresql://postgres:postgres@localhost:5432/tradingroom DATABASE_URL=postgresql://user:password@ep-xxx.region.aws.neon.tech/neondb?sslmode=require -DB_HOST=ep-xxx.region.aws.neon.tech -DB_NAME=neondb -DB_USER=your-neon-user -DB_PASSWORD=your-neon-password -DB_PORT=5432 -DB_SSL=true + +# Comma-separated origins allowed by the API (frontend + dev ports). +CORS_ORIGINS=http://localhost:5173,http://localhost:3000 + +# How the API reaches the signaling control-plane. +SIGNALING_URL=http://localhost:3000 +# ๐Ÿ” Shared secret the API presents to signaling. MUST equal signaling's +# SIGNALING_SERVER_SECRET below. -> openssl rand -hex 32 +SIGNALING_SECRET= + +# ๐Ÿ” JWT signing secret (auth + room tokens). -> openssl rand -hex 32 +JWT_SECRET= # ============================================================================= -# Stripe Configuration (use TEST keys for development) +# Stripe (๐Ÿงฉ stripe.com โ€” use TEST keys for development) # ============================================================================= -STRIPE_KEY=pk_test_xxx STRIPE_SECRET=sk_test_xxx STRIPE_WEBHOOK_SECRET=whsec_xxx - -# Stripe Price IDs -STRIPE_PRICE_STARTER_MONTHLY=price_xxx -STRIPE_PRICE_PROFESSIONAL_MONTHLY=price_xxx -STRIPE_PRICE_BUSINESS_MONTHLY=price_xxx +STRIPE_KEY=pk_test_xxx # publishable key (frontend) +# NOTE: per-plan price IDs are NOT env vars โ€” seed them into the `plans` table +# (see SUBSCRIPTIONS_AND_TIERS.md ยง2.3). # ============================================================================= -# Cloudflare R2 Storage +# Cloudflare R2 (๐Ÿงฉ object storage, S3-compatible) # ============================================================================= +R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com +R2_BUCKET=tradingroom-files R2_ACCESS_KEY_ID=your-access-key R2_SECRET_ACCESS_KEY=your-secret-key -R2_BUCKET=tradingroom-files -R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com -R2_PUBLIC_URL=https://files.tradingroom.io +R2_REGION=auto # ============================================================================= -# Redis Configuration +# Frontend (SvelteKit BFF) # ============================================================================= -REDIS_HOST=127.0.0.1 -REDIS_PORT=6379 -REDIS_PASSWORD=tradingroom_redis -REDIS_URL=redis://127.0.0.1:6379 +API_URL=http://localhost:8080 # server-side โ†’ Rust API +PUBLIC_SIGNALING_URL=ws://localhost:3000/ws # ============================================================================= -# Signaling Server +# Signaling server (Node) # ============================================================================= -SIGNALING_URL=http://localhost:3000 -SIGNALING_WS_URL=ws://localhost:3000/ws -SIGNALING_SECRET=your-signaling-secret SIGNALING_PORT=3000 +PORT=3000 # signaling listen port (container) +LOG_LEVEL=debug +# ๐Ÿ” Control-plane bearer protecting signaling /api/* โ€” set EQUAL to the API's +# SIGNALING_SECRET above, and reuse as the SFU's secret below. +SIGNALING_SERVER_SECRET= +# Split DB vars used by the signaling service (point at the same DB as DATABASE_URL). +DB_HOST=ep-xxx.region.aws.neon.tech +DB_NAME=neondb +DB_USER=your-neon-user +DB_PASSWORD=your-neon-password +DB_PORT=5432 +DB_SSL=true # ============================================================================= -# SFU Configuration +# Redis (self-hosted in compose, or ๐Ÿงฉ Upstash/Redis Cloud) +# ============================================================================= +REDIS_HOST=127.0.0.1 +REDIS_PORT=6379 +# ๐Ÿ” openssl rand -hex 16 +REDIS_PASSWORD= +REDIS_URL=redis://127.0.0.1:6379 + +# ============================================================================= +# SFU (mediasoup) โ€” runs with host networking; see docs/MEDIA_INFRASTRUCTURE.md # ============================================================================= SFU_NODE_ID=sfu-1 -# How signaling reaches the SFU control-plane (host:port). The SFU runs with -# host networking, so in production set this to the SFU box's reachable address -# (e.g. sfu1.:4000), not the bridge service name. +# How signaling reaches the SFU control-plane. In prod: sfu1.:4000 SFU_NODES=localhost:4000 -# The SFU host's PUBLIC IPv4 โ€” wired into the SFU as MEDIASOUP_ANNOUNCED_IP. -# Clients connect here for WebRTC media; must be a real public IP in production. +# ๐Ÿ–ฅ๏ธ The SFU host's PUBLIC IPv4 (โ†’ MEDIASOUP_ANNOUNCED_IP). Clients connect here +# for WebRTC media. Must be a real public IP in production. SFU_ANNOUNCED_IP=127.0.0.1 SFU_PORT=4000 - -# Mediasoup RTC media port range (UDP primary + TCP fallback). The SFU service -# in docker-compose pins MEDIASOUP_RTC_MIN_PORT/MAX_PORT to this window โ€” open it -# in the firewall on the SFU host. +# ๐Ÿ” SFU control-plane secret โ€” set EQUAL to SIGNALING_SERVER_SECRET. +SFU_SECRET= +# Mediasoup RTC media port range (UDP primary + TCP fallback) โ€” open in firewall. RTC_MIN_PORT=40000 RTC_MAX_PORT=49999 # ============================================================================= -# TURN Server Configuration +# TURN / STUN (coturn โ€” self-hosted in compose) # ============================================================================= TURN_SERVER_URL=turn:localhost:3478 +STUN_SERVER_URL=stun:localhost:3478 TURN_SERVER_USERNAME=tradingroom TURN_SERVER_CREDENTIAL=your-turn-password -STUN_SERVER_URL=stun:localhost:3478 - -# ============================================================================= -# CORS Configuration -# ============================================================================= -CORS_ORIGINS=http://localhost:5173,http://localhost:3000,http://localhost:8000 - -# ============================================================================= -# JWT Configuration -# ============================================================================= -JWT_SECRET=your-jwt-secret -JWT_EXPIRY=86400 - -# ============================================================================= -# Frontend URLs -# ============================================================================= -FRONTEND_URL=http://localhost:5173 -API_URL=http://localhost:8000 - -# ============================================================================= -# Logging & Monitoring -# ============================================================================= -LOG_LEVEL=debug -SENTRY_DSN= -SENTRY_ENVIRONMENT=development - -# ============================================================================= -# Email Configuration (Laravel) -# ============================================================================= -MAIL_MAILER=smtp -MAIL_HOST=smtp.mailgun.org -MAIL_PORT=587 -MAIL_USERNAME= -MAIL_PASSWORD= -MAIL_ENCRYPTION=tls -MAIL_FROM_ADDRESS=noreply@localhost -MAIL_FROM_NAME="Trading Room (Dev)" - -# ============================================================================= -# Queue Configuration (Laravel) -# ============================================================================= -QUEUE_CONNECTION=redis -HORIZON_PREFIX=tradingroom_horizon: - -# ============================================================================= -# Rate Limiting -# ============================================================================= -RATE_LIMIT_API=100 -RATE_LIMIT_AUTH=5 -RATE_LIMIT_WEBSOCKET=10 +# ๐Ÿ” coturn static-auth-secret (time-limited REST credentials). openssl rand -hex 32 +TURN_AUTH_SECRET= +# ๐Ÿ–ฅ๏ธ TURN host's PUBLIC IPv4 (coturn external-ip). +TURN_EXTERNAL_IP=127.0.0.1 # ============================================================================= -# Feature Flags +# Observability (โšช optional) # ============================================================================= -FEATURE_RECORDING=true -FEATURE_SCREEN_SHARE=true -FEATURE_CHAT=true -FEATURE_ALERTS=true +# OTEL_EXPORTER_OTLP_ENDPOINT=http://jaeger:4318 +# SENTRY_DSN=