Install and configure Optimal Engine

This page covers a self-hosted Engine. A managed Engine on MIOSA is set up for you; see Optimal Engine on MIOSA.

Requirements

NeedVersion or note
Erlang/OTP27 or newer. Avoid OTP 28.0 to 28.2; the Docker image uses 28.5.
Elixir1.17 or newer
Build toolsgit, a C toolchain, CMake. The image also installs zlib, zstd, lz4, bz2, snappy, and SQLite headers.
macOSbrew install snappy
Embeddings (optional)Ollama with nomic-embed-text, or any OpenAI-compatible embeddings endpoint
Media parsing (optional)pdftotext for PDF, tesseract for image text, ffmpeg for video, a whisper.cpp server for audio

Without an embedding model the Engine still works: search is full-text only, and a backfill embeds everything once a model is set up. Without a media tool, a file of that kind is stored with its metadata and a warning instead of its text.

Install

From a checkout

git clone https://github.com/Miosa-osa/OptimalEngine.git
cd OptimalEngine
mix deps.get
mix optimal.auth mint --name "root" --workspace '*'
OPTIMAL_API_ENABLED=true OPTIMAL_AUTH_REQUIRED=true mix run --no-halt

make bootstrap (or mix optimal.bootstrap) compiles, runs migrations, and loads the bundled sample-workspace/ so you have data to try.

With Docker

deploy/Dockerfile.engine builds an OTP release on Elixir 1.19.5 and OTP 28.5.

Image defaultValue
Useroptimal, UID 1000, not root
Data/data, the only volume. The database is /data/.optimal/index.db.
Port4200, bound to 0.0.0.0 inside the container
APIOn, with keys required (OPTIMAL_AUTH_REQUIRED=true)
EmbeddingsOLLAMA_HOST=http://host.docker.internal:11434
Health checkGET /api/health with Authorization: Bearer $OPTIMAL_ENGINE_API_KEY

Set OPTIMAL_ENGINE_API_KEY on the container, or the health check runs without a key and the container reports unhealthy. On Linux, host.docker.internal does not resolve by default; point OLLAMA_HOST at the host’s address.

With Docker Compose

cd deploy
cp env.example .env
# Set OPTIMAL_BOOTSTRAP_KEY and OPTIMAL_ENGINE_API_KEY to the same oe_ key.
docker compose up --build

Compose publishes the Engine on 127.0.0.1:4200 and keeps data in the optimal_data volume. For a public server, add the production overlay, which puts Caddy with automatic TLS in front and keeps the Engine port private:

docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Set DOMAIN and LETSENCRYPT_EMAIL in .env first.

As a release

MIX_ENV=prod mix release optimal
OPTIMAL_API_ENABLED=true OPTIMAL_AUTH_REQUIRED=true _build/prod/rel/optimal/bin/optimal start

bin/optimal maintenance <task> runs maintenance with the API off; see Operations.

Settings

The Engine reads its settings from environment variables at boot. An invalid value stops the boot with a message that names the variable.

Server and keys

VariableDefaultWhat it does
OPTIMAL_API_ENABLEDoff (image: on)Only the value true starts the HTTP API
OPTIMAL_API_PORT4200Port
OPTIMAL_API_INTERFACE127.0.0.1 (image: 0.0.0.0)Address to bind
OPTIMAL_AUTH_REQUIREDfalse (image: true)Require an API key on every request. Takes true or false only.
OPTIMAL_BOOTSTRAP_KEYnoneRegisters a first key at boot, in the form oe_<24 hex>_<secret of 32+ characters>. Changing it rotates the key.
OPTIMAL_BOOTSTRAP_SCOPESread,writeScopes of the bootstrap key
OPTIMAL_BOOTSTRAP_WORKSPACES*Workspaces of the bootstrap key
OPTIMAL_BOOTSTRAP_TENANTdefaultTenant of the bootstrap key
OPTIMAL_REFUSE_OPEN_NETWORKoffRefuse to start when bound beyond loopback with keys off
OPTIMAL_OPEN_NETWORK_ACKNOWLEDGEDoffYou run keys-off behind a proxy that authenticates every request
OPTIMAL_SIZE_PROFILEbusinessSize profile; see Operations

Paths and storage

