DocsGetting StartedConfiguration
Edit

Configuration

Bulwark is configured through runtime environment variables.

The current app reads configuration from .env.local at runtime. In production, the recommended starting point is the app's .env.example, copied to .env.local and then customized for your deployment.

Configuration Model

Bulwark supports two configuration layers:

  • Runtime variables - The preferred approach. These are read by the server at request time and work well for Docker and reverse-proxy deployments.
  • Legacy build-time variables - Still supported as a fallback for older deployments, but new setups should prefer runtime variables.

Runtime variables take precedence when both are set.

Minimal Setup

For a basic deployment, only one variable is truly required:

JMAP_SERVER_URL=https://mail.example.com

Most deployments also set a display name:

APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com

Environment Variables

VariableRequiredDefaultDescription
HOSTNAMENo0.0.0.0Address the server binds to - use :: for IPv6
PORTNo3000Port the server listens on
APP_NAMENoWebmailApplication name shown in the UI, browser tab, and PWA manifest
APP_SHORT_NAMENofalls back to APP_NAMEShort name for the PWA install prompt and home screen
APP_DESCRIPTIONNogeneric Bulwark descriptionDescription shown in the PWA manifest
JMAP_SERVER_URLYes¹-URL of your JMAP-compatible mail server
ALLOW_CUSTOM_JMAP_ENDPOINTNofalseShow a "JMAP Server" field on the login form so users can specify their own server
STALWART_FEATURESNotrueEnables Stalwart-specific features (password change, Sieve, vacation, admin, API keys)
OAUTH_ENABLEDNofalseEnables OAuth2 / OpenID Connect login
OAUTH_ONLYNofalseHides the username/password login form and requires OAuth
OAUTH_CLIENT_IDOAuth only-OAuth client ID
OAUTH_CLIENT_SECRETNoemptyOAuth client secret for confidential clients
OAUTH_CLIENT_SECRET_FILENoemptyPath to a file containing the OAuth client secret (Docker / Kubernetes secrets)
OAUTH_ISSUER_URLNofalls back to JMAP_SERVER_URL discoveryExplicit issuer URL for external IdPs
OAUTH_SCOPESNobuilt-in defaultOverride OAuth scope string
OAUTH_EXTRA_SCOPESNoemptyAdditional scopes appended to defaults
SESSION_SECRETFeature-gated-Enables encrypted Remember-me, settings sync, multi-account, and embedded SSO
SESSION_SECRET_FILENoemptyPath to a file containing the session secret
COOKIE_SAME_SITENolaxCookie SameSite attribute (lax, none, strict)
COOKIE_SECURENoderived from envForce Secure flag on cookies
SETTINGS_SYNC_ENABLEDNofalseEnables encrypted server-side settings sync across devices and accounts
SETTINGS_DATA_DIRNo./data/settingsDirectory for encrypted settings storage (resolves to /app/data/settings in Docker)
ADMIN_PASSWORDNorandom on first startInitial admin dashboard password
ADMIN_DATA_DIRNo./data/adminDirectory for admin config, plugin registry, audit log, and password hash
ADMIN_SESSION_TTLNosafe defaultAdmin session lifetime in seconds
TRUSTED_PROXY_DEPTHNo1Number of X-Forwarded-For hops to trust
EXTENSION_DIRECTORY_URLNoemptyMarketplace URL for browsing and installing plugins/themes
LOG_FORMATNotextLog output format: text or json
LOG_LEVELNoinfoLog verbosity: error, warn, info, or debug
FAVICON_URLNoBulwark faviconCustom browser tab favicon (SVG, PNG, or ICO; 32-512px)
PWA_ICON_URLNofalls back to FAVICON_URLSource image used to generate PWA install icons
PWA_THEME_COLORNo#ffffffPWA browser UI chrome color
PWA_BACKGROUND_COLORNo#ffffffPWA splash screen background
APP_LOGO_LIGHT_URLNoemptySidebar logo for light mode (SVG, PNG, or WebP; 24-128px)
APP_LOGO_DARK_URLNoemptySidebar logo for dark mode (SVG, PNG, or WebP; 24-128px)
LOGIN_LOGO_LIGHT_URLNoBulwark light logoLogin page logo for light backgrounds (SVG, PNG, or WebP; 32-512px)
LOGIN_LOGO_DARK_URLNoBulwark dark logoLogin page logo for dark backgrounds (SVG, PNG, or WebP; 32-512px)
LOGIN_COMPANY_NAMENoemptyCompany name shown on the login page
LOGIN_IMPRINT_URLNoemptyLogin page imprint / legal notice link
LOGIN_PRIVACY_POLICY_URLNoemptyLogin page privacy policy link
LOGIN_WEBSITE_URLNoemptyLogin page website link
NEXT_PUBLIC_LOCALE_PREFIXNosafe defaultLocale URL prefix mode: always, as-needed, or never
AUTO_SSO_ENABLEDNofalseAutomatically start OAuth flow on login page (for embedded SSO)
ALLOWED_FRAME_ANCESTORSNo'none'CSP frame-ancestors value for iframe embedding
NEXT_PUBLIC_PARENT_ORIGINNoemptyOrigin of parent frame for postMessage validation
STALWART_API_URLDeprecated-Removed in 1.5.0; Stalwart 0.16+ self-service goes through JMAP
NEXT_PUBLIC_APP_NAMELegacy fallback-Legacy build-time fallback for APP_NAME
NEXT_PUBLIC_JMAP_SERVER_URLLegacy fallback-Legacy build-time fallback for JMAP_SERVER_URL

¹ JMAP_SERVER_URL is required unless ALLOW_CUSTOM_JMAP_ENDPOINT=true, in which case users supply the URL on the login form.

Full Reference

For a complete explanation of every setting from .env.example, including defaults, dependencies, and implementation notes, see Environment Reference.

Notes on Integration

All variables currently listed in the app's .env.example are implemented in the current Bulwark codebase.

  • Some are feature-gated rather than always active.
  • Some are optional branding or operational settings.
  • The NEXT_PUBLIC_* variables are legacy fallbacks, kept for compatibility with older build-time deployments.

Stalwart Server Setup

Bulwark requires a Stalwart Mail Server with JMAP enabled. Make sure your Stalwart configuration includes:

[server.listener.jmap]
bind = ["0.0.0.0:8080"]
protocol = "http"

CORS Configuration

If Bulwark and Stalwart are on different domains, configure CORS in Stalwart:

[server.http]
permissive-cors = true

Authentication

Bulwark uses JMAP's built-in authentication. Users log in with their email credentials configured in Stalwart. Supported authentication methods:

  • Basic Auth - Username and password
  • OAuth 2.0 - If configured in Stalwart
  • OAuth App Passwords - For environments using OAuth as primary auth

Custom JMAP Server Endpoints

Bulwark supports configuring custom JMAP server endpoints directly from the login page and settings. This allows users to connect to different JMAP servers without modifying environment variables, useful for multi-server environments or testing.

Theming

Bulwark supports light and dark themes out of the box. The theme preference is stored in the browser's local storage and respects the system preference by default.

To set a default theme, you can customize the CSS variables in your deployment. See the Customization page for details.