Venelx Docs

Environment Variables

Every variable across the Venelx components, grouped by where it's set. Annotated, commit-safe templates live in the monorepo under env/*.env.example — regenerate local .env files from them with ./scripts/bootstrap-env.sh all.

Key split rules

The most common misconfiguration is putting a variable on the wrong process. The rules:

VariableAPI (venelx-backend)Worker (venelx-worker)
VENELX_DEPLOY_ROLEapiworker
RUN_QUEUE_WORKERfalsetrue
WORKER_AGENT_ONLYunsettrue
B2_*all setomit — use B2_UPLOAD_VIA_API=true
EXPO_TOKEN, OUTPUT_DIR, PROJECT_DIRomitset
WORKER_AGENT_TOKENset (ops fleet)same value as API or WORKER_PAIRING_TOKEN (customer workers)
CORS_ORIGINSsetomit
NEXT_PUBLIC_*frontend / Vercel only

Frontend (Vercel — venelx-frontend)

Template: env/vercel.env.example. Redeploy after changing any NEXT_PUBLIC_* value.

VariableExamplePurpose
NEXT_PUBLIC_API_URLhttps://api.venelx.comBase URL the browser calls for the REST API
NEXT_PUBLIC_WS_URLwss://api.venelx.comWebSocket base URL (live logs, worker updates)
NEXT_PUBLIC_PRODUCT_NAMEVenelxProduct name shown in the UI

The API must allow these origins back: set CORS_ORIGINS on venelx-backend to include your production and preview dashboard URLs.

API (venelx-backend)

Template: env/api.env.example (cloud) / env/backend-selfhost-mac.env.example (Mac + tunnel).

Process role & networking

VariableDefault / examplePurpose
NODE_ENVproductionNode environment
VENELX_DEPLOY_ROLEapiStartup guard — must be api on the control plane
PORT4000HTTP listen port
LISTEN_HOST0.0.0.0 (cloud) / 127.0.0.1 (Mac + tunnel)Bind address; only the tunnel should reach the port on a Mac
RUN_QUEUE_WORKERfalseMust stay false in production — no queue consumer on the API
WORKER_AGENT_ONLYunsetNever set on the API (worker-only mode)
WORKER_STRICTtrueRoute jobs only to workers advertising the platform
CORS_ORIGINShttps://app.venelx.com,https://*.vercel.appAllowed browser origins
PUBLIC_DOMAINapi.venelx.comPublic hostname of the API
PUBLIC_API_URLhttps://api.venelx.comExternal base URL — webhooks + GitHub callback must reach this
PUBLIC_APP_URLhttps://app.venelx.comWeb dashboard URL for invites, auth links, email CTAs

Auth

VariablePurpose
API_SECRETLegacy/API-level secret
AUTH_USERNAME / AUTH_PASSWORDBootstrap admin credentials
AUTH_JWT_SECRETSigns session JWTs
AUTH_TOKEN_TTL_HOURSSession token lifetime (default 12)
REFRESH_TOKEN_SECRETSigns refresh tokens
REQUIRE_EMAIL_VERIFICATION / SKIP_EMAIL_VERIFICATIONEmail-verification flow toggles

Database & queue

VariablePurpose
MONGODB_URIMongoDB Atlas connection string (Prisma)
MONGODB_DB_NAMEDatabase name (default expo_forge)
DATABASE_URLSame Mongo URI, for Prisma tooling
REDIS_URLBullMQ queue — Upstash rediss://... in split prod, redis://127.0.0.1:6379 on a Mac
BUILD_QUEUE_CONCURRENCYJobs dequeued in parallel (default 2)
DISABLE_REDISSet true only for customer-worker-only fleets without BullMQ

Worker fleet

VariablePurpose
WORKER_AGENT_TOKENShared secret for ops workers + internal routes (generate: openssl rand -hex 24)
WORKER_HEARTBEAT_STALE_MSMark a worker offline after this much silence (default 120000)
WORKER_HEARTBEAT_WRITE_MIN_MSMin gap between heartbeat DB writes (default 45000)
WORKER_INSTALLER_VERSION / WORKER_INSTALLER_BASE_URLVersion + download base served for worker installers
BACKEND_INSTALLER_VERSION / BACKEND_INSTALLER_BASE_URLSame, for the self-host backend installer

Product & encryption

VariablePurpose
PRODUCT_NAMEProduct name (Venelx)
FORGE_MASTER_SECRETMaster secret encrypting signing material / vault
SIGNING_VAULT_MODEVault mode (ephemeral)

GitHub / GitLab

See the GitHub guide for the full GITHUB_* table (OAuth client, callback URL, app slug, token sweep interval, PAT fallbacks). GitLab equivalents: GITLAB_CLIENT_ID, GITLAB_CLIENT_SECRET, GITLAB_HOST (optional).

AI, email, webhooks (optional)

VariablePurpose
GEMINI_API_KEY / OPENAI_API_KEYAI-assisted features
SMTP_HOST / SMTP_PORT / SMTP_USER / SMTP_PASS / SMTP_FROM / SMTP_TOOutgoing email (Zoho SMTP in templates)
SLACK_WEBHOOK_URL / OUTBOUND_WEBHOOK_URLSAlert webhooks
PR_PREVIEW_PLATFORMSPlatforms auto-built on PRs (default android-preview)

