Durabull Documentation

Environment Variables

Configure runtime modes, Redis connections, persistence, authentication, integrations, and telemetry.

For source-based runs, copy the repository's .env.example to .env and replace its placeholders. Shell variables take precedence over dotenv values. Restart the API after changing configuration.

For Docker, explicitly pass settings with -e, --env-file, or the container's Compose environment block. A Compose substitution file does not automatically become container configuration; see Docker configuration.

Core runtime

VariableDefaultPurpose
NODE_ENVUnsetdevelopment, test, or production; set production for deployments. Production images already set it.
PORT3001 outside production; 3000 in productionAPI listening port.
APP_BASE_URLhttp://localhost:5173Public app origin used by auth, invitations, and MCP. Set explicitly for any deployed origin.
VITE_PUBLIC_APP_URLUnsetBrowser app URL fallback; normally match APP_BASE_URL. Vite embeds client environment values at build time.
DURABULL_AUTHLESSfalseBypass login and grant owner access. Use only in trusted local/private environments.
DURABULL_ENV_CONNECTIONSfalseManage Redis connections through environment variables instead of UI/API create/edit/delete.
TRUST_PROXYfalseHonor forwarding headers for rate-limit keys; enable only behind a proxy that controls those headers. Cloud enables this behavior automatically.
DISABLE_RATE_LIMITfalseDisable all in-memory API and MCP rate limits. Keep unset in production.

Boolean settings in the shared environment schema accept true/false, 1/0, yes/no, and on/off. Use true or false in deployment configuration for clarity.

Authentication

VariableRequirementPurpose
BETTER_AUTH_SECRETAuthenticated deployments; required by the shipped self-hosted Compose fileSession and OAuth secret. Generate a long random value.
GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRETBoth needed for Google sign-inGoogle OAuth credentials.
GITHUB_OAUTH_CLIENT_ID, GITHUB_OAUTH_CLIENT_SECRETBoth needed for GitHub sign-inGitHub OAuth credentials.
MCP_AUTHLESS_BEARER_TOKENRequired when authless and NODE_ENV=productionBearer token for MCP only; does not protect the web UI or REST API.

Email/password authentication is enabled without social providers. Register OAuth callbacks at {APP_BASE_URL}/api/auth/callback/google and {APP_BASE_URL}/api/auth/callback/github. In normal Vite development, the origin is http://localhost:5173.

Persistence and encryption

VariableDefault / requirementPurpose
DATABASE_URLOptionalSet to use PostgreSQL; empty or unset uses file-backed PGlite.
DURABULL_PGLITE_DIRdata/pglite relative to the API working directoryPGlite storage directory; preserve it across restarts.
DURABULL_REDIS_URL_ENCRYPTION_KEYRequired when saving or synchronizing Redis connections32-byte encryption key encoded as 64 hexadecimal characters or base64.
DURABULL_SECRET_ENCRYPTION_KEYRequired for persisted integration/signing secretsSeparate 32-byte key for Linear OAuth tokens and webhook signing secrets.
REDIS_URLOptionalRedis URL used by development/seed scripts and as a workload fallback; does not configure an API connection by itself.
DURABULL_POSTGRES_PORT55432Host port for the development Docker PostgreSQL service. Match DATABASE_URL.
DURABULL_REDIS_PORT56379Host port for the development Docker Redis service. Match REDIS_URL.

Generate each encryption key separately with openssl rand -hex 32, then paste the result into configuration. Dotenv files do not evaluate $(...). Preserve the keys with your backups; replacing a key without re-encrypting existing data makes that data unreadable.

Environment-managed Redis connections

Set DURABULL_ENV_CONNECTIONS=true and define one or more named connections:

