This document describes all environment variables used in the in–midst–my–life system.
.env.production.example to .env.productionpnpm validate-envdocker-compose upType: String (PostgreSQL connection string)
Required: Yes
Example: postgresql://user:password@db-host:5432/midst_prod
Description: Primary PostgreSQL database connection. Used by both API and Orchestrator for profile storage, subscriptions, rate limits, and task queue.
How to obtain:
postgresql://username:password@hostname:port/database_nameSecurity:
?sslmode=require)Type: String Required: No (deprecated, use DATABASE_URL) Example: Same as DATABASE_URL
Description: Kept for backwards compatibility with older API versions. If not set, falls back to DATABASE_URL.
Type: String (Redis connection URL)
Required: Yes
Example: redis://:password@redis-host:6379/0
Description: Redis connection for caching and task queue. Used by Orchestrator for background job processing and API for session/quota caching.
How to obtain:
redis://[:password@]hostname:port/database_numberSecurity:
: )Type: String (Stripe live secret key)
Required: Yes
Example: sk_live_abc123def456...
Description: Stripe live API secret key for processing payments. Only use in production.
How to obtain:
sk_live_)Security:
Type: String (Webhook signing secret)
Required: Yes
Example: whsec_live_abc123...
Description: Secret key for verifying Stripe webhook signatures. Prevents spoofed webhook events.
How to obtain:
https://yourdomain.com/webhooks/stripewhsec_live_)Security:
Type: String (Stripe price IDs)
Required: Yes (for each plan)
Example: price_1Lb7abLBSRqDXZG30a7Xq9Jk
Description: Price IDs for each subscription tier and billing interval.
How to obtain:
price_)Note: Must match tier names in code (FREE, PRO, ENTERPRISE)
Type: String (256-bit hex)
Required: Yes
Example: a1b2c3d4e5f6g7h8... (64 hex chars)
Description: Secret key for signing JWT authentication tokens.
How to generate:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Security:
Type: String (256-bit hex) Required: Yes Example: Same format as JWT_SECRET
Description: Encryption key for sensitive profile data at rest. Used for data that should never be visible to admins (personal info, salary, etc.).
How to generate: Same as JWT_SECRET
Type: String (256-bit hex) Required: Yes Example: Same format as JWT_SECRET
Description: Secret for signing secure cookies in Next.js frontend.
How to generate: Same as JWT_SECRET
Type: String (comma-separated URLs)
Required: Yes
Example: https://app.yourdomain.com,https://yourdomain.com
Description: Domains allowed to make cross-origin requests to API. Prevents unauthorized sites from accessing your API.
For different environments:
http://localhost:3000,http://localhost:3001https://staging-app.yourdomain.comhttps://app.yourdomain.com,https://yourdomain.comSecurity:
Type: String (development | staging | production) Required: Yes Default: development
Description: Environment mode. Affects error reporting, logging, and feature availability.
Type: String (full URL) Required: Yes Examples:
https://api.yourdomain.comhttps://app.yourdomain.comDescription: Base URLs for API and frontend. Used in redirects, email links, etc.
Type: String (Sentry DSN URL)
Required: Optional
Example: https://abc123def456@sentry.io/project-id
Description: Sentry error tracking URL. If not provided, errors are logged locally only.
How to obtain:
Type: String (trace | debug | info | warn | error | fatal) Required: No Default: info
Description: Minimum log level to output. Production should be info or warn.
Type: Boolean (true | false) Required: No Default: true
Description: Enable/disable Hunter Protocol job search features. Set to false to disable feature during maintenance.
Type: Number Required: No Default: 3001
Description: Port the Fastify API server listens on.
Type: Number Required: No Default: 9464
Description: Port for the Prometheus metrics endpoint (separate from the main API port).
Type: String
Required: No (falls back to mock)
Example: sk-...
Description:
OpenAI API key for semantic search embeddings. If not set or set to
sk-test-mock, the API uses a mock embeddings provider.
Type: String (URL)
Required: No
Default: http://localhost:3002
Description: URL of the orchestrator worker service. Used by the API when building narrative output to delegate tasks.
Type: String Required: No Default: Same as NODE_ENV
Description: Environment label sent to Sentry. Useful for distinguishing staging vs production in the Sentry dashboard.
Type: String (URL)
Required: No
Example: http://localhost:4318
Description: OpenTelemetry collector endpoint for distributed tracing. If not set, tracing data is not exported.
The orchestrator (apps/orchestrator) has its own comprehensive set of
environment variables, validated via Zod in src/config.ts.
Type: String
Required: No
Default: 0.0.0.0
Description: Host address the orchestrator binds to.
Type: Number Required: No Default: 4000 (falls back to PORT if set)
Description: Port the orchestrator HTTP server listens on.
Type: Boolean Required: No Default: false
Description: Enable local LLM API integration. When true, the orchestrator sends prompts to a local LLM server instead of cloud providers.
Type: String (URL)
Required: No
Default: http://localhost:11434
Description: URL of the local LLM server (e.g., Ollama, llama.cpp server).
Type: String
Required: No
Default: mistral
Description: Model name/tag to use with the local LLM server.
Type: String (oss | hosted | locked)
Required: No
Default: oss
Description:
LLM usage policy. oss allows only open-source models, hosted allows
cloud providers, locked disables all LLM calls.
Type: Boolean Required: No Default: false
Description: Enable the periodic task scheduler. When true, the orchestrator automatically creates and runs scheduled tasks.
Type: Number (milliseconds) Required: No Default: 60000
Description: Rate limiting window duration for orchestrator API endpoints.
Type: Number Required: No Default: 100
Description: Maximum requests per rate limit window for orchestrator endpoints.
Check environment before deployment:
pnpm validate-env
This script verifies:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/midst_dev
REDIS_URL=redis://localhost:6379/0
NODE_ENV=development
JWT_SECRET=dev_secret_do_not_use_in_production
# Stripe: use test keys (sk_test_...)
DATABASE_URL=postgresql://user:pass@staging-db.example.com:5432/midst_staging
REDIS_URL=redis://staging-redis.example.com:6379/0
NODE_ENV=production
SENTRY_DSN=https://...@sentry.io/staging-project
# Stripe: use test keys (sk_test_...)
DATABASE_URL=postgresql://user:pass@prod-db.example.com:5432/midst_prod
REDIS_URL=redis://prod-redis.example.com:6379/0
NODE_ENV=production
SENTRY_DSN=https://...@sentry.io/prod-project
# Stripe: use live keys (sk_live_...)
.env.*.example files (templates).env or .env.production files