VariableDefaultWhat it does
OPTIMAL_ENGINE_ROOTthe working directory (image: /data)Root of the workspace folders
OPTIMAL_ENGINE_DB.optimal/index.dbSQLite database file
OPTIMAL_ENGINE_CACHE.optimal/cacheCache, including stored embeddings
OPTIMAL_BACKUP_DIRbackups/ next to the databaseWhere backups are written
OPTIMAL_KNOWLEDGE_BACKENDetsGraph projection: ets in memory, or rocksdb on disk
OPTIMAL_ASSET_STORAGEfilesystems3 keeps uploaded file bytes in S3-compatible storage
OPTIMAL_S3_ENDPOINT, OPTIMAL_S3_BUCKET, OPTIMAL_S3_ACCESS_KEY_ID, OPTIMAL_S3_SECRET_ACCESS_KEYnoneS3, MinIO, R2, or Garage. Also OPTIMAL_S3_REGION (us-east-1) and OPTIMAL_S3_PREFIX.

Secrets

Each is 64 hex characters; generate one with openssl rand -hex 32.

VariableNeeded when
CONNECTOR_KEYYou set up app connectors or replication peers. It encrypts their stored keys.
OPTIMAL_AUTHORITY_KEYRecommended always. It protects the signing keys of authority grants.
OPTIMAL_BACKUP_KEYYou send backups offsite. It encrypts them.

Embeddings

VariableDefaultWhat it does
OLLAMA_HOSThttp://localhost:11434Ollama server
OPTIMAL_EMBED_MODELnomic-embed-textEmbedding model, 768 dimensions
OPTIMAL_EMBED_URLnoneAnother endpoint. A path ending in /api/embed speaks Ollama; anything else speaks OpenAI /v1/embeddings.
OPTIMAL_EMBED_DIMENSIONS768Vector size of that model
OPTIMAL_EMBED_API_KEY or OPTIMAL_EMBED_API_KEY_FILEnoneKey for that endpoint, read per request and never stored
OPTIMAL_GENERATE_MODELqwen3:1.7bSmall model used to curate wiki pages and summarize sessions
OPTIMAL_VLM_MODELqwen2.5-vlVision model that describes images

Behavior

VariableDefaultWhat it does
OPTIMAL_CLAIM_PROMOTION_MODEauto_thresholdauto_threshold, manual, or agent_review; see Concepts
OPTIMAL_AUTHORITY_MODEoffoff, observe (log decisions), or enforce
OPTIMAL_ENGINE_SCOPEorgworkspace limits the Engine to OPTIMAL_ENGINE_WORKSPACE
OPTIMAL_IMPORT_MAX_BYTES1 GiBLargest import file
OPTIMAL_BUNDLE_MAX_BYTES5 GiBLargest workspace bundle
OPTIMAL_RELEASE_CHANNELdevdev, stable, beta, or pinned, as /api/version reports it

deploy/env.example in the repository lists every variable with a comment.

Where data lives

SQLite is the store. It holds full-text search, vectors, and every record, so one file plus the folders around it is the whole Engine.

<OPTIMAL_ENGINE_ROOT>/          workspace folders: nodes/, .wiki/, assets/
.optimal/index.db               the database (with -wal and -shm files)
.optimal/cache/                 cache and stored embeddings
.optimal/backups/               local backups
.optimal/knowledge-rocksdb/     graph projection, when the rocksdb backend is on

GET /api/stores lists the 13 logical stores and which provider backs each one.

API keys and scopes

Send a key as Authorization: Bearer <key> or X-API-Key: <key>. Keys look like oe_<id>_<secret>; the Engine keeps only a bcrypt hash of the secret.

Mint keys from the checkout:

mix optimal.auth mint --name "agent" --workspace default:notes --scope read --scope write
mix optimal.auth list
mix optimal.auth revoke <id>

Or over HTTP with an admin key: POST /api/auth/keys with {"name", "scopes", "workspace_scope", "expires_at"}. A key can only mint keys narrower than itself. GET /api/auth/whoami shows a key’s own scopes and workspaces.

ScopeAllows
read, writeReading and writing in the key’s workspaces
adminKeys, backups, maintenance, and other operator routes
claims:reviewPromoting and rejecting claims
topology:writeChanging workspaces and nodes
connectors:writeSetting up app connectors
syncReplication
data:adminApp data collections
authority:read, authority:enforce, authority:approve, authority:issue, authority:adminAuthority rules and grants
*Everything
Was this page helpful?