Core environment variables are centralized in api/constants.py. Variables marked Required in the description must be explicitly set β the application will either fail to boot or behave insecurely without them.
Deployment Modes
Peachdesk supports two deployment modes, set via DEPLOYMENT_MODE:
- OSS: The default mode. Designed for self-hosted deployments using Docker Compose β the fastest way to get Peachdesk running. Uses local JWT authentication and MinIO for storage.
- SaaS: Intended for customised deployments outside of Docker. Authentication and API key management are handled through Peachdesk Managed Platform Services (MPS), allowing greater flexibility in how the platform is hosted and integrated.
The relevant required variables for each mode are noted in the descriptions below.
Application
| Variable | Default | Description |
|---|
ENVIRONMENT | local | Runtime environment. Affects logging and behaviour. One of local, production, test |
DEPLOYMENT_MODE | oss | Deployment mode. Use oss for self-hosted |
AUTH_PROVIDER | local | Authentication provider. Use local for OSS |
Database
| Variable | Default | Description |
|---|
DATABASE_URL | N/A | Required. PostgreSQL connection string. e.g. postgresql+asyncpg://user:pass@host:5432/dbname |
REDIS_URL | N/A | Required. Redis connection string. e.g. redis://localhost:6379 |
Authentication (OSS)
| Variable | Default | Description |
|---|
OSS_JWT_SECRET | N/A | Required for OSS deployments. Secret used to sign JWT tokens. Must be set to a strong random value in production |
OSS_JWT_EXPIRY_HOURS | 720 | JWT token lifetime in hours (default: 30 days) |
Never use the placeholder OSS_JWT_SECRET in a production deployment. Generate a strong random secret and store it securely.
| Variable | Default | Description |
|---|
BACKEND_API_ENDPOINT | http://localhost:8000 | Internal URL of the backend API |
UI_APP_URL | http://localhost:3010 | URL of the frontend application |
MPS_API_URL | http://localhost:8000 | Base URL of the self-hosted Model Proxy Service (the APIβs own URL). Use https://api.peachdeskai.com for the hosted platform. |
PEACHDESK_MPS_SECRET_KEY | null | Required for non-OSS deployments. Secret key for authenticating with MPS |
Storage
Peachdesk uses MinIO by default, which is bundled with the self-hosted deployment and requires no external setup. Set ENABLE_AWS_S3=true to switch to AWS S3 β typically used for cloud or managed deployments where S3 is already part of the infrastructure.
MinIO (OSS default)
| Variable | Default | Description |
|---|
MINIO_ENDPOINT | localhost:9000 | MinIO server host and port |
MINIO_PUBLIC_ENDPOINT | null | Publicly accessible MinIO URL (for download links) |
MINIO_ACCESS_KEY | N/A | Required for OSS deployments. MinIO access key. Must be set to a secure value in production |
MINIO_SECRET_KEY | N/A | Required for OSS deployments. MinIO secret key. Must be set to a secure value in production |
MINIO_BUCKET | voice-audio | Bucket name for audio files |
MINIO_SECURE | false | Use HTTPS for MinIO connections |
AWS S3 (alternative)
| Variable | Default | Description |
|---|
ENABLE_AWS_S3 | false | Set to true to use AWS S3 instead of MinIO |
S3_BUCKET | null | S3 bucket name |
S3_REGION | us-east-1 | AWS region |
| Variable | Default | Description |
|---|
TURN_HOST | localhost | TURN server hostname for WebRTC NAT traversal |
TURN_PORT | 3478 | TURN server port |
TURN_TLS_PORT | 5349 | TURN server TLS port |
TURN_SECRET | null | Required for WebRTC. Shared secret for TURN credential generation |
TURN_CREDENTIAL_TTL | 86400 | TURN credential validity in seconds (default: 24h) |
FORCE_TURN_RELAY | false | Diagnostic flag. When true, restricts ICE to relay-only candidates on both server (SDP filter) and browser (iceTransportPolicy: 'relay'). Use to verify TURN connectivity end-to-end β calls fail cleanly if TURN is misconfigured instead of silently falling back to a direct path. |
Tracing (Langfuse)
| Variable | Default | Description |
|---|
LANGFUSE_HOST | null | Langfuse server URL |
LANGFUSE_PUBLIC_KEY | null | Langfuse public key |
LANGFUSE_SECRET_KEY | null | Langfuse secret key |
Tracing activates automatically as soon as credentials are available β either via these environment variables (applied to all organizations) or per-organization in the UI under Platform Settings. If neither is set, spans are dropped silently. See the Tracing guide for setup instructions.
Monitoring
| Variable | Default | Description |
|---|
SENTRY_DSN | null | Sentry DSN for error tracking |
ENABLE_TELEMETRY | false | Enable anonymous telemetry collection |
Logging
| Variable | Default | Description |
|---|
LOG_LEVEL | DEBUG | Log level: DEBUG, INFO, WARNING, ERROR |
LOG_FILE_PATH | null | Write logs to this file path (in addition to stdout) |
LOG_ROTATION_SIZE | 100 MB | Rotate log file when it reaches this size |
LOG_RETENTION | 7 days | How long to keep rotated log files |
LOG_COMPRESSION | gz | Compression format for rotated logs |
SERIALIZE_LOG_OUTPUT | false | Output logs as JSON (useful for log aggregation) |
Campaigns
| Variable | Default | Description |
|---|
DEFAULT_ORG_CONCURRENCY_LIMIT | 2 | Maximum concurrent outbound calls per organization |
Billing & Credits (Stripe)
Billing is opt-in and SaaS-only. Leave it off for OSS / on-premises /
Enterprise self-host deployments β usage is then unlimited, the billing routes
return 404, and no Stripe client is constructed.
| Variable | Default | Description |
|---|
ENABLE_BILLING | true if DEPLOYMENT_MODE=saas, else false | Master switch. When true: new orgs get a free credit allowance, managed (PeachDesk-keyed) calls consume credits, and the Stripe routes are mounted. BYOK calls (the userβs own provider keys) always run free and are never gated. |
FREE_TIER_CREDIT_TOKENS | 100 | Free managed credits granted to each new org (1 token = 1 US cent of managed cost; 100 β $1.00 β ~10β13 min). |
PEACHDESK_QUOTA_RESERVE_TOKENS | 1 | Tokens reserved at call admission (refunded at reconcile, so calls are charged actual cost). |
STRIPE_SECRET_KEY | β | Stripe secret key. The Stripe routes go live only when this is set and ENABLE_BILLING is true. Store in a secret manager, never in the repo. |
STRIPE_WEBHOOK_SIGNING_SECRET | β | whsec_β¦ for verifying webhook signatures. The webhook returns 503 until set. |
STRIPE_PUBLISHABLE_KEY | β | Publishable key (not required for hosted checkout; included for completeness). |
STRIPE_PRICE_PLAN_PRO, STRIPE_PRICE_PLAN_ENTERPRISE | β | Stripe recurring Price IDs for subscription plans. Only plans with a Price ID set appear in the catalog. |
STRIPE_PLAN_PRO_TOKENS, STRIPE_PLAN_ENTERPRISE_TOKENS | 0 | Recurring credit allowance granted each cycle for each plan. |
STRIPE_PRICE_TOPUP_SMALL, _MEDIUM, _LARGE | β | Stripe one-off Price IDs for credit top-up packs. |
STRIPE_TOPUP_SMALL_TOKENS, _MEDIUM_TOKENS, _LARGE_TOKENS | 0 | Credits granted per top-up pack. |
BILLING_SUCCESS_URL, BILLING_CANCEL_URL | {UI_APP_URL}/billing?status=β¦ | Stripe redirect targets after hosted checkout. |
To enable billing in a non-saas deployment (for example DEPLOYMENT_MODE=enterprise),
set ENABLE_BILLING=true and populate STRIPE_SECRET_KEY (plus the webhook
signing secret and at least one Price ID). With ENABLE_BILLING=true but no
Stripe key, free-tier credit limiting still applies and exhausted users can add
their own provider keys (BYOK), but the purchase and subscribe routes stay
disabled until the Stripe secret is configured.
A superadmin (is_superuser) can view every organizationβs token usage and
balances, and grant credits manually, at /admin/credits (API:
GET /api/v1/admin/credits/overview, POST /api/v1/admin/credits/grant).
Further Customisation
The variables documented here cover the standard configuration surface. For advanced customisation β such as integrating additional services or tuning internal behaviour β consult the relevant module alongside api/constants.py to understand how each variable is consumed.