Quickstart
This page is dual-purpose. Read it top-to-bottom yourself, or select the whole page, copy it, and paste it into your AI assistant (Claude Code, Claude Desktop, ChatGPT, Cursor, Gemini CLI). The steps are written as imperatives it can execute in order.
Prereqs: Docker Engine 24+, ~4 GB RAM free, a domain pointing at the host (only if you want TLS at the end; localhost trials skip this).
1. Clone the repo
Section titled “1. Clone the repo”git clone https://github.com/engram-app/Engram.gitcd Engram2. Copy the env example and generate the three secrets
Section titled “2. Copy the env example and generate the three secrets”cp .env.example .envOpen .env and fill in these three values, each generated with the
command shown. Don’t skip this step. The app will fail to boot
without them.
# Generate, then paste into .env:openssl rand -base64 48 # → SECRET_KEY_BASEopenssl rand -base64 48 # → JWT_SECRETopenssl rand -base64 32 # → ENCRYPTION_MASTER_KEYIf you’re trialing on localhost (no domain, no TLS yet), also append
these two lines to .env so the app’s advertised URLs match where it
actually listens:
PHX_SCHEME=httpPHX_PORT=4000For a production install with a domain, leave the two lines above
unset (the release defaults to https / 443, which is correct when
you put a TLS-terminating reverse proxy in front, see step 4) and
instead set:
PHX_HOST=engram.example.com3. Bring the stack up
Section titled “3. Bring the stack up”docker compose up -d --buildFirst build compiles the Engram release (a few minutes). On first
boot the bundled Ollama service also pulls the nomic-embed-text
model, which can take a few minutes depending on bandwidth. Subsequent
boots are instant.
The default stack starts five containers: Engram, Postgres, Qdrant
(vector store), Ollama (local embeddings), and a one-shot
ollama-init job that pulls the model. Only port 4000 is exposed to
the host; everything else stays on the private Docker network.
Verify it’s healthy:
docker compose pscurl -sf http://localhost:4000/api/health && echo OKYou should see engram healthy, postgres healthy, qdrant running,
ollama healthy, ollama-init exited(0), and the health endpoint
returns a JSON OK. If any service is unhealthy or the curl returns
non-200, stop here and triage. docker compose logs engram shows
boot output. Common issues: port 4000 already in use, Docker daemon
not running, or the OS didn’t allocate enough memory.
Optional: enable MinIO/S3 for large vaults
Section titled “Optional: enable MinIO/S3 for large vaults”The default stack stores attachments as Postgres bytea. Use that
unless 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 / R2 / etc.)
To switch: in .env set STORAGE_BACKEND=s3 and uncomment the four
STORAGE_* rows, then bring the stack up with the s3 profile so
the bundled MinIO container runs:
docker compose --profile s3 up -dSee Storage for the detail.
Optional: switch to Voyage AI for better embedding quality
Section titled “Optional: switch to Voyage AI for better embedding quality”The default uses local Ollama (no API key, runs in-stack). To swap to
Voyage AI (managed, paid, sign up at
voyageai.com): in .env set
EMBED_BACKEND=voyage plus EMBED_MODEL=voyage-4-large, EMBED_DIMS=1024,
and VOYAGE_API_KEY=.... No compose profile change needed. See
Embeddings.
4. Reverse proxy + TLS (skip on localhost)
Section titled “4. Reverse proxy + TLS (skip on localhost)”Engram doesn’t terminate TLS. For a production install put Caddy, Nginx, nginx-proxy-manager, or any reverse proxy you already run in front of port 4000.
Caddy example (/etc/caddy/Caddyfile):
engram.example.com { reverse_proxy localhost:4000}Reload Caddy. TLS provisions automatically from Let’s Encrypt.
5. Create your first user
Section titled “5. Create your first user”When PADDLE_API_KEY is unset (self-host mode), Engram’s onboarding
wizard short-circuits and signup works in-app:
- Visit
https://engram.example.com(orhttp://localhost:4000for the localhost trial) in a browser. - Use the Sign up form.
POST /api/auth/register(email + password) creates the user via the local auth provider. - The first user to sign up becomes admin and can mint invites for additional users from the admin settings.
- Log in; the vault opens directly without the billing/onboarding gate.
The default registration mode is open in .env.example so you can
sign yourself up. Tighten later via
ENGRAM_DEFAULT_REGISTRATION_MODE=invite_only (or closed) once
you’ve created the accounts you want.
If you’d rather create users out-of-band, an IEx shell also works:
docker compose exec engram bin/engram remote{:ok, user} = Engram.Accounts.create_user_with_password( "you@example.com", "a strong passphrase")6. Point Obsidian at your instance
Section titled “6. Point Obsidian at your instance”Install Engram Vault Sync in Obsidian (via BRAT), then:
Settings → Engram Vault Sync → Server URL →
https://engram.example.com (or http://localhost:4000). Sign in
with the account you just created. Push your vault. Done.
Now what?
Section titled “Now what?”Verify the install is fully working by creating a note in Obsidian
and waiting ~10 seconds for it to appear in the web UI at
/notes. That round-trip exercises the sync, the embedding queue,
and the vector store.
Then:
- Connect your AI assistant via MCP, the highest-value thing you can do with Engram.
- Encryption Setup to back up the master key properly and plan rotation.
- Backup & Restore covers what to dump and where to put it.
- Upgrade Path for bumping versions safely.
If anything above failed and you’re stuck, see Troubleshooting.