Environment Variables
Required
Section titled “Required”| Var | What it does |
|---|---|
PHX_HOST | Public hostname (e.g. engram.example.com). Used for URL generation, CORS, and WebSocket allowlists. Comma-separated for multi-host. |
SECRET_KEY_BASE | Phoenix cookie/session signing. Generate with openssl rand -base64 48. |
JWT_SECRET | Internal JWT signing (auth + refresh tokens). Generate with openssl rand -base64 48. |
ENCRYPTION_MASTER_KEY | Wraps per-user DEKs. Losing this = data loss. 32-byte base64. Full encryption-related env reference under Encryption below. |
STORAGE_BACKEND | database (attachments stored in Postgres bytea, no MinIO container) or s3 (S3-compatible object store via the bundled MinIO container, which needs docker compose --profile s3 up, or any external S3 provider). The backend code default is s3 (runtime.exs); the shipped self-host lite stack stores attachments in Postgres and sets STORAGE_BACKEND=database explicitly in its .env. Full picker under Storage below. |
DATABASE_URL is also required, but the shipped Compose stacks wire it
internally (postgresql://engram:engram@postgres:5432/engram). If
you’re running Engram against an external Postgres, set it yourself.
Embeddings
Section titled “Embeddings”Default: local Ollama, no API key, runs in the bundled Compose stack
(the ollama-init service pulls nomic-embed-text on first up).
Switch to Voyage AI when you want managed embeddings with stronger
retrieval quality and don’t mind outbound HTTP to api.voyageai.com
(paid; sign up at voyageai.com). Set EMBED_BACKEND=voyage
plus the four EMBED_* / VOYAGE_API_KEY lines below in .env. No
compose-profile change needed.
| Var | What it does |
|---|---|
EMBED_BACKEND | ollama or voyage. Self-host should set to ollama (in-stack, no API key needed). voyage requires a Voyage account. |
EMBED_MODEL | Override the default model. For Ollama, defaults to nomic-embed-text (768 dims). For Voyage, defaults to voyage-4-large (1024 dims). |
EMBED_DIMS | Embedding dimension count. Must match the model: 768 for nomic-embed-text, 1024 for voyage-4-large. Swapping a dimension on an existing instance requires a Qdrant re-index. |
OLLAMA_URL | Ollama HTTP endpoint. Default http://localhost:11434. Compose stacks set this to http://ollama:11434. |
VOYAGE_API_KEY | Required when EMBED_BACKEND=voyage. Get one from voyageai.com. |
DOC_EMBED_MODEL / QUERY_EMBED_MODEL | Optional asymmetric retrieval, using different models for documents vs queries (Voyage-specific). |
Storage
Section titled “Storage”Self-host lite default: STORAGE_BACKEND=database, with attachments stored as
Postgres bytea. No MinIO container in the lite Compose stack. Good for most
self-host vaults. (Note: the backend code default is s3, while the lite stack’s .env
sets database explicitly, so don’t assume it’s set just because you’re self-hosting.)
Switch to MinIO / S3 when any of:
- A single attachment will exceed ~50 MB (videos, big PDFs)
- Total attachment storage will exceed ~10 GB
- You want to point Engram at an existing S3 bucket (AWS / Cloudflare R2 / etc.)
To switch: in .env set STORAGE_BACKEND=s3 plus the four
STORAGE_* credentials rows in the table below, then bring the stack up with
the s3 profile so the bundled MinIO container runs:
docker compose --profile s3 up -dBackup note: bytea mode bundles attachments into every Postgres
dump (simple, but dumps balloon as your vault grows). MinIO/S3 mode
needs its own backup (e.g. mc mirror or bucket replication) on top of
your Postgres dumps.
S3 variables
Section titled “S3 variables”Used when STORAGE_BACKEND=s3. Unused (and ignored) when
STORAGE_BACKEND=database.
| Var | What it does |
|---|---|
STORAGE_BUCKET | Bucket name for attachments. Default engram-attachments. |
STORAGE_REGION | S3 region. Required for AWS, ignored by MinIO. |
STORAGE_ACCESS_KEY_ID | S3 access key. Default minioadmin matches the bundled MinIO root user. |
STORAGE_SECRET_ACCESS_KEY | S3 secret. Default minioadmin matches the bundled MinIO root password. |
STORAGE_SCHEME | HTTP scheme for the S3 endpoint, e.g. http://. Compose sets this internally for MinIO. |
STORAGE_HOST | S3 hostname, e.g. minio. Compose sets this internally for the bundled MinIO service. |
STORAGE_PORT | S3 port, e.g. 9000. Compose sets this internally. |
For AWS-native S3 leave STORAGE_SCHEME / STORAGE_HOST / STORAGE_PORT
unset. ex_aws will use its default regional endpoint and (on ECS)
fall back to the task role for credentials.
Qdrant
Section titled “Qdrant”| Var | What it does |
|---|---|
QDRANT_URL | Qdrant HTTP endpoint. Default http://qdrant:6333 (matches the bundled service name). |
QDRANT_COLLECTION | Collection name. Default obsidian_notes. |
QDRANT_API_KEY | API key if Qdrant has auth on. |
QDRANT_BINARY_QUANTIZATION | Default on. Set false on CPUs without AVX2 support. |
Auth (self-host)
Section titled “Auth (self-host)”| Var | What it does |
|---|---|
AUTH_PROVIDER | local for self-host (built-in email/password). Cloud uses clerk. |
ENGRAM_DEFAULT_REGISTRATION_MODE | open, invite_only (default), or closed. invite_only requires the first signup to be the admin and subsequent users to use an invite token. Set to open for public instances. |
Observability
Section titled “Observability”| Var | What it does |
|---|---|
SENTRY_DSN | If set, backend errors stream to Sentry. |
Encryption
Section titled “Encryption”ENCRYPTION_MASTER_KEY is listed under Required above.
The rest of the encryption-related env lives here.
| Var | What it does |
|---|---|
ENCRYPTION_MASTER_KEY_PREVIOUS | Rescue lane during master-key rotation. Unset after rotation completes. |
ENCRYPTION_MASTER_KEY_VERSION | Default 1. Bump during rotation (see Encryption Setup). |
DEK_CACHE_TTL_MS | DEK cache TTL in ms. Default 3600000 (1 hour). |
KEY_PROVIDER | local (default) or aws_kms. AWS KMS provider is operator-only today; see backend repo. |
BOOT_CANARY_ENABLED | false disables the boot canary check. Leave default unless you know why. |
Phoenix host / scheme
Section titled “Phoenix host / scheme”| Var | What it does |
|---|---|
PHX_HOST | Public hostname (e.g. engram.example.com). Used for URL generation. Listed under Required. |
PHX_SCHEME | https in prod (default for releases), http for plain-HTTP localhost trials. |
PHX_PORT | Default 443 in prod, 80 in dev. Set explicitly when running behind a reverse proxy on a non-standard port. |
PHX_SERVER | Set to true to enable the HTTP server in release mode. The shipped Compose stacks set this. |
Billing (cloud only)
Section titled “Billing (cloud only)”PADDLE_API_KEY, PADDLE_NOTIFICATION_SECRET, PADDLE_CLIENT_TOKEN,
PADDLE_STARTER_MONTHLY_PRICE_ID, PADDLE_STARTER_ANNUAL_PRICE_ID,
PADDLE_PRO_MONTHLY_PRICE_ID, PADDLE_PRO_ANNUAL_PRICE_ID,
PADDLE_ENV are all unset on self-host. When PADDLE_API_KEY is
missing the billing plumbing short-circuits cleanly (no onboarding
gate, no subscription checks).