VariableDefault / requirementPurpose
DURABULL_REDIS_URL_<NAME>At least one valid connection needed for queue operationsRedis URL (redis:// or rediss://). Names begin with a letter and use uppercase letters, digits, or underscores.
DURABULL_REDIS_URL_<NAME>_ENVIRONMENTdevelopmentdevelopment, staging, or production; invalid labels fall back to development.
DURABULL_REDIS_URL_<NAME>_PREFIXbullBullMQ key prefix, matching your queues and workers.
DURABULL_REDIS_URL_<NAME>_ALLOW_SELF_SIGNED_CERTSfalseDisable certificate-authority validation for this connection when the provider requires it. Use with rediss://.
DURABULL_REDIS_URL_DEFAULTFirst valid name alphabeticallyDefault connection key, such as MAIN.
DURABULL_ENV_CONNECTIONS=true
DURABULL_REDIS_URL_MAIN=rediss://user:password@redis.example.com:6379/0
DURABULL_REDIS_URL_MAIN_ENVIRONMENT=production
DURABULL_REDIS_URL_MAIN_PREFIX=bull
DURABULL_REDIS_URL_DEFAULT=MAIN

Replace the example credentials and host. These connections still use encrypted database rows, so DURABULL_REDIS_URL_ENCRYPTION_KEY is required.

Alerts and Redis health history

VariableDefaultPurpose
DURABULL_ALERT_ENABLEDtrueEvaluate alert rules. Redis health history has its own collection toggle.
DURABULL_ALERT_POLL_INTERVAL_MS60000 (minimum 5000)Polling interval for queue alerts and Redis health sampling.
DURABULL_ALERT_JOB_RESOLVE_INTERVAL_MS300000 (minimum 30000)Interval for checking job-failure incidents for recovery.
DURABULL_REDIS_HEALTH_HISTORY_ENABLEDtrueStore Redis health samples for Analytics independently of alert evaluation.
DURABULL_REDIS_HEALTH_RETENTION_DAYS30 (clamped to 1–30)Redis health history retention.
DURABULL_WEBHOOK_ALLOW_HTTPfalseAllow HTTP webhook targets for testing. Does not allow private or localhost targets. Development mode also permits HTTP.

Email and Linear

VariableDefault / requirementPurpose
RESEND_API_KEYOptionalSend invitation and alert emails through Resend.
EMAIL_FROMDurabull <no-reply@durabull.io>Sender address. Self-hosted Resend accounts should use their own verified domain.
LINEAR_OAUTH_CLIENT_ID, LINEAR_OAUTH_CLIENT_SECRETBoth needed for LinearOAuth application credentials.
LINEAR_OAUTH_REDIRECT_URI{APP_BASE_URL}/api/alerts/integrations/linear/callbackCallback override when the API has a different public origin.
LINEAR_OAUTH_ACTORuserUse app only when the Linear application is configured for app actor authorization.

Register the exact callback URL in Linear and set DURABULL_SECRET_ENCRYPTION_KEY before connecting. See Linear Integration and Webhook Notifications for setup and delivery behavior.

PostHog

VariableDefaultPurpose
POSTHOG_KEYUnsetSend the full PostHog browser analytics stream to your project.
POSTHOG_HOSThttps://us.i.posthog.comPostHog ingestion host, such as https://eu.i.posthog.com for EU Cloud.

The web app obtains PostHog configuration from GET /api/app/config; no VITE_ prefix is needed. The API proxies browser analytics through /ingest. Set POSTHOG_HOST to the ingestion host, not your app's /ingest URL.

Anonymous usage telemetry

Production Durabull, including desktop and self-hosted builds, collects anonymous/pseudonymous usage telemetry. Collection is disabled in development, test, and CI. Configuring POSTHOG_KEY for your own project does not disable Durabull telemetry, and there is no product-level opt-out.

Durabull's sanitized telemetry includes feature and route usage, safe runtime context, booleans, enums, and aggregate count/duration buckets. It excludes Redis URLs, queue names, Redis key names, job data, logs, emails, names, organizations, hostnames, raw URLs, search patterns, stack traces, and raw error messages. This field restriction applies to the sanitized Durabull stream; your configured PostHog project receives its full browser analytics stream.

MCP analytics additionally records tool/resource names, OAuth stages, scope counts, client and protocol metadata, event times, outcomes, and durations. Where configured, hashed user, service-account, organization, client, connection, session, and request identifiers associate activity across requests. These are pseudonymous identifiers, not a guarantee of anonymity. The separate browser PostHog stream can include identified user and organization profiles, page URLs, interactions, and exception diagnostics. See the Privacy Policy for data uses, recipients, retention, and available controls.

Self-hosted instances forward sanitized batches to Durabull's existing cloud API. They do not need a separate collector service. These settings support forwarding and cloud collector operation:

VariablePurpose
DURABULL_TELEMETRY_COLLECT_SECRETHMAC signing secret for forwarded batches and collector verification. Forwarding is skipped when no signing secret is available.
DURABULL_TELEMETRY_HMAC_SECRETDedicated HMAC secret for pseudonymous identifiers; not derived from BETTER_AUTH_SECRET.
DURABULL_CLOUDEnable Durabull Cloud collector behavior and trusted-proxy handling. Do not enable on an ordinary self-hosted instance.
DURABULL_TELEMETRY_POSTHOG_KEYCollector's Durabull telemetry destination; falls back to POSTHOG_KEY.
DURABULL_TELEMETRY_POSTHOG_HOSTCollector's telemetry ingestion host.

Backpressure emits stdout JSON with type: "telemetry_queue" and signal: "queue_dropped". These signals contain operational queue identifiers and counters rather than product payloads. See the MCP operations runbook.

MCP and asset serving

MCP is always mounted at {APP_BASE_URL}/mcp; there is no enable flag or separate port.

VariableDefaultPurpose
MCP_TELEMETRY_LOGEnabledSet false to suppress stdout mcp_telemetry logs.

ASSET_PRELOAD_MAX_SIZE and ASSET_PRELOAD_VERBOSE_LOGGING are accepted by the environment schema but are not consumed by the current API static-file serving implementation.

See MCP Server for OAuth scopes and client setup.

Example authenticated deployment

Use this as a configuration template, replacing every placeholder before starting:

NODE_ENV=production
APP_BASE_URL=https://your-domain.example
VITE_PUBLIC_APP_URL=https://your-domain.example
DURABULL_AUTHLESS=false
BETTER_AUTH_SECRET=<long-random-secret>
DATABASE_URL=postgresql://user:password@postgres.example.com:5432/durabull
DURABULL_REDIS_URL_ENCRYPTION_KEY=<64-character-hex-key>
DURABULL_ENV_CONNECTIONS=true
DURABULL_REDIS_URL_MAIN=rediss://user:password@redis.example.com:6379/0
DURABULL_REDIS_URL_MAIN_ENVIRONMENT=production
DURABULL_REDIS_URL_MAIN_PREFIX=bull
DURABULL_REDIS_URL_DEFAULT=MAIN

Add DURABULL_SECRET_ENCRYPTION_KEY if you configure Linear or webhook signing. Review Security and Hardening before publishing the app.