managarten/.env.macmini.example
Till JS 919fcca4b7 refactor(shared-tailwind): rewrite themes.css to single-layer shadcn convention
Pre-launch theme system audit found multiple parallel layers in themes.css
(--theme-X full hsl strings, --X partial shadcn aliases, --color-X populated
by runtime store with raw channels) plus dead-code companion files. The
inconsistency caused light-mode regressions when scoped-CSS consumers
wrote `var(--color-X)` standalone — the variable holds raw HSL channels
which is invalid as a color value, browser fell back to inherited (white).

Rewrite to one consistent layer:

  - Source of truth: --color-X defined as raw HSL channels (e.g.
    `0 0% 17%`) in :root, .dark, and all variant [data-theme="..."]
    blocks. Matches the format the runtime store
    (@mana/shared-theme/src/utils.ts) writes, eliminating the
    static-fallback-vs-runtime mismatch and the corresponding flash
    of unstyled content on hydration.

  - @theme inline uses self-reference + Tailwind v4 <alpha-value>
    placeholder so utility classes generate correctly AND opacity
    modifiers work: `text-foreground/50` → `hsl(var(--color-foreground) / 0.5)`.

  - @layer components (.btn-primary, .card, .badge, etc.) wraps
    var(--color-X) refs with hsl() — they were broken in light mode
    too for the same reason.

Convention going forward (also documented in the file header):

  1. Markup: use Tailwind utility classes (text-foreground, bg-card, …)
  2. Scoped CSS: hsl(var(--color-X)) — always wrap with hsl()
  3. NEVER raw var(--color-X) in CSS — that's the bug pattern

Net file: 692 → 580 LOC. Single source layer, no indirection.

Also delete dead companion files (zero imports anywhere):
  - tailwind-v4.css (had broken self-reference, never imported)
  - theme-variables.css (legacy hex-based palette)
  - components.css (legacy component utilities)
  - index.js / preset.js / colors.js (Tailwind v3 preset format,
    irrelevant under Tailwind v4)

package.json exports map shrinks accordingly to just `./themes.css`.

Consumers using `hsl(var(--color-X))` (~379 files across mana-web,
manavoxel-web, arcade-web) keep working unchanged — the public API
name `--color-X` is preserved. Only the broken pattern `var(--color-X)`
(~61 files) needs a follow-up sweep, handled in a separate commit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 01:13:06 +02:00

204 lines
9 KiB
Text

# =============================================================================
# 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