# ============================================================================= # Mnemosyne — docker compose interpolation template # ============================================================================= # This file is consumed by `docker compose` as the source for `${VAR}` # interpolations in docker-compose.yaml. In production it is generated from # a Jinja2 template by an Ansible role, with secrets pulled from the Ansible # vault — do not commit a populated copy. # # Copy to `.env` (at the repo root, NOT inside `mnemosyne/`) and fill in the # blanks before running `docker compose up -d`. The in-tree `mnemosyne/.env` # file (used by bare-Python development on caliban) is a separate concern # and is NOT read by the compose stack. # # Every variable below is referenced by at least one service in # docker-compose.yaml. Per-service scoping (which container sees which var) # is defined by the `environment:` blocks in that file; this template just # provides the values. # ============================================================================= # --- Django core ------------------------------------------------------------ # Consumed by: app, mcp, worker SECRET_KEY=change-me-to-a-real-secret-key DEBUG=False TIME_ZONE=UTC LANGUAGE_CODE=en-us # --- HTTP surface ----------------------------------------------------------- # Consumed by: app (CSRF_TRUSTED_ORIGINS: app only; ALLOWED_HOSTS: app + mcp) # Include every hostname HAProxy routes to this stack, plus localhost for the # inter-container health probes. ALLOWED_HOSTS=localhost,127.0.0.1,mnemosyne.ouranos.helu.ca CSRF_TRUSTED_ORIGINS=https://mnemosyne.ouranos.helu.ca # --- PostgreSQL (Portia) ---------------------------------------------------- # Consumed by: app, mcp, worker APP_DB_NAME=mnemosyne APP_DB_USER=mnemosyne APP_DB_PASSWORD=change-me DB_HOST=portia.incus DB_PORT=5432 # --- Neo4j (Umbriel — dedicated Mnemosyne instance) ------------------------- # Consumed by: app, mcp, worker # Umbriel MUST be dedicated to Mnemosyne; do not share with Spelunker or any # other graph workload. See README.md for the full rationale. NEOMODEL_NEO4J_BOLT_URL=bolt://neo4j:change-me@umbriel.incus:7687 # --- Memcached -------------------------------------------------------------- # Consumed by: app, mcp, worker # Must resolve from inside containers — 127.0.0.1 will NOT work. KVDB_LOCATION=oberon.incus:11211 KVDB_PREFIX=mnemosyne # --- S3 / MinIO (Nyx) — Mnemosyne's own bucket ------------------------------ # Consumed by: app, mcp, worker # Mnemosyne writes chunk text and item files here. Set USE_LOCAL_STORAGE=False # in production so the S3Boto3Storage backend is used instead of the local # FileSystemStorage fallback. USE_LOCAL_STORAGE=False AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_STORAGE_BUCKET_NAME=mnemosyne-content AWS_S3_ENDPOINT_URL=https://nyx.helu.ca:8555 AWS_S3_USE_SSL=True AWS_S3_VERIFY=False AWS_S3_REGION_NAME=us-east-1 # --- Daedalus S3 (cross-bucket reads for ingest) ---------------------------- # Consumed by: worker only # Mnemosyne's ingest Celery task reads files from Daedalus's bucket and # copies them into AWS_STORAGE_BUCKET_NAME for processing. These creds # should be scoped read-only to the Daedalus bucket in your secret manager. DAEDALUS_S3_ENDPOINT_URL=https://nyx.helu.ca:8555 DAEDALUS_S3_ACCESS_KEY_ID= DAEDALUS_S3_SECRET_ACCESS_KEY= DAEDALUS_S3_BUCKET_NAME=daedalus DAEDALUS_S3_REGION_NAME=us-east-1 DAEDALUS_S3_USE_SSL=True DAEDALUS_S3_VERIFY=True # --- Celery / RabbitMQ (Oberon) --------------------------------------------- # Consumed by: app (producer), worker (consumer). NOT mcp. # Remember to percent-encode any password characters that have meaning in a # URL (`@ : / # % + ? & =` and space). Kombu's AMQP URL parser is strict — # an unencoded password is the most common cause of PLAIN 403 failures when # the bare-Python client happens to connect fine. CELERY_BROKER_URL=amqp://mnemosyne:change-me@oberon.incus:5672/mnemosyne CELERY_RESULT_BACKEND=rpc:// CELERY_TASK_ALWAYS_EAGER=False # --- Worker tuning --------------------------------------------------------- # Consumed by: worker only (read by entrypoint.sh → `celery -A mnemosyne worker`) # Override per host if you want to dedicate a worker to a single queue. CELERY_QUEUES=celery,embedding,batch CELERY_CONCURRENCY=2 # --- MCP server ------------------------------------------------------------- # Consumed by: mcp only MCP_REQUIRE_AUTH=True # --- LLM API encryption ----------------------------------------------------- # Consumed by: app (admin pages), worker (ingest vision pass). NOT mcp. # Generate once per deployment, store in the vault, never rotate without # re-encrypting every stored provider key first. # python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" LLM_API_SECRETS_ENCRYPTION_KEY= # --- Email (smtp4dev on Oberon) -------------------------------------------- # Consumed by: app only EMAIL_HOST=oberon.incus EMAIL_PORT=22025 EMAIL_USE_TLS=False # --- Embedding pipeline ----------------------------------------------------- # Consumed by: worker only EMBEDDING_BATCH_SIZE=8 EMBEDDING_TIMEOUT=120 # --- Search & re-ranker ----------------------------------------------------- # Consumed by: app, mcp. Not worker (workers never serve queries). SEARCH_VECTOR_TOP_K=50 SEARCH_FULLTEXT_TOP_K=30 SEARCH_GRAPH_MAX_DEPTH=2 SEARCH_RRF_K=60 SEARCH_DEFAULT_LIMIT=20 RERANKER_MAX_CANDIDATES=32 RERANKER_TIMEOUT=30 # --- Logging ---------------------------------------------------------------- # Consumed by: app, mcp, worker (each picks the levels it cares about) LOGGING_LEVEL=INFO CELERY_LOGGING_LEVEL=INFO DJANGO_LOGGING_LEVEL=WARNING