Documentation

Environment variables

Every env var AppEngine reads — required, optional, and how to manage secrets.

AppEngine is configured entirely through environment variables — no config files. This page lists what's read, grouped by purpose. Set the required ones; leave the optional ones unset to disable the corresponding feature.

Required for boot

AppEngine refuses to start without these.

VarExamplePurpose
NODE_ENVproductionAffects logging, rate limiting, error verbosity
SERVER_PORT3300HTTP port
MONGODB_CONNmongodb://user:pass@host:27017Mongo connection string
MONGODB_HOSTmongodbMongo host (used when MONGODB_CONN not set)
MONGODB_PORT27017Mongo port
MONGODB_USERNAMEadminMongo user
MONGODB_PASSWORD<secret>Mongo password
REDIS_CONNredis://redis:6379Redis connection string
REDIS_HOSTredisRedis host (used when REDIS_CONN not set)
REDIS_PORT6379Redis port
JWT_SECRET64+ charsHMAC key for issued tokens
JWT_REFRESH_SECRET64+ charsHMAC key for refresh tokens
ROOT_ORGmycoInitial root org id, created on first boot
ROOT_USERadminInitial root user username
ROOT_EMAIL[email protected]Initial root user email
ROOT_PASSWORD<secret>Initial root user password

Generate JWT secrets with:

openssl rand -base64 64

The shipped development.env uses 'secretKey' as the fallback. Do not run that in production.

URLs and addressing

VarDefaultPurpose
BASE_URLhttp://localhost:3300The public URL AppEngine serves at; used in emails, callbacks
APPENGINE_URLhttp://localhost:3300Self-reference for internal calls
APPENGINE_LOCAL_URLhttps://proxy.appmint.ioUsed as a fallback when AppEngine talks to itself in prod
WEBSITEMINT_URLhttp://localhost:3100URL of the websitemint admin
BUILDER_URLhttp://localhost:3100URL of the builder
STUDIO_URL(unset)Vibe Studio URL, if deployed
APP_URL(unset)Front-end app URL for email link generation
SITE_HOST_NAME(unset)Override the host detection for Nginx pass-through
SHARED_ORGlocalhostOrg used for shared/free-tier pages
SITE_IDwebsitemintDefault site id
INSTANCE_IDlocal-devDisplay name for this AppEngine instance

Auth + security

VarRequiredPurpose
JWT_SECRETyesHMAC key
JWT_REFRESH_SECRETyesRefresh-token HMAC
JWT_EXPIRES_INnoAccess token TTL (default 8h)
JWT_REFRESH_EXPIRES_INnoRefresh token TTL (default 30d)
JWT_AUDIENCEnoaud claim, defaults to appmint
JWT_ISSUERnoiss claim
AUTH_TOKEN_AGEnoSame as JWT_EXPIRES_IN, legacy
REFRESH_TOKEN_AGEnoSame as JWT_REFRESH_EXPIRES_IN, legacy
RATE_LIMIT_MAXnoRequests/min/IP. Default 100. Disable with very high value
ALLOWED_ORIGINSnoCORS allowlist, comma-separated
TRUST_PROXY_HOPSnoNumber of upstream proxies to trust for IP detection
ALLOW_SELF_SIGNED_CERTSnoSet to true to accept self-signed TLS on outbound calls (dev only)

Storage

VarPurpose
S3_ENDPOINTS3-compatible endpoint URL
S3_KEYAccess key
S3_SECRETSecret key
S3_BUCKETBucket name
S3_REGIONRegion (e.g., us-east-1, sfo3)
S3_SPACE_BASE_URLPublic CDN URL for served assets
FILE_PATHLocal path for filesystem fallback (default ./)
IMAGE_SIZESComma-separated thumbnail sizes (e.g., 100,300,800)
IMAGE_EXTENSIONSAllowed upload extensions

Set the S3 vars to use object storage. With them missing, AppEngine writes to the local filesystem under FILE_PATH — fine for dev, useless for multi-pod production.

AI providers

Set the keys for any LLM you want to use; leave the rest unset.

VarProvider
OPENAI_API_KEYOpenAI
ANTHROPIC_API_KEYAnthropic Claude
DEEPSEEK_API_KEYDeepSeek
GEMINI_API_KEYGoogle Gemini
AI_PROVIDERDefault text provider (openai, anthropic, deepseek, gemini)
AI_PROVIDER_TEXTOverride for text-only flows
AI_PROVIDER_IMAGEProvider for image generation
AI_PRICING_OVERRIDESJSON map of model → price-per-1k-tokens for usage metering
ENABLE_TOKENIZATIONtrue to count tokens server-side

The /ai/agent/stream endpoint requires at least one provider key. Without any, AI features 500.

Email

VarPurpose
EMAIL_SERVICE_ENABLEDtrue to enable outbound email
MAILER_SERVICE_HOSTSMTP host
MAILER_SERVICE_PORTSMTP port

For SaaS, prefer Postmark/SendGrid HTTP API providers configured per-org via the admin UI rather than a global SMTP. The global SMTP is for system emails (root-org notifications).

OAuth providers

Configure the ones your customers will use. Each comes in pairs (client id + secret).

