Configuration Reference
TeamWeb AI is configured almost entirely from the Settings UI at runtime: LLM providers, embedding models, communication channels, MCP servers, and tool plugins are all chosen and credentialed through the database, not the environment. The environment variables documented here cover only the infrastructure plumbing — what to connect to, where to store files, and how the public-facing URLs are built.
Anything that looks LLM-shaped (model names, API keys, embedding model selection, etc.) belongs in Settings.
Core variables
These are set in .env for local development and in .env.prod (created
from deploy/.env.prod.example) for production. Every value listed as
“required” must be present.
| Variable | Required | Description |
|---|---|---|
SECRET_KEY | yes | Flask session signing key. Generate with python3 -c "import secrets; print(secrets.token_urlsafe(64))". |
SECRETS_ENCRYPTION_KEY | yes | Base64-encoded 32-byte AES-256-GCM key. Encrypts LLM provider API keys, OAuth refresh tokens, MCP credentials, channel plugin tokens, and system webhook signing secrets at rest. The app refuses to start without it; rotating it without a re-encryption step makes existing rows unreadable. See Secrets. |
DATABASE_URL | yes | PostgreSQL connection string. |
POSTGRES_PASSWORD | yes | Password used by the bundled db Compose service. Must match the password embedded in DATABASE_URL. |
REDIS_URL | yes | Redis connection string. Used as the Celery broker, Celery result backend, and Flask-Limiter storage. |
PUBLIC_URL | yes | Public base URL (with scheme, no trailing slash). Used for absolute links in emails, webhooks, and widget embeds. |
FLASK_ENV | no | development (default in .env.example) or production. Selects the config class. |
DOMAIN | prod only | Bare domain name for Caddy’s automatic HTTPS provisioning. Production only — see Deployment. |
| Variable | Description |
|---|---|
POSTMARK_SYSTEM_TOKEN | Postmark server token used for system notifications (digests, alerts) that are not tied to an assistant. Per-assistant email channels are configured through the Channels page. |
EMAIL_FROM_ADDRESS | Sender address for system notifications. |
Media storage
By default uploads and generated assets are stored in the media_data
volume on the local filesystem. Switch to S3 (or any S3-compatible service
such as MinIO or Backblaze B2) by setting MEDIA_STORAGE_BACKEND=s3 and
the S3 credentials.
| Variable | Default | Description |
|---|---|---|
MEDIA_STORAGE_BACKEND | local | local or s3. |
MEDIA_ROOT | /app/media | Filesystem path when the backend is local. |
S3_BUCKET_NAME | — | Bucket name. |
S3_ENDPOINT_URL | — | S3-compatible endpoint URL. Leave blank for AWS S3. |
S3_ACCESS_KEY_ID | — | Access key. |
S3_SECRET_ACCESS_KEY | — | Secret key. |
S3_REGION | us-east-1 | Region. |
S3_PREFIX | media/ | Key prefix prepended to every stored object. |
Embedding model cache
The active embedding model is chosen in Settings → Embedding, but the model files themselves need somewhere on disk to live.
| Variable | Default | Description |
|---|---|---|
EMBEDDING_CACHE_DIR | /data/models | Directory the sentence-transformers cache is written to. Mounted as a Docker volume in the bundled Compose files. |
Datasets
| Variable | Default | Description |
|---|---|---|
DATASETS_READONLY_DATABASE_URL | falls back to DATABASE_URL | Read-only DSN used by sandboxed SQL execution in the datasets feature. Point it at a Postgres role that has SELECT only on dataset tables. |
OAuth
| Variable | Description |
|---|---|
OAUTH_REDIRECT_BASE_URL | Override for the base URL used to build /oauth/callback. Useful when PUBLIC_URL uses a hostname OAuth providers reject (e.g. http://app.teamwebai.localhost) while http://localhost:5050 would be accepted. |
Plugin cache
| Variable | Default | Description |
|---|---|---|
PLUGIN_CACHE_DIR | /tmp/plugin_cache | Ephemeral directory where DB-stored plugins are extracted for import. Safe to wipe — rebuilt on demand. |
Widget rate limits
The embeddable chat widget has three independent rate limits, all backed by Redis and shared across workers.
| Variable | Default | Description |
|---|---|---|
WIDGET_RATE_LIMIT_MESSAGES_PER_MIN | 10 | Messages per minute per conversation. |
WIDGET_RATE_LIMIT_PER_IP_PER_MIN | 30 | Messages per minute per client IP, across all conversations. |
WIDGET_RATE_LIMIT_NEW_CONVOS_PER_HOUR | 5 | New widget conversations per hour per client IP. |
Docker networking
| Variable | Default | Description |
|---|---|---|
DOCKER_NETWORK | teamwebai_default | Compose network the worker attaches MCP containers to. The default matches docker compose running from the repo root; production overrides this to the named teamwebai network. Set it to your <project>_default if you run Compose with a custom -p project name. |
Browser automation
These tune the managed browser sessions used by the browser plugin. All default values are sensible for UK-based deployments; override them if you want a different locale, timezone, fingerprint, or session retention policy.
| Variable | Default | Description |
|---|---|---|
BROWSER_DEFAULT_BACKEND | local_managed | Which browser backend new sessions default to. |
BROWSER_PROFILE_ROOT | /tmp/teamwebai_browser_profiles | Where per-session browser profiles are written. |
BROWSER_HEADLESS | true | Run Chromium headless. |
BROWSER_NO_SANDBOX | true | Pass --no-sandbox to Chromium (required inside Docker). |
BROWSER_USER_AGENT | desktop Linux Chrome | Override the user-agent string. |
BROWSER_LOCALE | en-GB | Browser locale. |
BROWSER_TIMEZONE | Europe/London | Browser timezone. |
BROWSER_VIEWPORT_WIDTH | 1446 | Viewport width in pixels. |
BROWSER_VIEWPORT_HEIGHT | 934 | Viewport height in pixels. |
BROWSER_ALLOW_PRIVATE_NETWORK | false | Allow navigation to RFC 1918 / loopback addresses. |
BROWSER_ALLOWED_HOSTNAMES | (empty) | Comma-separated allow-list of hostnames the browser may reach. Empty means no restriction. |
BROWSER_SESSION_IDLE_MINUTES | 60 | Minutes a browser session can sit idle before being reaped. |
BROWSER_SESSION_RETENTION_DAYS | 7 | Days completed sessions are retained on disk. |
Configured in the Settings UI
The following are configured under Settings and stored encrypted in the database:
- LLM provider API keys and OAuth tokens — Settings → LLM Providers.
Anthropic, OpenAI, and Ollama each store their credentials on the
plugin’s
CorePluginConfigrow. - Embedding model name — Settings → Embedding. The local
sentence_transformersplugin keeps its model name (e.g.all-MiniLM-L6-v2) in itsconfig_json. - OpenAI image generation / WebRTC voice keys — set on the
openai_imagingandopenai_realtimeplugin rows. - Postmark per-assistant tokens — set on each Postmark channel.