Skip to main content

Environment Management

Ever Works uses environment variables extensively to configure every aspect of the platform -- from database connections and authentication to plugin API keys and billing. This page documents the env file structure, variable categories, and how configuration flows across the monorepo.

Environment File Structure

The monorepo contains multiple .env files, each scoped to a specific application:

platform/
.env.compose # Docker Compose shared config
apps/
api/
.env # API runtime config (gitignored)
.env.example # API reference template
web/
.env # Web runtime config (gitignored)
.env.example # Web reference template
cli/
.env # CLI runtime config (gitignored)
.env.example # CLI reference template

File Conventions

FileCommittedPurpose
.env.exampleYesTemplate with all supported variables and documentation
.envNo (gitignored)Local runtime values for development
.env.composeYesDefault values for Docker Compose deployment
.env.localNo (gitignored)Next.js local overrides for the web app

Variable Flow Across Apps

API Environment Variables

The API (apps/api/.env.example) is the most configuration-heavy app.

Core Configuration

VariableDefaultDescription
APP_TYPEapiApplication type identifier
PORT3100HTTP port for the API server
HTTP_DEBUGfalseEnable HTTP request/response logging
WEB_URLhttp://localhost:3000Public URL of the web dashboard
ALLOWED_ORIGINShttp://localhost:3000,http://localhost:3001CORS allowed origins (comma-separated)

JWT Authentication

VariableDefaultDescription
JWT_SECRET(required)Secret key for signing JWT access tokens
JWT_ACCESS_TOKEN_EXPIRATION7dAccess token lifetime (15m, 1h, 7d, or never)
JWT_REFRESH_TOKEN_EXPIRATION_DAYS14Refresh token lifetime in days (or never)
JWT_DISABLE_EXPIRATIONfalseDisable all token expiration (development only)

OAuth Providers

VariableDefaultDescription
GH_CLIENT_ID(empty)GitHub OAuth app client ID
GH_CLIENT_SECRET(empty)GitHub OAuth app client secret
GH_CALLBACK_URL${WEB_URL}/api/oauth/github/callbackGitHub OAuth callback URL
GOOGLE_CLIENT_ID(empty)Google OAuth client ID
GOOGLE_CLIENT_SECRET(empty)Google OAuth client secret
GOOGLE_CALLBACK_URL${WEB_URL}/api/oauth/google/callbackGoogle OAuth callback URL

Database Configuration

The API supports three database engines. Set DATABASE_TYPE to select one:

VariableDefaultDescription
DATABASE_TYPEsqliteEngine: sqlite, postgres, or mysql
DATABASE_LOGGINGfalseEnable SQL query logging
DATABASE_SSL_MODEfalseEnable SSL/TLS for database connections
DATABASE_CA_CERT(empty)CA certificate for SSL connections

SQLite-specific

VariableDefaultDescription
DATABASE_PATH./data/database.dbPath to the SQLite database file
DATABASE_IN_MEMORYtrue (dev)Force in-memory database

PostgreSQL-specific

VariableDefaultDescription
DATABASE_HOSTlocalhostPostgreSQL host
DATABASE_PORT5432PostgreSQL port
DATABASE_USERNAMEpostgresDatabase user
DATABASE_PASSWORD(required)Database password
DATABASE_NAMEever_worksDatabase name
DATABASE_URL(empty)Full connection URL (overrides individual fields)

MySQL-specific

VariableDefaultDescription
DATABASE_HOSTlocalhostMySQL host
DATABASE_PORT3306MySQL port
DATABASE_USERNAMErootDatabase user
DATABASE_PASSWORD(required)Database password
DATABASE_NAMEever_worksDatabase name

Email / Mailer

VariableDefaultDescription
MAILER_PROVIDERnoneMail provider: smtp, none, or resend
EMAIL_FROMEver Works <[email protected]>Sender address
SMTP_HOSTsmtp.gmail.comSMTP server host
SMTP_PORT587SMTP server port
SMTP_USER(required)SMTP username
SMTP_PASSWORD(required)SMTP password
SMTP_SECUREfalseUse TLS for SMTP
RESEND_APIKEY(empty)Resend API key
RESEND_EMAIL_FROM(empty)Resend sender address

Trigger.dev (Background Jobs)

VariableDefaultDescription
TRIGGER_ENABLEDfalseEnable Trigger.dev integration
TRIGGER_SECRET_KEY(empty)Trigger.dev project secret key
TRIGGER_API_URLhttps://api.trigger.devTrigger.dev API endpoint
TRIGGER_INTERNAL_SECRET(empty)Secret for internal Trigger.dev webhook
TRIGGER_MACHINE(empty)Machine size (micro, small-1x, medium-1x, large-1x)
TRIGGER_INTERNAL_API_URLhttp://localhost:3100/internal/triggerInternal API endpoint for Trigger.dev workers

Subscriptions and Billing

VariableDefaultDescription
SUBSCRIPTIONS_ENABLEDfalseEnable subscription management
BILLING_DEFAULT_CURRENCYusdDefault billing currency
SUBSCRIPTIONS_DEFAULT_PLANfreeDefault subscription plan
STRIPE_SECRET_KEY(empty)Stripe API secret key
STRIPE_WEBHOOK_SECRET(empty)Stripe webhook signing secret
PAY_PER_USE_PRICE_USD5Pay-per-use pricing