ProviderVars
GoogleGOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET
FacebookFACEBOOK_APP_ID, FACEBOOK_APP_SECRET, FACEBOOK_CLIENT_ID, FACEBOOK_CLIENT_SECRET, FACEBOOK_CALL_BACK_URL
GitHubGITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, GITHUB_AUTH_URL
TwitterTWITTER_API_KEY, TWITTER_API_SECRET, TWITTER_CLIENT_ID, TWITTER_CLIENT_SECRET, TWITTER_CONSUMER_SECRET
LinkedInLINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET
TikTokTIKTOK_CLIENT_ID, TIKTOK_CLIENT_SECRET
PinterestPINTEREST_CLIENT_ID, PINTEREST_CLIENT_SECRET
RedditREDDIT_CLIENT_ID, REDDIT_CLIENT_SECRET, REDDIT_USER_AGENT
SnapchatSNAPCHAT_CLIENT_ID, SNAPCHAT_CLIENT_SECRET
SlackSLACK_CLIENT_ID, SLACK_CLIENT_SECRET
TwitchTWITCH_CLIENT_ID, TWITCH_CLIENT_SECRET
FigmaFIGMA_CLIENT_ID, FIGMA_CLIENT_SECRET, FIGMA_REDIRECT_URI

Maps + geo

VarPurpose
GOOGLE_MAPS_API_KEYGeocoding, Places autocomplete

Payment + finance

VarPurpose
STRIPE_PUBLISHABLE_KEYPublic key (sent to clients via config)
BANKING_ROUTING_NUMBERACH routing for sponsored banking
SPONSOR_BANK_API_KEYSponsor bank integration
SPONSOR_BANK_API_URLSponsor bank base URL
SPONSOR_BANK_IDSponsor bank id

Stripe secret keys, PayPal credentials, Twilio account, etc. are configured per-org via the admin UI rather than env. That model lets multi-tenant deployments give each customer their own gateway.

Shipping + integrations

VarPurpose
EASYPOST_API_KEYEasyPost shipping rates + labels
RESELLER_CLUB_API_KEY / _USER_ID / _BASE_URLResellerClub for domains
DOMAIN_PROVIDERDomain registrar used for site provisioning
PEXELS_API_AUTH_TOKENStock photo lookup
VIDEOSDK_API_KEY / _SECRET_KEY / _API_ENDPOINTVideo calls

Site provisioning + dev environments

VarPurpose
KUBE_CONFIG_PATHPath to a kubeconfig used for site deployments
KUBERNETES_SERVICE_HOST / _PORTAuto-detected when running in-cluster
DEPLOY_TEMPLATE_PATHPath to deploy templates
GIT_LOCAL_REPOLocal git mirror
GIT_TOKENGit access token
GIT_USERGit author username
DEV_ENV_NODE_IMAGE_NAMEContainer image for Node dev environments
DEV_ENV_FLUTTER_IMAGE_NAMEContainer image for Flutter dev environments
DOCKER_TOKEN / DOCKER_USER / DOCKER_NAMESPACE / DOCKER_EMAIL / DOCKER_REGISTRY_SERVERImage push credentials
TAILWIND_LOCAL_REPO / TAILWIND_LOCAL_QUICK_REPOLocal Tailwind build paths
SPINFORGE_PROVIDER_URLSpinForge provider URL (if used)

Workers + background jobs

VarPurpose
ENABLE_SYNC_PROCESSORStrue/false — enable BullMQ processors
ENABLE_SYNC_CONSUMERStrue/false — enable consumers
ENABLE_SYNC_JOBStrue/false — enable cron jobs
ENABLE_SYNC_SOCIAL_MEDIAtrue/false — social media polling
PROCESS_JOBSJob processor mode
SOCIAL_MEDIA_SERVICE_ENABLEDEnable social posting workers
GOOGLE_ADS_SERVICE_ENABLEDEnable Google Ads sync

If you split the deployment into web replicas + worker replicas, set ENABLE_SYNC_* to true only on workers and false on web. Both still need to be able to enqueue, but only workers should consume.

Operational + monitoring

VarPurpose
MEMORY_LIMITHeap limit (in MB) AppEngine targets
DISABLE_INTERNAL_HEALTH_CHECKSDisable the internal liveness pings
TRACK_USAGE_WHEN_DISABLEDTrack usage even for orgs with disabled metering
VERIFY_TOKENWebhook verification token
VIBE_DATA_PATHPath for Vibe Studio data

Elasticsearch (optional)

VarPurpose
ELASTICSEARCH_NODECluster URL
ELASTICSEARCH_USERNAMEUsername
ELASTICSEARCH_PASSWORDPassword

Without these, full-text search falls back to MongoDB text indexes — adequate up to ~100k documents per searchable collection.

Cloudflare (optional)

VarPurpose
CLOUDFLARE_ACCOUNT_IDAccount id
CLOUDFLARE_API_TOKENAPI token

Used for DNS record creation when AppEngine provisions sites with custom domains.

Secret management in production

Don't ship .env files to production servers. Use a real secret store:

  • Kubernetes: External Secrets Operator + AWS Secrets Manager / GCP Secret Manager / Vault
  • Docker Compose on a single box: Docker secrets via secrets: blocks, not env files
  • Cloud platforms: their built-in secret store (Fly secrets, Render env groups, Vercel env)

Rotate JWT_SECRET and JWT_REFRESH_SECRET quarterly at minimum. Existing JWTs become invalid the moment you rotate — schedule it during a planned maintenance window or implement a graceful overlap (validate against new + old for 24h).

Vendor API keys (Stripe, OpenAI, etc.) configured at the org level rotate via the admin UI without restarting AppEngine.