# ============================================================================= # Mac Mini Production Environment # ============================================================================= # # Copy to .env.macmini (gitignored) and fill in the values. This file is # loaded by `docker compose -f docker-compose.macmini.yml ...` on the # Mac Mini host. The compose file references vars via ${VAR} (REQUIRED — # missing means container fails to start) and ${VAR:-default} (OPTIONAL # — falls back to the inline default if unset). # # Sections below mirror that split: # 1. REQUIRED — production deployment cannot boot without these # 2. OPTIONAL — defaults exist in compose; only set to override # # Verify the example covers every var the compose file uses: # grep -ohE '\$\{[A-Z_][A-Z0-9_]*' docker-compose.macmini.yml | sort -u # (audit baseline established 2026-04-08, see # docs/REFACTORING_AUDIT_2026_04.md item #9) # ============================================ # Compose project name (pinned, do not change) # ============================================ # All Mac Mini containers were originally created under this project # name, which mismatches the current directory name (mana-monorepo). # Pinning the project name here means anyone running 'docker compose ...' # from the repo root automatically lands in the same project as the # already-running containers, instead of silently spawning a duplicate # project with the same compose file. Removing this line WILL break # the next deployment. COMPOSE_PROJECT_NAME=manacore-monorepo # ============================================ # Database (PostgreSQL) # ============================================ POSTGRES_PASSWORD=your-secure-password-here # ============================================ # Redis # ============================================ REDIS_PASSWORD=your-redis-password-here # ============================================ # JWT Keys (generate with: openssl rand -base64 32) # For EdDSA keys, use mana-auth key generation # ============================================ JWT_SECRET=your-jwt-secret-here # Leave empty to use auto-generated keys JWT_PUBLIC_KEY= JWT_PRIVATE_KEY= # ============================================ # Encryption Vault Key Encryption Key (KEK) — REQUIRED # ============================================ # Wraps every user's master key in auth.encryption_vaults. # Generate with: openssl rand -base64 32 # # Without a real value, mana-auth boots with a 32-zero-byte fallback # and prints a loud warning every startup. Production must set this. # Treat it like a database root password — store as a Docker secret, # KMS-injected env var, or Vault-served value. # # Rotation requires planned downtime today (no background re-wrap job # yet). The kek_id column on encryption_vaults is reserved for the # future migration path. MANA_AUTH_KEK= # ============================================ # Supabase (optional, for legacy features) # ============================================ SUPABASE_URL= SUPABASE_SERVICE_ROLE_KEY= # ============================================ # Azure OpenAI (for Chat AI features) # ============================================ AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/ AZURE_OPENAI_API_KEY=your-api-key-here # ============================================ # Monitoring (Grafana) # ============================================ GRAFANA_PASSWORD=your-grafana-admin-password # ============================================ # Web Analytics (Umami) # ============================================ UMAMI_APP_SECRET=your-umami-secret-here # ============================================================================= # REQUIRED — production cannot boot without these # ============================================================================= # ─── Azure OpenAI ─────────────────────────────────────────── # Some compose entries reference ${AZURE_OPENAI_KEY} (no default), distinct # from the ${AZURE_OPENAI_API_KEY:-} above. Provide both — they may be the # same value or different keys depending on which deployment they hit. AZURE_OPENAI_KEY= AZURE_OPENAI_DEPLOYMENT= # ─── Azure Speech (mana-stt / mana-tts fallback) ──────────── # Four rotation keys + endpoint. Get from Azure Portal → Speech resource. AZURE_SPEECH_ENDPOINT= AZURE_SPEECH_KEY_1= AZURE_SPEECH_KEY_2= AZURE_SPEECH_KEY_3= AZURE_SPEECH_KEY_4= # ─── Azure Blob Storage (Memoro batch audio) ──────────────── AZURE_STORAGE_ACCOUNT_NAME= AZURE_STORAGE_ACCOUNT_KEY= # ─── Google Gemini ────────────────────────────────────────── # Used by mana-llm + several Gemini-Vision modules (planta, nutriphi). GEMINI_API_KEY= # ─── Service-to-service auth keys ─────────────────────────── # Shared secrets backends use to call each other without going through # user JWTs. Generate with: openssl rand -base64 32 # MANA_SERVICE_KEY appears in compose with BOTH a default and a no-default # reference, so it MUST be set to a real value in production. MANA_SERVICE_KEY= MANA_CREDITS_SERVICE_KEY= MEMORO_SERVICE_KEY= # ─── Memoro Supabase (legacy) ─────────────────────────────── # Memoro still keeps recording metadata in Supabase. Move to mana_platform # is tracked in the Memoro CLAUDE.md. MEMORO_SUPABASE_URL= MEMORO_SUPABASE_SERVICE_KEY= # ============================================================================= # OPTIONAL — defaults baked into docker-compose.macmini.yml # ============================================================================= # Only uncomment + set if you want to override the in-compose default. # Each line shows the default that ships in the compose file so you know # what you're overriding. # ─── Database / Cache (defaults are insecure!) ────────────── # POSTGRES_PASSWORD=devpassword # CHANGE for prod # REDIS_PASSWORD=redis123 # CHANGE for prod # ─── MinIO (defaults are insecure!) ───────────────────────── # MINIO_ACCESS_KEY=minioadmin # CHANGE for prod # MINIO_SECRET_KEY=minioadmin # CHANGE for prod # ─── Better Auth ──────────────────────────────────────────── # Default falls back to ${JWT_SECRET}. Override only if you want a # distinct session-signing key. # BETTER_AUTH_SECRET= # ─── LLM models ───────────────────────────────────────────── # MANA_LLM_API_KEY= # default empty (open llm.mana.how) # MANA_LLM_MODEL=ollama/gemma3:12b # OLLAMA_URL=http://host.docker.internal:13434 # OLLAMA_MODEL=gemma3:12b # ─── Third-party AI APIs (optional) ───────────────────────── # OPENROUTER_API_KEY= # GROQ_API_KEY= # GOOGLE_API_KEY= # TOGETHER_API_KEY= # ─── STT / TTS (defaults point to GPU box on LAN) ─────────── # STT_SERVICE_URL=http://192.168.178.11:3020 # TTS_SERVICE_URL=http://192.168.178.11:3022 # MANA_STT_API_KEY= # ─── Stripe (defaults empty — billing disabled if unset) ──── # STRIPE_SECRET_KEY= # STRIPE_CREDITS_WEBHOOK_SECRET= # STRIPE_SUBSCRIPTIONS_WEBHOOK_SECRET= # ─── Mail (Stalwart) — defaults work for the bundled stack ── # SMTP_HOST=stalwart # SMTP_PORT=587 # SMTP_USER=noreply # SMTP_PASSWORD=ManaNoReply2026! # CHANGE for prod # STALWART_ADMIN_PASSWORD=ChangeMe123! # CHANGE for prod # ─── Search (SearXNG) ─────────────────────────────────────── # SEARXNG_SECRET=change-me-searxng-secret # ─── Error tracking (GlitchTip / Sentry) ──────────────────── # GLITCHTIP_DSN_MANA_WEB= # GLITCHTIP_SECRET_KEY=change-me-in-production # ─── Notifications ────────────────────────────────────────── # NTFY_TOPIC= # TELEGRAM_BOT_TOKEN= # TELEGRAM_CHAT_ID= # ─── Cloudflare (only if deploying landings via wrangler) ─── # CLOUDFLARE_ACCOUNT_ID= # CLOUDFLARE_API_TOKEN= # EXPO_ACCESS_TOKEN= # ─── Admin / abuse limits ─────────────────────────────────── # ADMIN_USER_IDS= # comma-separated user IDs # MAX_DAILY_SIGNUPS=0 # 0 = unlimited # ─── Misc ─────────────────────────────────────────────────── # AZURE_OPENAI_API_VERSION= # AZURE_STORAGE_CONTAINER=memoro-batch-audio # AZURE_SPEECH_REGION=germanywestcentral