Plugin Environment Variables

Plugins can read API keys from environment variables. The convention is PLUGIN_<NAME>_<KEY>:

VariablePluginDescription
PLUGIN_TAVILY_API_KEYTavilyTavily search API key
PLUGIN_SCREENSHOTONE_ACCESS_KEYScreenshotOneScreenshot service access key
PLUGIN_SCREENSHOTONE_SECRET_KEYScreenshotOneScreenshot service secret key
PLUGIN_OPENROUTER_API_KEYOpenRouterOpenRouter API key
PLUGIN_OPENROUTER_DEFAULT_MODELOpenRouterDefault model identifier
PLUGIN_GITHUB_CLIENT_IDGitHub PluginPlugin-specific GitHub OAuth client ID
PLUGIN_GITHUB_CLIENT_SECRETGitHub PluginPlugin-specific GitHub OAuth secret

Scheduled Updates

VariableDefaultDescription
SCHEDULED_UPDATES_ENABLEDtrueEnable scheduled work updates
SCHEDULED_UPDATES_DISPATCH_INTERVAL_MINUTES5Dispatch check interval
SCHEDULED_UPDATES_MAX_BATCH25Max works to update per batch
SCHEDULED_UPDATES_MAX_FAILURE_BEFORE_PAUSE3Failures before pausing a work

Web Environment Variables

The web app (apps/web/.env.example) uses the NEXT_PUBLIC_ prefix for client-exposed variables.

Application Settings

VariableDefaultDescription
APP_NAMEEver WorksApplication display name
NEXT_PUBLIC_WEB_URLhttp://localhost:3000Public web app URL
API_URLhttp://localhost:3100API endpoint (server-side only)
AUTH_SECRET / COOKIE_SECRET(required)Cookie encryption secret

Site Branding (Multi-tenant)

VariableDefaultDescription
NEXT_PUBLIC_SITE_NAMEEver WorksSite display name
NEXT_PUBLIC_SITE_TITLEEver WorksHTML title / SEO title
NEXT_PUBLIC_SITE_DESCRIPTIONBuild Works with AIMeta description
NEXT_PUBLIC_SITE_KEYWORDSEver Works,Works,AI,...Meta keywords
NEXT_PUBLIC_LOGO_LIGHT/logo-light.pngLogo for light mode
NEXT_PUBLIC_LOGO_DARK/logo-ever-work.pngLogo for dark mode
NEXT_PUBLIC_FAVICON_LIGHT/favicon-light.pngFavicon for light mode
NEXT_PUBLIC_FAVICON_DARK/favicon-dark.pngFavicon for dark mode

Internationalization

VariableDefaultDescription
NEXT_PUBLIC_LOCALESen,ar,de,es,fr,zhSupported locales (comma-separated)
NEXT_PUBLIC_DEFAULT_LOCALEenDefault locale

CLI Environment Variables

The CLI (apps/cli/.env.example) needs minimal configuration:

VariableDefaultDescription
NODE_ENVproductionNode environment
CLI_VERBOSEfalseEnable verbose logging
API_URLhttp://localhost:3100API endpoint
WEB_URLhttp://localhost:3000Web app URL
TRIGGER_*(various)Same Trigger.dev variables as the API

Environment Profiles

Development

# apps/api/.env
DATABASE_TYPE=sqlite
DATABASE_IN_MEMORY=true
MAILER_PROVIDER=none
JWT_DISABLE_EXPIRATION=true
HTTP_DEBUG=true
TRIGGER_ENABLED=false

Staging

# apps/api/.env
DATABASE_TYPE=postgres
DATABASE_HOST=staging-db.internal
MAILER_PROVIDER=resend
JWT_ACCESS_TOKEN_EXPIRATION=1h
TRIGGER_ENABLED=true
SUBSCRIPTIONS_ENABLED=false

Production

# apps/api/.env
DATABASE_TYPE=postgres
DATABASE_HOST=prod-db.internal
DATABASE_SSL_MODE=true
MAILER_PROVIDER=resend
JWT_ACCESS_TOKEN_EXPIRATION=15m
JWT_REFRESH_TOKEN_EXPIRATION_DAYS=7
TRIGGER_ENABLED=true
SUBSCRIPTIONS_ENABLED=true
STRIPE_SECRET_KEY=sk_live_...

Plugin Settings Resolution

Plugin settings are resolved through a 4-level hierarchy (highest priority first):

  1. Work-level: Per-work overrides set in the work plugin settings modal
  2. User-level: User's personal settings for a plugin (e.g., their own API key)
  3. Admin-level: Platform-wide defaults set by the administrator
  4. Environment variable: Fallback from PLUGIN_* env vars defined in .env

Plugins declare which env var maps to a setting using the x-envVar schema extension:

{
"apiKey": {
"type": "string",
"x-secret": true,
"x-envVar": "PLUGIN_TAVILY_API_KEY"
}
}

Security Best Practices

  • Never commit .env files -- they are gitignored by default.
  • Use .env.example as the template -- copy it to .env and fill in real values.
  • Rotate secrets regularly -- especially JWT_SECRET, AUTH_SECRET, and API keys.
  • Use different secrets per environment -- never share production secrets with development.
  • Mark sensitive plugin settings with x-secret: true so the UI masks them.
  • Prefix client-safe variables with NEXT_PUBLIC_ -- all other web variables are server-side only.