Configuration
This page highlights the key environment variables and deployment-mode differences for self-hosting.
Deployment Modes
Section titled “Deployment Modes”| Feature | SaaS | Enterprise |
|---|---|---|
| Org model | Personal org per user | Shared org for all users |
| Credits/Billing | Enabled (Stripe) | Disabled |
| URL pattern | /{username}/main | /{org_key}/{username} |
Client applications can read public config from GET /api/v1/config, including
deployment_mode and website_url.
Mode settings
Section titled “Mode settings”# SaaS mode (default)DEPLOYMENT_MODE=saas
# Enterprise modeDEPLOYMENT_MODE=enterpriseENTERPRISE_ORG_NAME="Acme Corp"ENTERPRISE_ORG_KEY="acme"Environment Variables
Section titled “Environment Variables”Use platform/envs/local.example.env as the reference for the full list. The table below highlights the most important values for self-hosting.
| Variable | Description | Example |
|---|---|---|
ENVIRONMENT | Runtime environment name | local |
DEPLOYMENT_MODE | SaaS or enterprise mode | saas |
WEBSITE_URL | Marketing website URL used for install script links | https://dreadnode.io |
DATABASE_HOST | Postgres host | localhost |
DATABASE_PORT | Postgres port | 5432 |
DATABASE_NAME | Postgres database name | dreadnode |
DATABASE_USER | Postgres user | postgres |
DATABASE_PASSWORD | Postgres password | postgres |
CLICKHOUSE_USER | ClickHouse user | default |
CLICKHOUSE_DATABASE | ClickHouse database | app |
S3_AWS_ENDPOINT_URL | S3/MinIO endpoint | http://localhost:9000 |
S3_AWS_EXTERNAL_ENDPOINT_URL | Public S3/MinIO endpoint | http://localhost:9000 |
S3_AWS_ACCESS_KEY_ID | S3 access key | minioadmin |
S3_AWS_SECRET_ACCESS_KEY | S3 secret key | minioadmin |
S3_AWS_DEFAULT_REGION | S3 region | us-east-1 |
PYTHON_PACKAGE_BUCKET_NAME | Bucket for packages | python-packages |
ORG_DATA_BUCKET_NAME | Bucket for org data | org-data |
USER_DATA_LOGS_BUCKET_NAME | Bucket for user logs | user-data-logs |
USER_DATA_ROLE_ARN | IAM role for user data uploads | arn:aws:iam::...:role/mock-role |
SECRET_KEY | App secret key | hex-32-bytes |
JWT_SECRET_KEY | JWT signing key | hex-32-bytes |
REFRESH_SECRET_KEY | Refresh token key | hex-32-bytes |
SECRETS_ENCRYPTION_KEY | Fernet key for secrets | base64-key |
SANDBOX_PROVIDER | Sandbox provider (docker or e2b) | docker |
SANDBOX_CUSTOM_DOMAIN | Custom sandbox URL domain | sandbox.dreadnode.io |
MAX_CONCURRENT_SANDBOXES_PER_ORG | Max concurrent running sandboxes per org | 3 |
MIN_SANDBOX_RUNTIME_SECONDS | Minimum per-sandbox runtime allowance (seconds) | 60 |
E2B_WORLDS_TEMPLATE_ALIAS | E2B alias for Worlds backends | dn-worlds-dev |
E2B_TRAINING_TEMPLATE_ALIAS | E2B alias for hosted training sandboxes | dn-training-dev |
E2B_OPTIMIZATION_TEMPLATE_ALIAS | E2B alias for hosted optimization sandboxes | dn-optimization-dev |
DOCKER_WORLDS_IMAGE | Docker image for Worlds backends | worlds:latest |
DOCKER_TRAINING_IMAGE | Docker image for hosted training sandboxes | dreadnode-training:latest |
DOCKER_OPTIMIZATION_IMAGE | Docker image for hosted optimization sandboxes | dreadnode-optimization:latest |
SANDBOX_SERVER_URL | Sandbox callback URL | http://host.docker.internal:3000 |
WORLDS_IN_PROCESS_WORKER_ENABLED | Run queued Worlds jobs inside the API process | true |
TRAINING_IN_PROCESS_WORKER_ENABLED | Run queued Tinker training jobs inside the API process | true |
TRAINING_IN_PROCESS_WORKER_CONCURRENCY | Max concurrent in-process training jobs | 1 |
TRAINING_IN_PROCESS_WORKER_POLL_INTERVAL_SEC | Poll interval for the in-process training worker | 2.0 |
TRAINING_IN_PROCESS_WORKER_LEASE_SECONDS | Lease duration for claimed training jobs | 3600 |
OPTIMIZATION_IN_PROCESS_WORKER_ENABLED | Run queued optimization jobs inside the API process | true |
OPTIMIZATION_IN_PROCESS_WORKER_CONCURRENCY | Max concurrent in-process optimization jobs | 1 |
OPTIMIZATION_IN_PROCESS_WORKER_POLL_INTERVAL_SEC | Poll interval for the in-process optimization worker | 2.0 |
OPTIMIZATION_IN_PROCESS_WORKER_LEASE_SECONDS | Lease duration for claimed optimization jobs | 3600 |
TINKER_BASE_URL | Override hosted training Tinker URL | https://tinker.example.com |
TINKER_API_KEY | API key injected into hosted training sandboxes | tml_... |
TINKER_OPENAI_BASE_URL | OpenAI-compatible Tinker URL for Worlds agent checkpoints | https://tinker.example.com/oai/api/v1 |
LITELLM_ENABLED | Enable LiteLLM proxy | true |
LITELLM_INTERNAL_URL | Internal LiteLLM URL | http://localhost:4000 |
LITELLM_PUBLIC_URL | Public LiteLLM URL | http://host.docker.internal:4000/v1 |
LITELLM_MASTER_KEY | LiteLLM master API key | sk-dev-master-key |
LITELLM_TUI_KEY_DURATION_SECONDS | TTL for TUI-provisioned LiteLLM keys (seconds) | 86400 |
LITELLM_CALLBACK_ENDPOINT | LiteLLM usage callback URL | http://api:8000/api/v1/internal/litellm/usage |
LITELLM_CALLBACK_SECRET | Shared secret for LiteLLM callbacks | local-callback-secret |
LITELLM_RECONCILIATION_INTERVAL_SECONDS | Poll interval for spend logs (seconds) | 300 |
LITELLM_RECONCILIATION_LOOKBACK_SECONDS | Lookback window for spend logs (seconds) | 600 |
CORS_ORIGINS | Allowed browser origins | [...] |
USE_DUCKDB | Use DuckDB for traces | false |
DUCKDB_PATH | DuckDB file path | ./data/otel_traces.duckdb |
RECAPTCHA_ENABLED | Enable reCAPTCHA for signup | false |
REQUIRE_EMAIL_VERIFICATION | Require email verification | false |
INFERENCE_CREDITS_PER_DOLLAR | Credits per $1 of inference cost | 1000 |
STRIPE_PRICE_ID | Stripe price ID (credits) | price_... |
STRIPE_SECRET_KEY | Stripe API secret | sk_... |
STRIPE_WEBHOOK_SECRET | Stripe webhook secret | whsec_... |
Secrets management
Section titled “Secrets management”Environment files live under platform/envs/. For local development, copy platform/envs/local.example.env to platform/envs/local.env, or run just setup to generate secrets automatically. Production secrets should be managed with the platform/bin/env tooling rather than editing encrypted files directly.
Database migrations
Section titled “Database migrations”# Run pending migrationsjust migrate
# Create a new migration (always autogenerate)just migrate-new "add-field"Never hand-write migration files — always use --autogenerate to keep the revision chain consistent.