Environment Variables Overview
This group of pages covers the deployment, application, runtime tuning, sandbox, and frontend build environment variables supported by Aivory. For readability, the variables are split by purpose:
- This page: core variables for images, Compose, application startup, storage, authentication, and external integrations.
- Advanced runtime variables: all
AIVORY_*runtime tuning, rate limiting, RAG, queue, and admin task variables. - Sandbox variables: all
SANDBOX_*sidecar and session runtime variables. - Frontend build variables: all
VITE_*variables.
This document does not list any source code locations. All keys, passwords, tokens, private URLs, and backup archives should be treated as highly sensitive: do not commit them to Git, do not post them in support tickets, and do not write them into screenshots or browser frontend environment variables.
How variables take effect and their precedence
The official deployments use different env files: .env.personal for the Personal edition and .env for the Full edition. After copying the template, edit the file you actually use; do not only change .env.example.
Explicit environment values written in Compose take precedence over env_file. This has two important consequences:
- The Personal edition pins SQLite and
VECTOR_BACKEND=sqlite, and clears the Redis/Qdrant addresses. Therefore, writingDATABASE_URL,REDIS_URL,QDRANT_URL, orQDRANT_API_KEYin.env.personalwill not change the Personal edition topology. - The Full edition pins the internal PostgreSQL, Redis, Qdrant, and built-in sandbox addresses. Therefore, writing the same connection addresses in
.envdoes not switch the official full stack to external backends.
Application process variables are typically read at container startup; after changing them, recreate the container with the corresponding Compose up -d --no-build. Sandbox variables require restarting the sandbox service; VITE_* are build-time variables, and adding them to .env at runtime has no effect on prebuilt images.
Channel, model, SMTP, OAuth, search, object storage, payment, and many tool settings in the admin backend are persisted. Environment variables serve as their startup fallback or deployment boundary; do not treat the two as forms that can arbitrarily override each other.
Minimal production configuration
The Personal edition needs at least a stable JWT_SECRET and a writable data directory:
JWT_SECRET=替换为至少32字符的强随机密钥
DATA_DIR=/opt/aivory/data-personal
IMAGE_TAG=latest
The Full edition needs at least mutually distinct database, Redis, and session secrets:
POSTGRES_PASSWORD=替换为强随机数据库密码
REDIS_PASSWORD=替换为强随机Redis密码
JWT_SECRET=替换为至少32字符的强随机密钥
DATA_DIR=/opt/aivory/data
IMAGE_TAG=latest
Generate random values:
openssl rand -hex 32
Model provider API keys are not written in these variables; they should be stored under Channels in the admin backend. After startup, you must also create at least one enabled chat model and select it as the default model in the model policy.
Images, versions, and Compose variables
| Variable | Applies to | Default | Purpose and values | Sensitivity |
|---|---|---|---|---|
IMAGE_OWNER | Personal edition, Full edition | hjxwz123 | Image namespace; change it to your own owner when forking or using a private image registry. | Normal |
IMAGE_REGISTRY | Personal edition, Full edition | ghcr.io when unset | Image registry or controlled image proxy address, without the image name. If a proxy returns inconsistent images, remove it and go back to the official registry. | Normal/Internal network |
IMAGE_TAG | Personal edition, Full edition | latest | Version of the application and the current release's sandbox images; use 3.0.0 for release tags, not v3.0.0. | Normal |
SANDBOX_IMAGE_TAG | When using the built-in sandbox | Inherits IMAGE_TAG | Compatibility override only when a historical version has no matching sandbox tag. Keep it unset in new versions to avoid application/sandbox version drift. | Normal |
DATA_DIR | Personal edition, Full edition | Personal edition ./data-personal; Full edition ./data | Host persistent root directory. The Personal edition holds SQLite and vectors; the Full edition holds uploads, artifacts, local objects, and backups. An absolute path is recommended, and back it up as a whole. | High-value data |
BACKUP_DIR | Personal edition, Full edition | /app/data/backups | In-container full backup archive directory, normally located at DATA_DIR/backups. | Highly sensitive data |
MAX_BACKUP_BYTES | Personal edition, Full edition | 21474836480 | Maximum bytes allowed when importing a full backup in the admin backend; default 20 GiB. Before raising it, evaluate disk, temporary space, and reverse proxy limits. | Normal |
POSTGRES_USER | Full edition | aivory | Built-in PostgreSQL username. Usually keep the default. | Normal |
POSTGRES_DB | Full edition | aivory | Built-in PostgreSQL database name. Usually keep the default. | Normal |
POSTGRES_PASSWORD | Full edition, required | No secure default | Built-in PostgreSQL password; must be a distinct strong random value. | Secret |
REDIS_PASSWORD | Full edition, required | No secure default | Built-in Redis password; must not be reused with the database or JWT secret. | Secret |
QDRANT_URL | Full edition/custom deployments | Internal http://qdrant:6333 in the official Full edition | Qdrant service address. The official full stack pins the internal address; only point this at a controlled external Qdrant in custom deployments. | Internal network |
QDRANT_API_KEY | Full edition/custom deployments | Shared internal default in the official Full edition | Qdrant API authentication. The official service does not publish a port; in production, still set a distinct strong random value consistent with Qdrant. | Secret |
ENABLE_MOCK_PROVIDER | Legacy compatibility variable | false | The current official release runtime no longer uses it to create usable model channels. Do not rely on it; for first use, add a real channel and model in the admin backend. | Normal |
Application startup, network, and backends
Database engine and DSN forms
DATABASE_URL selects the relational store at process start. A value beginning with postgres:// or postgresql:// uses PostgreSQL; a libpq-style value such as host=db user=aivory dbname=aivory sslmode=require is also accepted. Any other value is treated as a SQLite path, including the Personal edition's WAL URL. SQLite runs with one write connection and foreign keys enabled; PostgreSQL uses a connection pool and is the required topology for multiple application replicas.
Both engines run the same embedded schema and idempotent boot migration. Do not run server/migrations/0001_init.sql by hand and do not copy a live SQLite file while its -wal sidecar is changing. Use the online .backup procedure or stop the app and archive the complete DATA_DIR; for PostgreSQL use pg_dump/pg_restore. RAG vectors follow VECTOR_BACKEND: sqlite stores them in vector_points, while qdrant stores them in Qdrant and still keeps document/chunk metadata in the relational database.
| Variable | Applies to | Default | Purpose and values | Sensitivity |
|---|---|---|---|---|
AIVORY_LISTEN | Custom deployments | :8787 | API/Web listen address, e.g. :8787 or 127.0.0.1:8787. The official Compose already pins the in-container port. | Normal |
AIVORY_ENV | Custom deployments | development | Runtime environment marker. The official Compose pins it to production; production rejects weak or empty JWT secrets. | Normal |
AIVORY_HTTP_IDLE_TIMEOUT | Custom deployments | 20m | HTTP keep-alive idle timeout. Coordinate with reverse proxy, SSE, and load balancer idle timeouts. | Normal |
DATABASE_URL | Custom deployments | ./data/aivory.db?... | SQLite path or PostgreSQL DSN. Both the official Personal and Full editions pin their respective backends; do not try to override this in official env files. | High-value data |
REDIS_URL | Custom deployments | Empty, uses in-process cache | Redis DSN. The official Full edition pins internal Redis; the Personal edition explicitly clears it. | Secret/Internal network |
VECTOR_BACKEND | Custom deployments | auto | auto, qdrant, sqlite, or disabled. qdrant requires a Qdrant address; sqlite requires a SQLite database. | Normal |
STATIC_DIR | Separated frontend or self-built images | Empty | Directory for the embedded SPA static files. The official application image already ships the web UI; set this only for API-only/self-built frontend deployments. | Normal |
ALLOWED_ORIGINS | Domain or HTTPS reverse-proxy deployments | Development address list | Required exact browser scheme://host[:port] origins, comma-separated and without paths. Same-origin IP/HTTP testing may leave it unset; do not use uncontrolled wildcards. | Security configuration |
HTTP_PROXY, HTTPS_PROXY, NO_PROXY | Deployments with an outbound proxy | Not set | Standard proxy variables, used for model services, OAuth token exchange, and other outbound HTTP. NO_PROXY should include internal services and local addresses. | Internal network/May contain credentials |
Authentication, sessions, and OAuth
| Variable | Applies to | Default | Purpose and values | Sensitivity |
|---|---|---|---|---|
JWT_SECRET | Personal edition, Full edition, required | Temporarily generated in non-production development; no secure default in production | Session token signing secret. At least 32 characters, long-term stable and different from all passwords; changing it invalidates existing sessions. | Secret |
ACCESS_TTL | All deployments | 30m | Access token lifetime, using durations such as 30m or 1h. Lowering it shortens the exposure window but increases refresh frequency. | Security configuration |
REFRESH_TTL | All deployments | 720h | Refresh token lifetime, default 30 days. Decide it together with device risk, revocation policy, and user experience. | Security configuration |
OAUTH_CALLBACK_BASE_URL | Multi-domain OAuth | Empty | Pin the OAuth callback origin, e.g. https://aivory.example.com, without a trailing /. When unset, it is derived from the request domain. | Security configuration |
OAUTH_RETURN_ORIGINS | Multi-domain OAuth | Empty | Comma-separated list of exact origins allowed to return after login completes; an open-redirect defense, and it must not contain wildcards or paths. | Security configuration |
SEED_ADMIN_EMAIL and SEED_ADMIN_PASSWORD are compatibility items from older examples; the current release process does not use them to create administrators. On a brand-new instance, the first account successfully created on the initialization page automatically becomes the administrator; do not put any so-called default admin password into deployment configuration.
Files, objects, and quotas
| Variable | Applies to | Default | Purpose and values | Sensitivity |
|---|---|---|---|---|
UPLOAD_DIR | Custom deployments | ./data/uploads | Local directory for user uploads. The official Compose mounts its parent directory via DATA_DIR. | High-value data |
ARTIFACT_DIR | Custom deployments | ./data/artifacts | Local directory for generated files and tool artifacts. | High-value data |
AIVORY_LOCAL_STORAGE_DIR | Custom deployments | UPLOAD_DIR/object-storage | Local storage directory for API-owned objects (e.g. avatars). Suitable for single-node local storage; use a controlled object storage solution for multiple replicas. | High-value data |
MAX_UPLOAD_BYTES | All deployments | 52428800 | Hard per-file limit accepted by the application, default 50 MiB. Lower backend settings cannot exceed it; also check proxy limits. | Normal |
DAILY_MESSAGE_LIMIT | All deployments | 200 | Startup default for the per-user daily message cap. For long-term operations, manage this centrally in backend plan/quota policies. | Normal |
IMAGE_DAILY_LIMIT | All deployments | 30 | Startup default for the per-user daily image generation cap. | Normal |
Search, embedding, document parsing, and sandbox fallback
These variables provide startup fallbacks. The corresponding settings already saved in the admin backend usually take precedence for actual features; when configuring them, complete testing and permission review in the admin backend.
| Variable | Applies to | Default | Purpose and values | Sensitivity |
|---|---|---|---|---|
SEARCH_PROVIDER | All deployments | Empty | serper, brave, searxng, or auto. Web search is unavailable when unconfigured; searxng requires a base URL. | Normal |
SEARCH_API_KEY | Serper/Brave | Empty | Search provider API key. Self-hosted SearXNG usually does not need one. | Secret |
SEARCH_BASE_URL | SearXNG | Empty | Root URL of a self-hosted SearXNG instance; it should not include the specific /search path. | Internal network |
EMBEDDING_BASE_URL | All deployments | Empty | Base URL of an OpenAI-compatible embedding API. When empty, a basic local embedding serves as the fallback. | Internal network |
EMBEDDING_API_KEY | External embeddings | Empty | Embedding service key. | Secret |
EMBEDDING_MODEL | External embeddings | text-embedding-3-small | Embedding model request ID; it must match a model supported by the provider. | Normal |
EMBEDDING_DIM | External embeddings | 1536 | The model's actual output dimension. After changing the model or dimension, you must rebuild the vectors of the affected knowledge bases. | Normal |
MINERU_API_URL | OCR/complex documents | Empty; the template may provide https://mineru.net | MinerU or compatible document parsing service address. | Internal network |
MINERU_API_KEY | OCR/complex documents | Empty | MinerU service key. Scanned documents and image-based PDFs often require it. | Secret |
SANDBOX_BASE_URL | External or Personal edition local sandbox | Empty; the official Full edition pins the internal address | Sandbox HTTP service address. The Personal edition local profile uses http://sandbox:8000; without configuration, Python remains unavailable. | Internal network |
SANDBOX_API_KEY | When the sandbox is enabled | Empty; the official built-in sandbox has an internal shared value | Sandbox Bearer key; it must match the sandbox server side. Do not expose the sandbox over the public internet. | Secret |
For sandbox resource, session, upload, and workspace variables, see Sandbox variables. For operational steps on model channels, search, OCR, and embeddings, see Channels, Models, and Policies and Knowledge Bases, RAG, and Storage.