Artifacts (Backblaze B2) — API only

VariablePurpose
B2_KEY_ID / B2_APP_KEYB2 credentials
B2_BUCKET_NAMEArtifact bucket
B2_ENDPOINT / B2_REGIONS3-compatible endpoint + region
B2_CDN_BASE_URLOptional CDN base for downloads
B2_DELETE_LOCAL_AFTER_UPLOADFree API disk after upload
ARTIFACT_KEEP_COUNTArtifacts retained per project/platform (default 5)
ARTIFACT_PURGE_INTERVAL_HOURSRetention sweep interval (default 24)

Billing (Lemon Squeezy)

VariablePurpose
LEMONSQUEEZY_WEBHOOK_SECRETWebhook HMAC verification (shared by all plans)
LEMONSQUEEZY_STORE_ID / LEMONSQUEEZY_STORE_SLUGStore identifiers
LEMONSQUEEZY_VARIANT_ID_PROPro plan variant
LEMONSQUEEZY_VARIANT_ID_WORKER_ANNUALSelf-hosted worker annual plan (includes 2 slots)
LEMONSQUEEZY_VARIANT_ID_WORKER_SLOT_ADDONExtra worker slot add-on
LEMONSQUEEZY_API_KEY / LEMONSQUEEZY_TEST_MODEAPI access / test mode

Misc

VariablePurpose
FIREBASE_SERVICE_ACCOUNT_PATHFCM service-account JSON path (push notifications)
VENELX_FASTLANE_DIRfastlane runtime for store submit (install once via scripts/install-fastlane-runtime.sh)
TAILSCALE_IPOptional Tailscale CORS allowlist
OUTPUT_DIR / OTA_BUNDLE_DIRLocal paths (Mac self-host; default ~/.venelx/...)

Worker (venelx-worker)

Templates: env/worker-mac.env.example (macOS, iOS ± Android) / env/worker-linux.env.example (Linux/WSL2, Android).

VariableDefault / examplePurpose
VENELX_DEPLOY_ROLEworkerStartup guard
WORKER_AGENT_ONLYtrueWorker-only mode — no user-facing HTTP
RUN_QUEUE_WORKERtrueConsume BullMQ jobs
WORKER_STRICTtrueConsume only this worker's named queue (recommended for fleets)
WORKER_NAMEmac-ios-1Unique per machine
WORKER_PLATFORMSios / android-preview,android-productionPlatforms this worker accepts — drives scheduler routing
API_URLhttps://api.venelx.comControl plane base URL
MAIN_HOST127.0.0.1Legacy host hint when API shares the Mac
REDIS_URLsame as APIBullMQ queue (must match the API exactly)
MONGODB_URI / DATABASE_URL / MONGODB_DB_NAMEsame as APIJob status updates via Prisma
WORKER_AGENT_TOKENsame as APIOps-fleet auth — customer workers use WORKER_PAIRING_TOKEN instead
WORKER_PAIRING_TOKENfrom dashboardOne-time pairing token for customer self-hosted workers
VENELX_WORKER_CONFIG~/.venelx/worker.envConfig file path for installed customer workers
FORGE_MASTER_SECRETsame as APIDecrypts signing material at build time
B2_UPLOAD_VIA_APItrueUpload artifacts via API presign — no B2 keys on workers
OUTPUT_DIR~/.venelx/buildsBuild workspace (clones, logs, local artifacts)
PROJECT_DIR / REPO_ROOThost pathsOptional fixed checkouts
EXPO_TOKENExpo/EAS access for npm + EAS-managed steps
SKIP_PREBUILDfalseSkip Expo prebuild step
BUILD_TIMEOUT_MINUTES60Per-build timeout
ANDROID_HOME/opt/android-sdkAndroid SDK location (Android workers)
ANDROID_SERVICE_ACCOUNT_KEYpath to JSONPlay service account for submit
ANDROID_PACKAGE_NAMEcom.example.appDefault package name for submit
WORKER_HEARTBEAT_INTERVAL_MS45000Heartbeat cadence
WORKER_CLAIM_POLL_MS15000Job-claim poll interval (WS/HTTP)
WORKER_WS_HTTP_FALLBACK_MS30000Drop to HTTP when the WebSocket is down this long
USE_TART_FOR_IOS / TART_VM_NAMEoptionalRun iOS builds inside a Tart VM

GitHub OAuth client fields (GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_OAUTH_MODE) may also be set on local workers that run OAuth-dependent steps.

MCP server (@venelx/mcp)

VariableRequiredDefaultPurpose
VENELX_TOKENyesPersonal API token (vx_...) — see API tokens
VENELX_API_URLnohttps://api.venelx.comAPI base URL (point at your self-hosted API)

Mobile app (venelx-app)

Template: env/app.env.example.

VariablePurpose
EXPO_PUBLIC_API_URLAPI base URL baked into the Expo app

Validating

bash
./scripts/validate-deploy-env.sh api venelx-backend/.env
./scripts/validate-deploy-env.sh worker venelx-worker/.env