docs(env): expand .env.example into full compose interpolation template
Replace the minimal placeholder .env.example with a comprehensive template documenting every variable consumed by docker-compose.yaml, organized by service (Django core, HTTP, Postgres, Neo4j, Memcached, S3/MinIO, Daedalus, Celery/RabbitMQ, etc.). Clarifies that this file is rendered from an Ansible Jinja2 template with vaulted secrets in production, and distinguishes it from the in-tree mnemosyne/.env used for bare-Python development.
This commit is contained in:
136
.env.example
136
.env.example
@@ -1,13 +1,133 @@
|
||||
# =============================================================================
|
||||
# Mnemosyne — Docker Compose environment
|
||||
# Mnemosyne — docker compose interpolation template
|
||||
# =============================================================================
|
||||
# This file documents variables consumed by docker-compose.yaml itself
|
||||
# (image tags, port overrides, etc.). It is NOT the application config.
|
||||
# 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.
|
||||
#
|
||||
# Application config lives in mnemosyne/.env — copy mnemosyne/.env\ example
|
||||
# to mnemosyne/.env and fill in your values before running `docker compose up`.
|
||||
# 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.
|
||||
#
|
||||
# This file has no required variables for a default deployment: the compose
|
||||
# file uses a fixed image tag and port. Add overrides here if you parameterise
|
||||
# those in docker-compose.yaml (e.g. MNEMOSYNE_IMAGE, MNEMOSYNE_PORT).
|
||||
# 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
|
||||
|
||||
Reference in New Issue
Block a user