Configuration reference
Every environment variable of a self-hosted Future AGI install: its default in each setup, which setups read it, and what breaks when it is wrong.
In this page
Every environment variable you can set on a self-hosted Future AGI install:
what it does, its default, which setup reads it, and what goes wrong when it
is wrong. Environment variables
covers the keys you are most likely to set, grouped by what you want to do,
and how .env is read.
Nothing is required for a local install. ./bin/install creates .env
from .env.example, generates every secret and starts the
Standalone setup on http://localhost:3000. Come back
here when you want LLM keys, a public URL, email, or a production deployment.
How configuration works
Setups. The Setups column of every table below says who reads a key:
| Code | Setup | Files |
|---|---|---|
| S | Standalone, the default: one app container plus Postgres and ClickHouse | docker-compose.yml (./bin/install) |
| D | Distributed, for scale: one container per service, PeerDB, per-queue workers | docker-compose.distributed.yml (./bin/install --distributed) |
| H | Helm: Distributed on Kubernetes | deploy/helm/futureagi; set application keys through the chart’s values |
| dev | Hot-reload development only | docker-compose.dev.yml, docker-compose.distributed.dev.yml (./bin/dev) |
A key marked S or D but not H only exists in the Compose files (ports, image tags, CPU and memory limits, installer settings); the Helm chart has its own values for those.
Where values come from, why an empty value is not always unset, and how to apply a change: How .env is read.
1. Generated by the installer
On a fresh install (no volumes of this Compose project yet) ./bin/install
fills every key below that is empty or still a CHANGEME- placeholder with a
random value and writes it to .env. It never changes a value afterwards. On
an existing install it fills only INTEGRATION_ENCRYPTION_KEY,
AGENTCC_WEBHOOK_SECRET and, on Standalone, REDIS_PASSWORD, which is safe
while they are unset, and warns about the rest.
--wipe-volumes and ./bin/uninstall --wipe-data make the next install fresh
again, and a value already in .env is kept even then.
Without the installer, set them yourself before the first start:
openssl rand -hex 32 for each, and
python3 -c "import base64, os; print(base64.urlsafe_b64encode(os.urandom(32)).decode())"
for INTEGRATION_ENCRYPTION_KEY. Left empty, the stack runs on the defaults
below, which are published in the open-source repository and therefore not
secret.
Every secret below can change at any time (set it in .env, then
docker compose up -d), except PG_PASSWORD, INTEGRATION_ENCRYPTION_KEY
and CH_PASSWORD once in use: their rows say what breaks.
Secrets
| Key | Default if empty | Setups | What it does, and what breaks if it is wrong |
|---|---|---|---|
SECRET_KEY | local-dev-only-not-for-production-replace-me | S D H | Signs logins, tokens and password-reset links. Changing it signs everyone out. With ENV_TYPE other than local, the app refuses to start on Django’s built-in default. |
PG_PASSWORD | futureagi | S D H | Postgres password. Written into the Postgres volume on the first start: changing it later gives password authentication failed until you restore the old value or wipe the volume. |
MINIO_ROOT_PASSWORD | futureagi (.env.example ships the placeholder CHANGEME-set-by-bin-install, which the installer replaces) | S D H | Object storage password: datasets, exports, media. Compose derives S3_SECRET_KEY from it. A CHANGEME- value next to existing volumes makes the installer stop and ask. |
AGENTCC_INTERNAL_API_KEY | local-dev-only-shared-secret-replace-me | S D H | Shared secret for app-to-gateway calls, and through the gateway your provider keys. Both sides read the same value, so it can change at any time. |
AGENTCC_ADMIN_TOKEN | local-dev-only-admin-token-replace-me | S D H | Bearer token for the LLM gateway’s admin API. The gateway also sends it when it loads keys from the app. |
AGENTCC_WEBHOOK_SECRET | S: a random one on every start; D: empty, and the app refuses the gateway’s request logs, so the gateway’s logs and analytics stay empty | S D H | Shared secret the LLM gateway sends its request logs to the app with. Both read it on start, so it can change at any time. Helm: secrets.agentccWebhookSecret when set, else the key of that name in secrets.existingSecret when that is set, else generated. |
INTEGRATION_ENCRYPTION_KEY | Empty. With ENV_TYPE=local, every process start makes a throwaway key, so saved integration credentials do not survive a restart. Other ENV_TYPEs: connecting an integration fails. | S D H | Fernet key (32 random bytes, URL-safe base64) that encrypts stored integration credentials. Changing it strands what was saved with the old key; those integrations must be connected again. |
REDIS_PASSWORD | local-dev-only-redis-password | S | Password of the Redis inside the app container, which code evals can reach. Only letters, digits and - _ . ~ (it is part of the Redis URLs); anything else stops the container at start. Distributed runs Redis without a password on the internal network. |
CH_PASSWORD | Empty: ClickHouse’s default user has no password, and code evals can then read and change every trace | S D H | Password of ClickHouse’s default user. ClickHouse reads it at every start, and the app, the collector and the bootstrap jobs log in with it; PeerDB’s init job stores it in the ch_dest peer when it creates that. Generated on a fresh install only: an install made before the installer generated one keeps running without it, and on an existing install the installer stops whenever the value differs from the password ClickHouse runs with. No <, > or &: ClickHouse reads it into its XML configuration. Changing it later stops Distributed’s Postgres → ClickHouse sync until that peer carries the new one too, and removing it leaves the dictionaries spans are read through on the old one. To set or change one later, see INSTALLATION.md. Helm: clickhouse.password, else generated. |
Choices the installer records
| Key | Default | Setups | What it does |
|---|---|---|---|
COMPOSE_FILE | unset: Standalone (docker-compose.yml) | S D | Read by Docker Compose. ./bin/install --distributed writes docker-compose.distributed.yml so plain docker compose commands keep using Distributed. An install keeps its setup: moving data between Standalone and Distributed is not supported, and the installer refuses. A COMPOSE_FILE exported in your shell wins over .env; the installer stops unless it lists the chosen setup’s file and not the other one. |
COMPOSE_PROJECT_NAME | futureagi | S D | Read by Docker Compose; prefixes container, volume and network names. ./bin/install --new-instance writes futureagi-2, futureagi-3, … to run an isolated second copy. Changing it on an existing install points it at new, empty volumes. |
The installer also writes FUTURE_AGI_VERSION=local (and, for Distributed,
the other image tags) after --from-source, and a free host port when a
default port is taken. See Images and Host ports.
Installer inputs from your shell
Read by ./bin/install from the shell environment, not from .env.
| Key | Default | Setups | What it does |
|---|---|---|---|
FAGI_ADMIN_EMAIL, FAGI_ADMIN_NAME, FAGI_ADMIN_PASSWORD | unset | S D H | With -y (non-interactive), create the first account from these three. If any is missing, account creation is skipped. Helm: the bootstrap job reads them from bootstrap.admin.existingSecret and creates the account only if no user with that email exists; with the email set, a missing name or password, a malformed email, or a password the sign-up rules reject fails the job, which says why. |
SKIP_USER_CREATION | 0 | S D | 1 skips the first-account prompt (same as --skip-user-creation). |
CI | unset | S D | Any value makes the installer non-interactive (same as -y). |
2. Recommended
LLM provider keys
Server-wide keys for built-in evals, the prompt playground and other platform features that call an LLM. Workspaces can also add their own provider keys in the UI; some eval paths prefer the server-wide key when both exist. One provider is enough to start.
The LLM gateway in the bundled config
(agentcc-gateway/config.example.yaml) routes OpenAI only. To route other
providers through it, copy that file, enable them and point
AGENTCC_CONFIG_PATH at the copy (Application behaviour).
| Key | Default | Setups | What it does |
|---|---|---|---|
OPENAI_API_KEY | empty | S D H | OpenAI key for the app and the gateway’s default route. |
ANTHROPIC_API_KEY | empty | S D H | Anthropic key for the app; for the gateway, enable Anthropic in its config. |
GOOGLE_API_KEY | empty | S D H | Gemini (Google AI Studio) key. The gateway receives it as GEMINI_API_KEY. |
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY | empty | S D H | AWS Bedrock credentials. |
AWS_REGION | us-east-1 | S D H | Region for Bedrock calls. |
A wrong key does not stop anything from starting: the calls that use it fail with the provider’s authentication error.
Public URLs
Needed as soon as anyone opens the UI from anything other than
http://localhost:3000: a server IP, a domain, or a reverse proxy. With plain
ports the UI is http://<host>:3000 and the API http://<host>:8000.
| Key | Default | Setups | What it does, and what breaks if it is wrong |
|---|---|---|---|
VITE_HOST_API | empty: the UI calls http://localhost:<BACKEND_PORT> (8000); Helm: urls.api | S D H | URL the browser uses to reach the API, e.g. https://api.example.com. Written into the UI’s config.js at container start, no rebuild. Wrong or unset on a remote host: the UI loads but every API call fails (often reported as a CORS error). Required by the production overlay and by docker-compose.frontend.yml (UI only). |
BASE_URL | http://localhost:8000 | S D H | The API’s own public URL: SSO and OAuth callbacks, the MCP and SDK endpoints shown in the UI, trusted CSRF origins. Wrong: SSO sign-in redirects fail and copied snippets point at localhost. |
FRONTEND_URL | unset: those links use APP_URL (http:// for a loopback host); Helm: urls.app | S D H | The UI’s URL, e.g. https://app.example.com: links in digest, annotation, discussion and rule-run emails, MCP OAuth consent redirects, and the setup check that warns about plain HTTP. Required by the production overlay. |
APP_URL | localhost:<FRONTEND_PORT> (localhost:3000) in both compose files; Helm: urls.app | S D H | The UI’s address, as host[:port] (app.example.com) or a full URL (https://app.example.com). Invite, verification and password-reset links, the links in app emails and the SSO redirects back to the UI are built from it. A scheme you write is kept. Without one, links use http:// for localhost and loopback addresses, and otherwise https://, or http:// while ENV_TYPE is local or test. So write the full URL when that guess is wrong: https://... for a UI behind TLS with the default ENV_TYPE=local, http://... for a plain-HTTP host with ENV_TYPE=production. Wrong: invite and reset links open the wrong address. |
MINIO_URL | http://localhost:9005 (follows MINIO_API_PORT); Helm: urls.objects, else the ingress’s objects host or the external endpoint, else http://localhost:<objectStorage.bundled.service.downloadPort> | S D H | Base URL of every stored-file link the browser opens (uploads, exports, audio and image previews). Object storage listens on 127.0.0.1 only, so a remote browser needs a reverse proxy in front of port 9005 and this set to its URL. See Opening the UI from another machine in INSTALLATION.md. Wrong: file previews and downloads fail while the rest works. |
FI_COLLECTOR_PUBLIC_URL | http://localhost:<FI_COLLECTOR_OTLP_HTTP_PORT> (http://localhost:4318); Helm: urls.otlp, else the OTLP host of the ingress or the Gateway API routes, else http://localhost:4318 (the port-forward) | S D H | OTLP/HTTP base URL of the trace collector as SDKs outside the stack reach it: what the in-app SDK snippet, the first-run setup screen, the installer’s and the app’s start-up summaries hand out as FI_BASE_URL. The collector listens on 127.0.0.1 in both Compose setups, so SDKs on other machines need a reverse proxy in front of port 4318 and this set to its URL. Wrong: copied snippets send traces to an address that does not answer. |
Without email the install still works: invites return a link for you to share, and “Forgot password” answers with the command an administrator runs to set a new password:
- Standalone:
docker compose exec app python manage.py reset_password --email <address> - Distributed:
docker compose exec backend python manage.py reset_password --email <address> - Helm:
kubectl -n <namespace> exec -it deploy/<release>-backend -c backend -- python manage.py reset_password --email <address>
With email delivery configured (MAILGUN_API_KEY, or an EMAIL_BACKEND other
than the console or dummy backend), “Forgot password” emails the reset link
instead, and answers the same whether or not the address has an account.
| Key | Default | Setups | What it does |
|---|---|---|---|
MAILGUN_API_KEY | empty: emails are written to the app log instead of sent | S D H | Mailgun API key. Setting it switches the app to the Mailgun backend. |
MAILGUN_SENDER_DOMAIN | empty | S D H | Your Mailgun sending domain, e.g. mg.example.com. |
DEFAULT_FROM_EMAIL | empty: Future AGI <noreply@<MAILGUN_SENDER_DOMAIN>> | S D H | Sender of every app email (invites, verification, password resets), on MAILGUN_SENDER_DOMAIN: Mailgun rejects senders on other domains. Helm: config.email.fromEmail. |
DEFAULT_REPLY_TO_EMAIL | empty: no Reply-To header, so replies go to the sender | S D H | Reply-To address of app emails, e.g. support@example.com. Helm: config.email.replyTo. |
SERVER_EMAIL | empty | S D H | Sender of Django’s own error emails. |
EMAIL_BACKEND | Mailgun when MAILGUN_API_KEY is set, otherwise the console backend | S D H | Advanced: any Django email backend class path. Mailgun is the supported provider; SMTP host settings are not read from the environment. |
3. Optional integrations
Each of these is off until you set it.
Extra services
| Key | Default | Setups | What it does |
|---|---|---|---|
COMPOSE_PROFILES | empty | S D | Read by Docker Compose, comma-separated. Standalone: sandbox runs code evals in the privileged nsjail code-executor container instead of the app container (use it when people who write code evals must not trust one another; set it in .env, not only with --profile, because the app reads it to route evals); ml adds the serving embedding-model container (a few GB of RAM) for embedding-based evals and knowledge bases. Distributed: all adds the per-queue workers, the Temporal UI and the PeerDB UI; workers, observability and peerdb add one group each. |
Google Cloud and Vertex AI
Gemini, Imagen and embeddings on Vertex AI work in every setup. The partner models on Vertex (Claude, Llama, Mistral, Model Garden) need the Vertex AI SDK, which Standalone’s app image leaves out; see Backend variants.
| Key | Default | Setups | What it does |
|---|---|---|---|
GOOGLE_APPLICATION_CREDENTIALS | empty (mounts /dev/null) | S D H | Absolute host path of a GCP service-account JSON, mounted read-only. Standalone mounts it at /etc/futureagi/secrets/vertex.json and points the variable there for every process in app (API, worker, gateway); without a file the variable is unset there, so Google’s other credential sources apply. Distributed mounts it into agentcc-gateway and worker-simulation-runner only: the backend and the other workers receive the host path, so mount the file at that path with a compose override if they need it. Never commit the file. |
GOOGLE_CLOUD_PROJECT | empty | S D H | GCP project for Vertex AI calls. |
GOOGLE_CLOUD_LOCATION | global (hosted agent authoring: us-central1) | S D H | Vertex AI region. |
GOOGLE_GENAI_USE_VERTEXAI | True for hosted agent jobs | S D H | Makes Google GenAI clients inside hosted agent sandboxes use Vertex AI. |
CLOUD_ML_REGION | us-east5 (dev overlay: global) | S D H dev | Vertex region for Claude-on-Vertex in hosted agent authoring. |
Other model and voice providers
| Key | Default | Setups | What it does |
|---|---|---|---|
OPENROUTER_API_KEY | empty | S D H | OpenRouter key for the app. |
HUGGINGFACE_API_TOKEN | empty | S D H | Hugging Face token for models pulled from the Hub. |
PERPLEXITY_API_KEY, GROQ_API_KEY, XAI_API_KEY | empty | S D H | Keys the gateway config can reference as ${...} once you enable those providers in it (see AGENTCC_CONFIG_PATH). |
DEEPGRAM_API_KEY, CARTESIA_API_KEY | empty | S D H | Speech providers for voice simulations. |
Enterprise Edition
| Key | Default | Setups | What it does |
|---|---|---|---|
EE_LICENSE_KEY | empty: the open-source feature set | S D H | Enterprise Edition license key. Helm: license.existingSecret (or license.key) with edition: ee; the chart gives it to the backend, every worker and the bootstrap job. |
FUTURE_AGI_LICENSE_URL | https://api.futureagi.com | S D H | License activation and heartbeat server. Helm: license.url. |
FUTURE_AGI_ENTERPRISE_HEARTBEAT_DISABLED | false | S D H | true stops the license heartbeat. Helm: license.heartbeat: false, or global.airgap. |
EE_LICENSE_PUBLIC_KEY, EE_LICENSE_PUBLIC_KEYS, EE_LICENSE_KEY_ID | built-in keyring | S D H | Advanced: override the public keys a license is verified against. Only on instruction from Future AGI. |
EE_LICENSE_CLOCK_SKEW_SECONDS | 300 | S D H | Advanced: clock skew tolerated when checking a license’s validity window. |
Agent simulations in hosted sandboxes
Agent simulations can build and run the agent under test in a remote sandbox from Daytona or E2B. Off until you set that provider’s key.
Distributed and Helm run the default backend image, which has the Daytona and
E2B SDKs and git. Standalone’s app image is built on the slim backend, which
has neither: there, hosted runs answer 501 sandbox_sdk_missing, and runs
from a GitHub source 501 git_unavailable, until you build the app image on
the default backend (Backend variants).
| Key | Default | Setups | What it does |
|---|---|---|---|
HOSTED_SANDBOX_PROVIDER | daytona | S D H | daytona or e2b. Any other value is refused. |
DAYTONA_API_KEY | empty | S D H | Daytona API key. |
DAYTONA_API_URL, DAYTONA_TARGET, DAYTONA_ORGANIZATION_ID | Daytona’s defaults | S D H | Daytona endpoint, region and organization. |
ALK_DAYTONA_SNAPSHOT, ALK_DAYTONA_SNAPSHOT_DIGEST | empty | S D H | Pre-built Daytona snapshot for the sandbox and its pinned digest. |
ALK_DAYTONA_DOCKERFILE | empty | S D H | Build the sandbox from a Dockerfile instead of a snapshot. Development only; leave empty in production. |
E2B_API_KEY | empty | S D H | E2B API key. |
ALK_E2B_TEMPLATE_REFERENCE, ALK_E2B_TEMPLATE_BUILD_ID | empty | S D H | E2B template for the sandbox. The reference must end with the exact build ID. |
ALK_E2B_TEMPLATE_CPU_UNITS, ALK_E2B_TEMPLATE_MEMORY_MB, ALK_E2B_TEMPLATE_DISK_GB | 4, 8192, 10 | S D H | Size of the E2B sandbox. |
ALK_E2B_MAX_TTL_SECONDS | 0 | S D H | Your E2B plan’s limit on a sandbox’s lifetime. Required for E2B: at 0 every E2B job fails with a configuration error. |
HARNESS_PROVIDER | daytona in the compose files (hosted in code; both mean the platform-managed path) | S D H | sandbox sends jobs to an out-of-process sandbox server instead (development). |
HARNESS_PUBLIC_BASE_URL | empty | S D H | Public URL sandboxes use to call back into the platform. |
ALK_HARNESS | claude | S D H | Agent that authors the environment inside the sandbox. |
ALK_HARNESS_MODEL | derived from ALK_HARNESS and the gateway settings (dev overlay’s local sandbox server: claude-sonnet-4-6) | S D H dev | Model the authoring agent uses. |
ALK_HOSTED_AGENTCC_BASE_URL, AGENTCC_BASE_URL | empty | S D H | Gateway URL reachable from inside the sandbox, for authoring through the gateway. The first wins. |
ALK_HOSTED_AGENTCC_MODEL | vertex_ai/gemini-3.7-flash | S D H | Model requested through that gateway. |
AGENTCC_HARNESS_API_KEY | empty (falls back to AGENTCC_INTERNAL_API_KEY) | S D H | Platform-owned gateway key for sandbox authoring. |
SIMULATOR_LLM_PROVIDER, SIMULATOR_LLM_MODEL | vertex, gemini-3.8-flash | S D H | LLM that plays the simulated user. |
SIMULATOR_LLM_THINKING | empty: the least deliberation the model accepts by default | S D H | That LLM’s thinking level or token budget. Set it to go lower where the model allows, e.g. minimal on gemini-3.5-flash-lite (gemini-3.7-flash refuses it). |
ALK_HOSTED_BASE_EGRESS_DOMAINS | empty | S D H | Extra domains a sandbox may reach, comma-separated. |
ALK_HOSTED_WEBRTC_EGRESS_CIDRS | empty | S D H | CIDRs a sandbox may reach for WebRTC media, comma-separated. |
ALK_HOSTED_EGRESS_UNRESTRICTED | false | S D H | true lifts the sandbox egress allow-list. |
ALK_HOSTED_AUTHORING_MAX_DURATION_SECONDS | 3600 | S D H | Longest an authoring run may take. |
ALK_HOSTED_AUTHORING_TIMEOUT | empty: ALK_HOSTED_AUTHORING_MAX_DURATION_SECONDS + 300 | S D H | Timeout of the whole authoring step, in seconds. |
ALK_HOSTED_SANDBOX_TTL_SECONDS | 7200 | S D H | Lifetime of a job’s sandbox. |
ALK_HOSTED_PROVIDER_UNREACHABLE_GRACE_SECONDS | 180 | S D H | Seconds a running sandbox may stay unreachable through its provider’s API before the job fails it (sandbox_unreachable) and replaces it from its infrastructure retries. Raise it for long runs that must ride out a brief provider outage. |
ALK_HOSTED_CHAT_TTL_SECONDS | 1800 | S D H | Lifetime of an interactive chat sandbox. |
ALK_HOSTED_BUNDLE_DIR | empty | S D H | Directory of pre-authored environment bundles (<dir>/<owner>__<repo>/manifest.json). |
HARNESS_PARALLELISM_ENABLED | false | S D H | true lets one sandbox run several of a simulation’s scenarios at once. Parallelism stays off, and a run that asks for it runs one scenario at a time, unless this is true and the sandbox’s image is in HARNESS_PARALLEL_SNAPSHOT_DIGESTS. A Daytona sandbox built from ALK_DAYTONA_DOCKERFILE (development) needs only this flag. |
HARNESS_PARALLEL_SNAPSHOT_DIGESTS | empty: no image qualifies | S D H | Sandbox images cleared for parallel scenarios, comma-separated: Daytona snapshot digests (ALK_DAYTONA_SNAPSHOT_DIGEST, or a profile’s snapshot_digest) and E2B template build IDs (ALK_E2B_TEMPLATE_BUILD_ID). |
HARNESS_MAX_WORLD_SLOTS | 8 | S D H | Most scenarios one sandbox runs at once, 1 to 8: any other value fails every hosted run. The sandbox’s CPU and memory can lower it further. |
HARNESS_RESOURCE_PROFILES | []: every run uses the provider’s fixed sandbox size | S D H | Measured sandbox sizes, a JSON array of objects with name, cpu_units, memory_mb, disk_gb, max_parallelism, connectors (the agent connectors it serves) and, except for sandboxes built from ALK_DAYTONA_DOCKERFILE, snapshot_name and snapshot_digest. A run gets the profile that runs the most of its scenarios at once, and the smallest of those. A value that is not JSON, an empty one included, stops the app from starting; an invalid profile fails every hosted run. |
Voice simulations (Distributed)
Hosted voice runs execute in the worker-simulation-runner container, which
runs its own image. Standalone skips its queue (TEMPORAL_EXCLUDED_QUEUES).
Check the runner’s effective environment with
scripts/verify-simulation-runner-deployment.sh --env-only. Never give the
runner FI_API_KEY or FI_SECRET_KEY: results would be filed under the wrong
organization.
The LiveKit and SIP trunk keys (S below) also reach the API: phone runs in
hosted sandboxes (above) dial out
through the platform’s trunk, never a customer’s, so Standalone’s app and
Distributed’s backend read them too.
| Key | Default | Setups | What it does |
|---|---|---|---|
LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET | empty | S D H | LiveKit project the simulator joins. Must own the SIP trunk below. The API also hands it to phone runs in hosted sandboxes, which is why Standalone’s app reads it. |
INTERNAL_API_SECRET | empty | D H | Bearer the runner uses to report results to the platform. |
LIVEKIT_OUTBOUND_TRUNK_ID | empty | S D H | Outbound SIP trunk (the platform dials the customer’s agent). |
PSTN_CALLER_NUMBER | empty | S D H | E.164 caller id provisioned on that trunk. |
SIP_OUTBOUND_TRUNK_ID, SIP_OUTBOUND_FROM_NUMBER | empty | S D H | Fallbacks for LIVEKIT_OUTBOUND_TRUNK_ID and PSTN_CALLER_NUMBER when a phone run in a hosted sandbox dials out; those two win when set. |
ALK_SIM_SLOT_LEASE_SCRIPT | empty | D H | Path inside the runner to the lease script for inbound (Retell) runs. Unset: the SDK provisions a dispatch rule per run. |
SIM_SLOT_LEASE_STORE | the lease script’s own per-container default | D H | Where that script records leases; point every runner at one shared location. Read by the lease script, not by the platform. |
HOSTED_RUNNER_ENABLED | false (the runner container: true) | D H | Send eligible simulation runs to the runner. |
HOSTED_RUNNER_VOICE_ENABLED | false | D H | Send voice runs to the runner too. Needs HOSTED_RUNNER_ENABLED. |
HOSTED_RUNNER_MAX_CASES | 500 (0 = no cap) | D H | Most scenario rows one hosted voice run may reserve. |
HOSTED_RUNNER_MAX_WALLCLOCK_SECONDS | 21600 (0 = no cap) | D H | Longest one hosted voice run may hold a runner slot. |
HOSTED_RUNNER_LEASED_ROOM_REUSE | false | D H | Serve a multi-row phone run over one leased room. Only once a runner kit that supports it is deployed. |
HOSTED_RUNNER_LEASED_ROOM_MAX_CASES | 25 (0 = no cap) | D H | Tighter row cap for leased-number phone runs. |
HOSTED_RUNNER_LEASED_ROOM_MAX_WALLCLOCK_SECONDS | 14400 (0 = no cap) | D H | Tighter time cap for leased-number phone runs. |
HOSTED_RUNNER_PARENT_SLACK_SECONDS | 600 | D H | Seconds the workflow timeout and number lease exceed the run’s own budget. An empty value stops the worker at import: leave it unset instead. |
SIMULATOR_CONVERSATION_DIRECTION | simulator_first | D H | Who speaks first in a simulated call. |
ALK_RUNNER_MAX_CONCURRENCY | 4 | D | Concurrent runs per runner container (also its activity slots). |
ALK_RUNNER_PYTHON | /opt/alk-venv/bin/python | D | Interpreter of the runner’s SDK environment. |
TEMPORAL_SIMRUNNER_MAX_WORKFLOWS | 8 | D | Workflow task slots of the runner. |
SIMULATION_RUNNER_GRACEFUL_SHUTDOWN_TIMEOUT | 300 | D | Seconds the runner drains in-flight calls on stop. |
SIMULATION_RUNNER_STOP_GRACE_PERIOD | 330s | D | Docker’s stop timeout for the runner. Keep it above the drain timeout, or a call in flight is cut and its leased number stays taken. |
VAPI_API_KEY, VAPI_PHONE_NUMBER_ID | empty | S D H | Vapi account for voice simulations through Vapi. |
VAPI_API_BASE_URL | Vapi’s public API | S D H | Vapi API endpoint. |
SYSTEM_VOICE_PROVIDER | vapi | S D H | Provider of the simulator side of a voice call. Calls to LiveKit agents always use LiveKit. |
Deployment telemetry
Deployment telemetry is on by default, so Future AGI knows how many installs run which version. It never sends traces, prompts, completions, datasets or any other content. What it sends and when, what the opt-out still sends, and how to see what your install sent: Telemetry and outbound connections.
| Key | Default | Setups | What it does |
|---|---|---|---|
FUTURE_AGI_TELEMETRY_DISABLED | false | S D H | true opts out (1, yes and on also work): no email addresses and no heartbeats are sent, and buffered heartbeats are deleted; one minimal registration remains (what it contains). ./bin/install --no-telemetry (.\bin\install.ps1 -NoTelemetry) writes it before anything starts. Helm: config.telemetry=false. |
FUTURE_AGI_TELEMETRY_URL | https://api.futureagi.com | S D H | Where registrations and heartbeats go. Change it only to test against another receiver. |
FUTURE_AGI_TELEMETRY_INTERVAL_HOURS | 6 | S D H | Heartbeat interval: 1, 2, 3, 4, 6, 8, 12 or 24. Other values fall back to 6. |
FUTURE_AGI_TELEMETRY_JITTER_SECONDS | 1800 | S D H | Maximum random delay added to each scheduled run, so installs do not all send at once. |
FUTURE_AGI_TELEMETRY_TIMEOUT_SECONDS | 5 | S D H | Timeout of each request. ./bin/install runs its create_user with 2 unless this is set, so an unreachable telemetry URL delays the first account only briefly. |
FUTURE_AGI_TELEMETRY_BUFFER_DIR | S: /data/telemetry; D: /tmp/futureagi-deployment-telemetry; H: futureagi-deployment-telemetry under the system temp dir | S D H | Where undelivered heartbeats wait for the next attempt, in a directory only the app’s user can read. Files older than 30 days are deleted. |
FUTURE_AGI_DEPLOYMENT_TYPE | S D: docker; H: detected: kubernetes | S D H | Reported as deployment_type in telemetry. Unset, it is detected: kubernetes, docker or bare_metal. |
Integrations of Future AGI’s hosted service
These power Future AGI’s own cloud service. Leave them empty when you self-host: empty means the feature is skipped and nothing is sent.
| Key | Default | Setups | What it does |
|---|---|---|---|
HUBSPOT_API_TOKEN | empty: skipped | S D H | Adds a HubSpot contact at signup and marks it at login. |
SLACK_WEBHOOK_CHANNEL | empty: skipped | S D H | Slack incoming webhook for new-signup notices. |
ERROR_LOGS_WEBHOOK | empty | S D H | Slack incoming webhook for selected error reports. Never used with ENV_TYPE=local. |
MIX_PANEL_TOKEN | empty: off | S D H | Server-side Mixpanel product analytics. |
POSTHOG_API_KEY | empty: off | S D H | Server-side PostHog product analytics. |
POSTHOG_HOST | https://us.i.posthog.com | S D H | PostHog endpoint. |
SENTRY_DSN | empty: off | S D H | Send errors to your Sentry project. |
SENTRY_ENABLED | on outside ENV_TYPE=local, but only with a DSN | S D H | false turns Sentry off even with a DSN. |
USAGE_EVENTS_ENABLED | false in both compose files and the chart (config.usageEvents) | S D H | Billing usage events, one per trace export and per metered action, on the Redis stream usage:events. The app and fi-collector (Standalone runs it inside app) read it. Only Future AGI Cloud drains that stream: turned on anywhere else, it grows until it reaches USAGE_EVENTS_MAX_LEN, taking Redis memory the cache and locks need. Unset, the app turns it on only when the image ships that consumer, and fi-collector turns it on. |
USAGE_EVENTS_MAX_LEN | 1000000 | S D H | Most entries kept on usage:events (about 160 bytes each) while its consumer is behind or stopped. A positive integer in plain digits; blank means the default. The app and fi-collector refuse to start on zero, a negative number or text. |
Browser-side analytics (Mixpanel, PostHog, Sentry, ad pixels) are build-time
settings of the UI image. The published images are built without them, so the
UI sends nothing to those services. VITE_MIXPANEL_SESSION_REPLAY_PERCENT and
VITE_SESSION_REPLAY_BLOCKED_PATH_PREFIXES only matter in an image built with
a Mixpanel token.
Sign-up and sign-in
| Key | Default | Setups | What it does |
|---|---|---|---|
OSS_RETURN_PASSWORD_RESET_LINK | false | S D H | true returns the password-reset link in the browser instead of emailing it, even when email is configured. The endpoint takes no authentication, so anyone who can reach the instance can take over any account. Only on a laptop or a network where everyone is trusted. ./bin/install warns when .env sets it, and the Standalone start-up summary marks it UNSAFE. |
RECAPTCHA_ENABLED | false in the compose files; Helm: config.recaptcha (false) | S D H | reCAPTCHA on sign-up, login and token refresh. Needs RECAPTCHA_SECRET_KEY and a UI image built with VITE_GOOGLE_SITE_KEY; the published images have none, so turning it on there rejects every sign-up and login. The Helm chart refuses to render config.recaptcha=true without RECAPTCHA_SECRET_KEY (in secrets.extra or config.extraEnv) or a config.extraEnvFrom source. |
RECAPTCHA_SECRET_KEY | empty | S D H | reCAPTCHA server key. |
AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET | empty: no Google sign-in | S D H | Google sign-in: the OAuth client of a Google Cloud “Web application” (the app names Google’s settings AUTH0_*). Redirect URI: <API URL>/saml2_auth/auth/callback/. Helm: auth.google. |
GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET | empty: no GitHub sign-in | S D H | GitHub sign-in: a GitHub OAuth app. Redirect URI: <API URL>/saml2_auth/github/callback/. Helm: auth.github. |
MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET | empty: no Microsoft sign-in | S D H | Microsoft sign-in: a multi-tenant Entra app registration (the common endpoint). Redirect URI: <API URL>/saml2_auth/microsoft/callback/. Helm: auth.microsoft. |
VITE_HELP_LINK | empty: the community Discord | S D H | Where the sidebar’s Help entry points. |
4. Advanced tuning
Defaults are the values the compose files and the app use when a key is unset.
Images
Helm pins every image to the chart’s appVersion; override it with the chart
value image.tag. The keys below are the Compose equivalents.
| Key | Default | Setups | What it does |
|---|---|---|---|
FUTURE_AGI_VERSION | latest | S D | Tag of the Future AGI images (futureagi/standalone in Standalone, built on the slim backend; futureagi/future-agi, the default backend, in Distributed; see backend variants). Pin a release such as v1.42.0; local means images built from this checkout by ./bin/install --from-source (needed for a development branch: published images are built from main). Also reported as the version in telemetry. |
FRONTEND_VERSION, AGENTCC_GATEWAY_VERSION, SERVING_VERSION, CODE_EXECUTOR_VERSION | latest | S D | Tags of the UI, gateway, embedding-server and code-executor images. Standalone uses only SERVING_VERSION (ml profile) and CODE_EXECUTOR_VERSION (sandbox profile). |
FI_COLLECTOR_VERSION | local (built from ./fi-collector) | D | Tag of the trace collector image. The production overlay requires a published, reviewed tag. |
SIMULATION_RUNNER_VERSION | latest | D | Tag of the simulation runner image. Required by the production overlay. |
Host ports
./bin/install checks every port the chosen setup publishes and offers a free
one when a default is taken. Ports marked 127.0.0.1 only accept connections
from the Docker host; the rest listen on all interfaces. Under
./bin/dev --distributed, Postgres, ClickHouse, Redis, MinIO and Temporal
listen on all interfaces too.
| Key | Default | Setups | What it publishes |
|---|---|---|---|
FRONTEND_PORT | 3000 | S D dev | UI. An unset APP_URL follows it. |
BACKEND_PORT | 8000 | S D dev | API. An unset VITE_HOST_API follows it; when the installer moves this port it also rewrites a VITE_HOST_API that names localhost. A VITE_HOST_API naming another host is yours to update. |
AGENTCC_GATEWAY_PORT | 8090 | S D dev | LLM gateway (OpenAI-compatible). |
FI_COLLECTOR_OTLP_PORT | 4317 | S D dev | OTLP gRPC trace ingest, 127.0.0.1. |
FI_COLLECTOR_OTLP_HTTP_PORT | 4318 | S D dev | OTLP HTTP trace ingest, 127.0.0.1. An unset FI_COLLECTOR_PUBLIC_URL follows it. |
MINIO_API_PORT | 9005 | S D dev | Object storage API, 127.0.0.1. MINIO_URL follows it. |
FI_COLLECTOR_ADMIN_PORT | 9464 | D | Collector health and metrics, 127.0.0.1. |
SERVING_PORT | 8080 | D | Embedding model server. |
CODE_EXECUTOR_PORT | 8060 | D | Code executor, 127.0.0.1: it runs any code it is sent, without authentication. |
PG_PORT | 5432 | D dev | Postgres, 127.0.0.1. |
CH_HTTP_PORT, CH_PORT | 8123, 9000 | D dev | ClickHouse HTTP and native, 127.0.0.1. |
REDIS_PORT | 6379 | D dev | Redis, 127.0.0.1. |
MINIO_CONSOLE_PORT | 9006 | D dev | MinIO console, 127.0.0.1. |
TEMPORAL_PORT | 7233 | D dev | Temporal gRPC, 127.0.0.1. |
TEMPORAL_UI_PORT | 8085 | D | Temporal UI (all or observability profile, or ./bin/dev --distributed). |
PEERDB_PORT | 9900 | D | PeerDB, 127.0.0.1. |
PEERDB_UI_PORT | 3001 | D | PeerDB UI (all or peerdb profile, or ./bin/dev --distributed). |
PROPERTY_CATALOG_KAFKA_PORT | 29092 | D | Kafka of the observed-attribute catalog, 127.0.0.1. |
Standalone publishes no Postgres, ClickHouse, Redis, Temporal or code-eval
sandbox port, and its ml and sandbox profiles publish none either.
Standalone sizing
| Key | Default | Setups | What it does |
|---|---|---|---|
FI_APP_TEMPORAL_MAX_CONCURRENT_ACTIVITIES | 8 | S | Activity slots per queue of the app’s embedded Temporal worker. Each running activity can hold a Postgres connection: raise it only on a larger host. |
FI_APP_TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS | 8 | S | Workflow-task slots per queue of the embedded worker. |
GRANIAN_THREADS | 2 | S D H | API server threads. |
REDIS_MAXMEMORY | 128mb | S | Memory cap of the app container’s Redis (cache and locks; nothing in it must survive a restart). At the cap it evicts the least recently used keys (allkeys-lru). |
SPAN_LIST_PAGE_WALL_MS, TRACE_LIST_PAGE_WALL_MS, SESSION_LIST_PAGE_WALL_MS | Standalone: 15000; elsewhere 5000 | S D H | How long a span, trace or session list page may search before it answers with the rows found so far and a cursor for the rest (marked degraded). Standalone’s ClickHouse runs two threads a query, so it waits longer. Between 100 and 60000. |
FI_ADOPT_DISTRIBUTED_INSTALL_DATA | unset | S | true makes Standalone take over a Postgres database created by Distributed. Uploads in the old MinIO volume and in-flight workflows are left behind. Moving an install between setups is otherwise refused. |
Distributed sizing
| Key | Default | Setups | What it does |
|---|---|---|---|
GRANIAN_WORKERS | 1 | D H | API server processes. |
ENABLE_HTTP, ENABLE_GRPC | true, true | D H | Run the backend’s HTTP server and its gRPC server (port 50051). |
TEMPORAL_ALL_QUEUES | true | D H | true: the single worker polls every queue except TEMPORAL_EXCLUDED_QUEUES. false: it polls only the default queue, so run the per-queue workers (all or workers profile) for the rest. |
TEMPORAL_MAX_CONCURRENT_ACTIVITIES, TEMPORAL_MAX_CONCURRENT_WORKFLOW_TASKS | 50, 50 | D H | Slots of the all-queues worker. Standalone ignores these (see FI_APP_TEMPORAL_*). |
TEMPORAL_DEFAULT_MAX_ACTIVITIES, TEMPORAL_DEFAULT_MAX_WORKFLOWS | 100, 100 | D | Slots of worker-default. |
TEMPORAL_TASKS_S_MAX_ACTIVITIES, TEMPORAL_TASKS_S_MAX_WORKFLOWS | 200, 200 | D | Slots of worker-tasks-s. |
TEMPORAL_TASKS_L_MAX_ACTIVITIES, TEMPORAL_TASKS_L_MAX_WORKFLOWS | 50, 50 | D | Slots of worker-tasks-l. |
TEMPORAL_TASKS_XL_MAX_ACTIVITIES, TEMPORAL_TASKS_XL_MAX_WORKFLOWS | 10, 20 | D | Slots of worker-tasks-xl. |
TEMPORAL_TRACE_MAX_ACTIVITIES, TEMPORAL_TRACE_MAX_WORKFLOWS | 100, 100 | D | Slots of worker-trace-ingestion. |
TEMPORAL_COMPASS_MAX_ACTIVITIES, TEMPORAL_COMPASS_MAX_WORKFLOWS | 50, 50 | D | Slots of worker-agent-compass. |
FI_COLLECTOR_CPUS, FI_COLLECTOR_MEMORY | 1.0, 1G | D | CPU and memory limit of the trace collector. |
Databases and storage
The Postgres and ClickHouse hosts are set by the compose files. To use a managed
database, override PG_HOST, PGBOUNCER_HOST or CH_HOST in a
docker-compose.override.yml: values in .env do not reach those keys.
| Key | Default | Setups | What it does |
|---|---|---|---|
PG_USER, PG_DB | futureagi, futureagi | S D H | Postgres user and database. Set before the first start; changing them later points the app at a database that does not exist. |
CH_DATABASE | default | S D H | ClickHouse database. CH25_DATABASE and FI_CH_DATABASE follow it unless set. |
CH25_DATABASE | CH_DATABASE | S D H | Database of the v2 trace schema. Keep it equal to FI_CH_DATABASE. |
FI_CH_DATABASE | CH25_DATABASE | S D H | Database the trace collector writes. A different database from the app’s means traces never show up. |
CH_USERNAME | default | S D H | ClickHouse user of the app. Helm: clickhouse.user, which must stay default with the bundled ClickHouse. |
CH_ENABLED | true | D H | Read analytics from ClickHouse. Do not turn off: trace views need it. |
CH_USE_REPLICATED_ENGINES | false | D H | Create Replicated table engines, for a ClickHouse cluster. |
CH25_EVAL_LOGGER_TABLE | tracer_eval_logger | S D H | Table of eval results in the v2 schema. Do not change. |
CH25_QUERY_TYPES_V2_ONLY | every query type | S D H | Query types served only from the v2 schema. Do not change. |
MINIO_ROOT_USER | futureagi | S D H | Object storage user; S3_ACCESS_KEY follows it. Set before the first start. |
STORAGE_BACKEND | minio | S D H | Object storage flavour: minio, s3 or gcs. The compose files wire the bundled MinIO; the others need your own S3_* values in a compose override. |
PGSSLMODE | prefer | S D H | TLS mode of the trace collector’s Postgres connections. Use verify-full for a remote Postgres. |
PGSSLROOTCERT, PGSSLCERT, PGSSLKEY | empty | S D H | Certificate paths inside the collector container; mount the files read-only in a compose override. Helm: with postgres.external.sslMode verify-ca or verify-full and a global.caBundle, the chart sets PGSSLROOTCERT itself; otherwise mount the CA through the extraVolumes and extraVolumeMounts of backend, worker, bootstrap and fiCollector, and set PGSSLROOTCERT in config.extraEnv and fiCollector.extraEnv (example in the chart README). |
PGBOUNCER_READ_HOST, PGBOUNCER_READ_PORT, PG_READ_DB | unset: no replica | S D H | A read replica (or a pooler in front of one) for opted-in reads; same user and password as the primary. Helm: postgres.readReplica. |
READ_REPLICA_OPT_IN | empty: nothing reads from the replica | S D H | Model class names and feature: keys routed to the replica, comma-separated. Helm: postgres.readReplica.optIn. |
PG_DIRECT_HOST, PG_DIRECT_PORT | unset | S D H | A direct (unpooled) Postgres connection for migrations when PGBOUNCER_HOST is a transaction-mode pooler. Helm sets it on the bootstrap job when postgres.pooler is on. |
AGENTCC_REDIS_ADDRESS, AGENTCC_REDIS_PASSWORD, AGENTCC_REDIS_DB | unset: state in memory | D H | Redis the LLM gateway keeps rate limits, budgets and other shared state in, as host:port; needed as soon as it runs more than one replica. No TLS. Helm: agentccGateway.redis (on by default with more than one replica, database 4); with redis.external.tls, a Redis without TLS set here through agentccGateway.extraEnv. |
Application behaviour
| Key | Default | Setups | What it does |
|---|---|---|---|
ENV_TYPE | local | S D H | local keeps the self-host fallbacks: the default SECRET_KEY is accepted, a throwaway INTEGRATION_ENCRYPTION_KEY is made, links use http://. Any other value (the production overlay uses production) turns them off: the app refuses to start without a real SECRET_KEY, and links use https://. |
DEBUG | S: false; D: on while ENV_TYPE=local | S D H | Django debug pages. Never on for an instance others can reach. The production overlay turns it off. |
LOG_LEVEL | INFO | S D H | Application log level. |
LOG_STREAM | stdout | S D H | stderr sends the application’s logs to stderr, for a one-off manage.py command whose output you redirect (sqlmigrate, dumpdata); ./bin/dev manage sets it. Leave it unset for the services: some log collectors (GKE, for one) mark every stderr line as an error. |
ALLOWED_HOSTS | * | S D H | Host names the API answers to, comma-separated. Standalone adds 127.0.0.1,localhost to a list without *, because the container’s own health checks call the API on loopback. Distributed adds nothing: include backend,localhost,127.0.0.1 yourself, since the workers call the API as backend (live updates, harness callbacks) and ./bin/install checks it on localhost. Helm: config.allowedHosts, to which the chart adds localhost, its service names, the API host and the pod’s own IP ($(POD_IP), the Host of load balancer health checks that probe pods directly); empty (the default) means the API host once the API has a public URL, else *. |
CORS_ALLOWED_ORIGINS | empty: any origin | S D H | Browser origins allowed to call the API, comma-separated (e.g. https://app.example.com). Setting it turns off allow-all. Helm: config.corsAllowedOrigins; empty (the default) means the UI’s origin once the UI has a public URL, else any origin; * keeps any origin. |
CORS_ALLOWED_ORIGIN_REGEXES | empty | S D H | Same, as regular expressions. |
EXTRA_CSRF_ORIGINS | empty | S D H | Extra trusted CSRF origins, comma-separated. |
AGENTCC_CONFIG_PATH | agentcc-gateway/config.example.yaml | S D | Gateway provider config, relative to the repository root, mounted into the gateway. Copy the example to enable Anthropic, Gemini, Bedrock, Vertex and others; the copy is git-ignored. A path that does not exist stops the stack from starting. |
AGENTCC_ALLOW_PRIVATE_PROVIDER_URLS | false; Helm: agentccGateway.allowPrivateProviderURLs | S D H | true lets org providers use base URLs on private networks (RFC 1918 addresses, Docker service names): a local Ollama or vLLM, see INSTALLATION.md. Read by the gateway and the API; a gateway or API from before this setting ignores it and refuses every private address. Loopback, link-local and cloud metadata addresses stay refused. Anyone who can add a provider can then reach every service on that network, ClickHouse included (its default user has no password while CH_PASSWORD is empty, as on installs made before the installer generated one), so turn it on only when they are all trusted. |
AGENTCC_SYNC_INTERVAL | 60s (Helm: 60s, from agentccGateway.config.control_plane.sync_interval) | S D H | A Go duration (60s, 5m): the gateway also re-reads keys and org settings from the app this often, so a gateway that started before the app (Distributed on a slow host) or several gateway replicas catch up. A gateway from before this setting ignores it and syncs only on start: its control plane sync enabled log line shows an interval of 0s. Helm sets it in the gateway’s config file, which every gateway reads. |
APP_VERSION | unset | S D H | The running version, reported by the license check, Sentry and the model server. Helm sets it to the backend image tag. |
SIM_COLLECTOR_OTLP_ENDPOINT | fi-collector:4317 | D H | OTLP/gRPC host:port where simulations and voice calls send their spans. Helm sets it to the release’s collector. |
OTEL_ENABLED | false | S D H | Export the platform’s own OpenTelemetry traces (monitoring Future AGI itself, not your application’s traces). |
FAST_STARTUP | false | D H | Skip start-up checks in the backend containers. |
TEMPORAL_TEST_EXECUTION_ENABLED | true | S D H | Run test executions as Temporal workflows. |
ERROR_LOCALIZER_BACKEND | S: legacy; D H: claude_agent_sdk | S D H | Which error localizer explains a failed eval. claude_agent_sdk needs the localizer extra, which Standalone’s slim image leaves out (Backend variants); legacy is the original localizer and cannot localize simulation call audio. |
EXACT_AGGREGATION_TASK_QUEUE | exact_aggregation | S D H | Queue of exact analytics, which a dedicated single-slot worker serves. |
TEMPORAL_EXCLUDED_QUEUES | simulation_runner | S D H | Queues the general worker does not poll. The runner queue needs its own image. |
TEMPORAL_NAMESPACE | default | D H | Temporal namespace. |
FI_CDC_MODE | S: outbox (D always uses PeerDB) | S | How Postgres changes reach ClickHouse. Standalone uses capture triggers drained by a Temporal schedule; do not change. |
CODE_EXECUTOR_URL | http://code-executor:8060 (the app’s built-in sandbox; sandbox profile: the nsjail container) | S | Where code evals run. The built-in sandbox runs Python only; JavaScript evals need the sandbox profile. Point it at your own executor only if you run one. |
CODE_EXECUTOR_EGRESS_PORTS | 80,443 | S | TCP ports code evals in the built-in sandbox may connect to, comma-separated; they can listen on none. Landlock enforces it where the Docker host runs Linux 6.7 or later; on older kernels evals reach every port, and the app’s log says so at start. A malformed list stops the sandbox. The nsjail sandbox (sandbox profile) does not apply it. See INSTALLATION.md. |
CODE_EXECUTOR_LOCAL_FALLBACK | false (Standalone: fixed false) | D H | true runs code evals inside the worker when code-executor cannot be reached, next to the platform’s secrets. Off, they fail with Code executor unavailable. Only for installs that cannot run the privileged code-executor and where everyone who can write code evals is trusted; ignored on Future AGI Cloud. See INSTALLATION.md. Helm: codeExecutor.localFallback. |
MODEL_SERVING_URL | http://serving:8080 | S D H | Embedding model server. Without the ml profile the features that need it are unavailable. |
WEBSOCKET_ENDPOINT | http://backend/call-websocket/ | D H | Where workers post live updates for browsers. It must reach the backend from every container; change it only when the backend runs under another name or port. Standalone fixes it inside the container. |
ALK_RUNNER_API_URL | S: http://127.0.0.1:8000; D: http://backend | S D H | Platform URL the simulation runner reports results to. |
Observed-attribute catalog
The span attributes and values that trace filters, dashboard widgets and task
filters suggest (including values of built-in properties such as the model).
The bootstrap creates the catalog database and its two users. Standalone and
Helm collectors write it directly (FI_OBSERVED_CATALOG_MODE=direct, through
a local spool); Distributed’s collector publishes to Kafka and
fi-property-catalog-consumer writes it. Spans stored before an install
collected them can be indexed later with fi-observed-catalog-backfill
(INSTALLATION.md).
| Key | Default | Setups | What it does |
|---|---|---|---|
PROPERTY_CATALOG_DATABASE | property_catalog | S D H | ClickHouse database of the catalog. |
PROPERTY_CATALOG_API_PASSWORD | oss-observed-reader-local-only | S D H | Password of the catalog’s read-only ClickHouse user. Required by the production overlay; reuse the provisioned value, never rotate it on retained data. |
PROPERTY_CATALOG_CONSUMER_PASSWORD | oss-observed-writer-local-only | S D H | Password of the catalog’s writer user: the collector (S, H) or the Kafka consumer (D). Same rules. |
OBSERVED_CATALOG_KAFKA_TOPIC | futureagi.observed-attributes.v1 | D H | Topic the collector publishes observations to. |
OBSERVED_CATALOG_KAFKA_GROUP | futureagi.observed-attributes.consumer.v1 | D H | Consumer group of the catalog writer. |
OBSERVED_CATALOG_MAX_SPOOL_FILES, OBSERVED_CATALOG_MAX_SPOOL_BYTES | 10000, 536870912 | D H | Local spool limits of the collector while Kafka is unreachable. Standalone reads them as FI_OBSERVED_CATALOG_MAX_SPOOL_FILES and FI_OBSERVED_CATALOG_MAX_SPOOL_BYTES (while ClickHouse is unreachable). |
FI_OBSERVED_CATALOG_MAX_KEYS_PER_SPAN, FI_OBSERVED_CATALOG_MAX_ARRAY_MEMBERS_PER_SPAN | 128, 256 | S D H | Most attribute keys and array members observed per span. |
ERROR_FEED_KAFKA_TOPIC | error-feed.trace-available.v1 | D H | Topic announcing new traces to the error feed. Must differ from the catalog topic. |
PROPERTY_CATALOG_KAFKA_PARTITIONS | 6 | D | Partitions of both topics. |
PROPERTY_CATALOG_KAFKA_RETENTION_MS, PROPERTY_CATALOG_KAFKA_RETENTION_HOURS | 259200000, 72 | D | Topic retention and the broker’s log retention. |
PROPERTY_CATALOG_KAFKA_CPUS, PROPERTY_CATALOG_KAFKA_MEMORY, PROPERTY_CATALOG_KAFKA_HEAP_OPTS | 1.0, 1G, -Xms256m -Xmx512m | D | Kafka container limits and JVM heap. |
PROPERTY_CATALOG_CONSUMER_CPUS, PROPERTY_CATALOG_CONSUMER_MEMORY | 0.5, 512M | D | Catalog writer container limits. |
Installer
| Key | Default | Setups | What it does |
|---|---|---|---|
INSTALL_READY_TIMEOUT_SECONDS | 600 (60 to 1800) | S D | How long ./bin/install waits for the stack to become ready. The wait extends while first-boot migrations are still running. |
INSTALL_STABILITY_SECONDS | 15 (5 to 120) | S D | How long the stack must stay ready before the installer reports success. |
INSTALL_READY_MAX_SECONDS | 3600 (300 to 7200) | S D | Hard limit on the wait, extensions included. It matches the app healthcheck’s start_period: on a slow or busy host a first boot’s migrations can take over half an hour. |
Fine-grained limits
- Application limits. About 230 bounded numeric settings (page sizes,
timeouts, batch sizes, read budgets) are declared with their default, minimum
and maximum in
futureagi/tfc/settings/runtime_setting_specs.py. Any of them can be set by name in.env(Standalone and Distributed pass.envto the app). A value outside its bounds stops the app at start with a message naming the key. - UI limits. The
VITE_*timeouts and page sizes listed infrontend/docker-entrypoint.sh, with defaults infrontend/.env.example, are read when the UI container starts. Standalone takes them from.env; Distributed passes onlyVITE_HOST_APIandVITE_HELP_LINKto thefrontendcontainer, so set others in a compose override. Out-of-range values fall back to the default.
Proxy, CA bundle and air-gap
The processes honour the standard proxy and trust-store variables. Set them
in a compose override; the Helm chart sets them from global.proxy,
global.caBundle and global.airgap.
| Key | Default | Setups | What it does |
|---|---|---|---|
HTTP_PROXY, HTTPS_PROXY, NO_PROXY (and lowercase) | unset | S D H | Outbound proxy and the hosts that bypass it, object storage included; object storage on a loopback address (Standalone’s) is always reached directly. On Distributed, list the internal hosts in NO_PROXY (minio,code-executor,serving,agentcc-gateway,fi-collector,localhost,127.0.0.1), or their calls go to the proxy. Helm: global.proxy, which builds NO_PROXY from the cluster’s names, the release’s Services and the datastore hosts plus global.proxy.noProxy. The LLM gateway does not use a proxy yet. |
SSL_CERT_FILE, REQUESTS_CA_BUNDLE, CURL_CA_BUNDLE, NODE_EXTRA_CA_CERTS | the image’s trust store | S D H | A PEM bundle to trust instead of the image’s (so it must include the public roots). Helm: global.caBundle, mounted at /etc/futureagi/ca/ca.crt. |
LITELLM_LOCAL_MODEL_COST_MAP | unset: fetched at start | S D H | True uses litellm’s bundled model price list instead of downloading it. Helm: on with global.airgap. |
HF_HUB_OFFLINE, TRANSFORMERS_OFFLINE | unset | S D H | 1 stops the model server from downloading models; pre-seed its cache first. Helm: on (serving only) with global.airgap. |
Development overlays (./bin/dev)
Read only by docker-compose.dev.yml and docker-compose.distributed.dev.yml.
| Key | Default | Setups | What it does |
|---|---|---|---|
VITE_ENVIRONMENT | development | dev | Environment name the Vite dev server builds with. |
VITE_GOOGLE_SITE_KEY | empty | dev | reCAPTCHA site key for the Vite dev server. |
BACKEND_GRPC_PORT | 50051 | dev | Published gRPC port of the development backend. |
FLOWER_PORT | 5555 | dev | Published port 5555 of the development backend (task monitor). |
PGBOUNCER_PORT | 6432 | dev | Published PgBouncer port (Distributed dev). The app’s own PGBOUNCER_PORT is set by the compose files. |
DEV_API_PROXY_OTLP_MAX_BODY_SIZE, DEV_API_PROXY_CONNECT_TIMEOUT, DEV_API_PROXY_READ_TIMEOUT, DEV_API_PROXY_SEND_TIMEOUT | 16m, 5s, 30s, 30s | dev | Limits of the development API proxy. |
DOCKER_SOCKET | /var/run/docker.sock | dev | Host Docker socket the local sandbox server (local-sandbox profile) builds with. |
ALK_HOST_WORKSPACE_ROOT | required by the local sandbox server | dev | Host directory holding the agent repositories the local sandbox server builds. |
ALK_SANDBOX_MAX_CONCURRENCY, ALK_SANDBOX_PORT | 1, 8788 | dev | Concurrency and published port of the local sandbox server. |
FI_API_KEY, FI_SECRET_KEY | required by the local sandbox server | dev | Organization API key pair the local sandbox server files results with. Never set on the simulation runner. |
5. Internal: set by the compose files
The compose files set these in environment: blocks, which win over .env, or
supervisord sets them inside the app container. Changing them in .env does
nothing. Change what they are derived from instead, or use a
docker-compose.override.yml if you really mean it.
| Key | Set to | Setups | Derived from / why |
|---|---|---|---|
PG_HOST, PG_PORT, PGBOUNCER_HOST, PGBOUNCER_PORT | postgres, 5432 | S D | The bundled Postgres. |
CH_HOST, CH_HTTP_PORT, CH_USER | clickhouse, 8123, default | S D | The bundled ClickHouse. CH_PORT is 9000 inside the network (its host port in Distributed is the key of the same name). |
REDIS_HOST, REDIS_URL, REDIS_CACHE_URL, REDIS_LOCK_URL, REDIS_STATE_URL, CHANNEL_LAYER_BACKEND, CHANNEL_REDIS_URL | the bundled Redis, databases 0 to 3 | S D | REDIS_PASSWORD in Standalone. |
TEMPORAL_HOST | 127.0.0.1:7233 (S), temporal:7233 (D) | S D | The bundled Temporal. |
S3_ENDPOINT_URL, S3_ACCESS_KEY, S3_SECRET_KEY, S3_BUCKET | the bundled MinIO, bucket futureagi | S D | MINIO_ROOT_USER, MINIO_ROOT_PASSWORD. |
FI_PG_WRITE, FI_PG_READ, FI_CH_URL, FI_CH_USERNAME, FI_CH_PASSWORD, FI_AUTH_REDIS_ADDR, FI_AUTH_REDIS_PASSWORD, FI_GRPC_ADDR, FI_HTTP_ADDR, FI_ADMIN_ADDR, FI_DEAD_LETTER_FILE, FI_ERROR_FEED_KAFKA_BROKERS and the other FI_* collector settings | the collector’s addresses and credentials | S D | PG_*, REDIS_PASSWORD, CH_DATABASE, CH_USERNAME, CH_PASSWORD, the catalog keys above. |
FI_OBSERVED_CATALOG_MODE, FI_OBSERVED_CATALOG_CH_URL, FI_OBSERVED_CATALOG_CH_DATABASE, FI_OBSERVED_CATALOG_CH_USERNAME, FI_OBSERVED_CATALOG_CH_PASSWORD, FI_OBSERVED_CATALOG_SPOOL_DIR | S: direct, the catalog’s writer user, spool in /data/collector/observed-catalog; D: kafka and the FI_OBSERVED_CATALOG_KAFKA_* broker and topic | S D | How the collector hands on observed attributes. PROPERTY_CATALOG_DATABASE, PROPERTY_CATALOG_CONSUMER_PASSWORD, OBSERVED_CATALOG_KAFKA_TOPIC. FI_PROPERTY_CATALOG_MODE stays disabled: the collector refuses any other value of this retired key. |
FI_COLLECTOR_HOST | 127.0.0.1 (S), fi-collector (D) | S D | The setup checks probe the collector there, on its container port 4317 whatever FI_COLLECTOR_OTLP_PORT publishes on the host. |
PROPERTY_CATALOG_CH_HOST, PROPERTY_CATALOG_CH_PORT, PROPERTY_CATALOG_CH_USER, PROPERTY_CATALOG_CH_PASSWORD | the catalog’s read-only ClickHouse user | S D | PROPERTY_CATALOG_API_PASSWORD. |
DJANGO_SETTINGS_MODULE, SERVICE_TYPE, NO_STARTUP_DB_MUTATIONS, FI_SKIP_CH25_MIGRATION | fixed | S D | Only the bootstrap jobs change the database schema. |
FI_EMBEDDED_TEMPORAL_WORKER, TEMPORAL_GRACEFUL_SHUTDOWN_TIMEOUT | fixed | S | The embedded worker and its drain. |
TEMPORAL_TASK_QUEUE | one queue per worker | D | Per-queue workers. |
GEMINI_API_KEY | GOOGLE_API_KEY | S D | The gateway’s name for the Gemini key. |
AGENTCC_INTERNAL_URL, AGENTCC_GATEWAY_INTERNAL_URL | http://127.0.0.1:8080 (S), http://agentcc-gateway:8080 (D) | S D | The gateway’s container port, where the app and workers call it. A host-facing URL (the published AGENTCC_GATEWAY_PORT, :8090) exported in the shell must not replace this service-to-service route. Helm sets both to the gateway’s Service. |
AGENTCC_CONTROL_PLANE_URL, AGENTCC_CONTROL_PLANE_TOKEN, AGENTCC_SYNC_ON_STARTUP | the API (http://127.0.0.1:8000 in S, http://backend in D), AGENTCC_ADMIN_TOKEN, true | S D | The gateway loads the keys and org settings made in the UI from the app: on start, retrying while the app comes up, and then every minute (AGENTCC_SYNC_INTERVAL, on a gateway that reads it). It posts its request logs there too. Standalone starts its gateway after the bootstrap, so the app is up by then. |
Legacy and retired keys
Safe to leave in an old .env; nothing needs them.
| Key | Status |
|---|---|
FUTURE_AGI_CLOUD_API_KEY, FUTURE_AGI_CLOUD_API_URL | Retired: the compose files no longer pass them, and no code reads them. |
RABBITMQ_USER, RABBITMQ_PASSWORD | Retired with RabbitMQ; live updates use Redis. |
HOSTED_RUNNER_MAX_DURATION_SECONDS | Retired: no code reads it. Use HOSTED_RUNNER_MAX_WALLCLOCK_SECONDS. |
CH25_DROP_LEGACY_CDC_CHAIN | Legacy. Kept for explicit migration tooling; installs never read it at start. |
COMPOSE_PROFILES=full | Older name of the Distributed all profile; still accepted. On Standalone it has no effect. |
Older .env.example files also carried keys for features this page now
documents in their own section (voice simulation, hosted sandboxes, image
tags). Keeping them does no harm; empty values fall back to the defaults above,
except where a row says otherwise.
Production
Start from Distributed with the production overlay or the Helm chart.
deploy/docker-compose.production.yml layered on
docker-compose.distributed.yml, with values in deploy/.env.production,
refuses to start while a required value is empty
(deploy/README.md). Standalone suits a single host;
the same checklist applies to it. Work through the
production checklist.
Note
This page is generated from deploy/env-reference.toml in the
future-agi repository. To correct
a row, open a pull request there.
Dive deeper
Questions & Discussion