Environment Reference
This page documents every setting currently present in Bulwark's .env.example.
All of the variables below are implemented in the current app. Some are always available, some only affect optional features, and some exist as compatibility fallbacks for older build-time deployments.
Server Listen Address
HOSTNAME
- Purpose - Sets the address the server binds to.
- Required - No.
- Default -
0.0.0.0 - When to set it - Set to
::to listen on IPv6 (dual-stack), or to a specific interface address to restrict access.
PORT
- Purpose - Sets the port the server listens on.
- Required - No.
- Default -
3000 - When to set it - Set this when you need the server to listen on a non-default port.
Core Settings
APP_NAME
- Purpose - Sets the application name displayed in the UI.
- Required - No.
- Default behavior - Falls back to a built-in app name when not set.
- When to set it - Set this if you want your deployment to be branded differently from the default Bulwark name.
JMAP_SERVER_URL
- Purpose - Points Bulwark to your JMAP-compatible mail server.
- Required - Yes, unless you rely on the legacy
NEXT_PUBLIC_JMAP_SERVER_URLfallback. - Example -
https://mail.example.com - When to set it - Always for a normal runtime deployment.
Stalwart Integration
STALWART_FEATURES
- Purpose - Enables Stalwart-specific features such as password change, Sieve management, vacation responder controls, and similar account-management flows.
- Required - No.
- Default - Enabled unless explicitly set to
false. - When to set it - Set
STALWART_FEATURES=falseif you are using Bulwark with a non-Stalwart JMAP server and want to hide features that depend on Stalwart APIs.
STALWART_API_URL
- Purpose - Overrides the URL used for Stalwart management API requests.
- Required - No.
- Default - Falls back to
JMAP_SERVER_URL. - When to set it - Use this when your reverse proxy forwards JMAP but does not expose Stalwart management paths such as
/api/account/*or/api/principal/*.
OAuth / OpenID Connect
OAUTH_ENABLED
- Purpose - Turns on OAuth2 / OIDC login support.
- Required - No.
- Default -
false - When to set it - Set to
truewhen your deployment should show an SSO login flow.
OAUTH_ONLY
- Purpose - Makes OAuth the only login method and hides the username/password form.
- Required - No.
- Dependency - Requires
OAUTH_ENABLED=true. - When to set it - Use this when all users should authenticate through your identity provider only.
OAUTH_CLIENT_ID
- Purpose - OAuth client ID registered with your identity provider.
- Required - Required when OAuth is enabled.
- When to set it - Always set this together with
OAUTH_ENABLED=true.
OAUTH_CLIENT_SECRET
- Purpose - OAuth client secret used for confidential clients.
- Required - No.
- When to set it - Only needed if your IdP registration expects a confidential client instead of a public PKCE-only client.
OAUTH_ISSUER_URL
- Purpose - Explicit issuer URL used for OIDC discovery.
- Required - No.
- Default behavior - If omitted, Bulwark falls back to discovery through
JMAP_SERVER_URL. - When to set it - Set this when your mail server delegates auth to an external IdP such as Keycloak or Authentik.
Session & Security
SESSION_SECRET
- Purpose - Secret used to encrypt persistent "Remember me" sessions, settings sync data, and multi-account configuration.
- Required - No for basic login, required for encrypted persistent sessions, settings sync, and multi-account support.
- When to set it - Set this if you want users to keep signed in across browser restarts, enable settings sync, or use multi-account support.
- Generation -
openssl rand -base64 32
Settings Sync
SETTINGS_SYNC_ENABLED
- Purpose - Enables encrypted server-side settings persistence across devices and accounts.
- Required - No.
- Dependency - Requires
SESSION_SECRET. - Default -
false - When to set it - Set to
truewhen you want settings to follow users across browsers, devices, and accounts.
SETTINGS_DATA_DIR
- Purpose - Filesystem location where encrypted settings files are stored.
- Required - No.
- Default -
./data/settings(resolves to/app/data/settingsin Docker, sinceWORKDIRis/app) - When to set it - Set this when you want settings data stored on a specific persistent volume or host path.
- Docker note - Mount a persistent volume at
/app/data/settings(or at whatever absolute path you configure) so that settings survive container restarts:volumes: - bulwark-settings:/app/data/settings
Logging
LOG_FORMAT
- Purpose - Controls server log output format.
- Allowed values -
text,json - Default -
text - When to set it - Use
jsonfor structured log collection in platforms such as containers, centralized logging, or observability stacks.
LOG_LEVEL
- Purpose - Controls server log verbosity.
- Allowed values -
error,warn,info,debug - Default -
info - When to set it - Increase to
debugduring troubleshooting; lower towarnorerrorin quieter production environments.
Branding
FAVICON_URL
- Purpose - Custom favicon (browser tab icon) for the application.
- Required - No.
- Default - Bulwark favicon (
/branding/Bulwark_Favicon.svg). - Accepted values - Absolute URL or path relative to
public/. - Supported formats - SVG (recommended), PNG, ICO.
- Recommended size - 32×32px minimum, 512×512px maximum. SVG is preferred for crisp scaling at all resolutions.
- When to set it - Set this to replace the default Bulwark favicon with your organization's icon in the browser tab.
APP_LOGO_LIGHT_URL
- Purpose - Logo shown in the sidebar on light backgrounds (main app, after login).
- Required - No.
- Default - Empty (no sidebar logo).
- Accepted values - Absolute URL or path relative to
public/. - Supported formats - SVG (recommended), PNG, WebP.
- Recommended size - 24×24px minimum, 128×128px maximum. Displayed at 24×24px.
- When to set it - Set this to add your brand logo to the sidebar.
APP_LOGO_DARK_URL
- Purpose - Logo shown in the sidebar on dark backgrounds (main app, after login).
- Required - No.
- Default - Empty (falls back to
APP_LOGO_LIGHT_URLif set, otherwise no logo). - Accepted values - Absolute URL or path relative to
public/. - Supported formats - SVG (recommended), PNG, WebP.
- Recommended size - 24×24px minimum, 128×128px maximum. Displayed at 24×24px.
- When to set it - Set this when you need a different logo variant for dark mode (e.g., a white logo).
Login Page Customization
LOGIN_LOGO_LIGHT_URL
- Purpose - Logo shown on light backgrounds on the login page.
- Required - No.
- Default - Bulwark light logo.
- Accepted values - Absolute URL or path relative to
public/. - Supported formats - SVG (recommended), PNG, WebP.
- Recommended size - 32×32px minimum, 512×512px maximum. Displayed at 64×64px.
LOGIN_LOGO_DARK_URL
- Purpose - Logo shown on dark backgrounds on the login page.
- Required - No.
- Default - Bulwark dark logo.
- Accepted values - Absolute URL or path relative to
public/. - Supported formats - SVG (recommended), PNG, WebP.
- Recommended size - 32×32px minimum, 512×512px maximum. Displayed at 64×64px.
LOGIN_COMPANY_NAME
- Purpose - Company or organization name shown above the version on the login page.
- Required - No.
- Default - Empty.
LOGIN_IMPRINT_URL
- Purpose - Adds an imprint / legal notice link to the login page.
- Required - No.
- Default - Empty.
LOGIN_PRIVACY_POLICY_URL
- Purpose - Adds a privacy policy link to the login page.
- Required - No.
- Default - Empty.
LOGIN_WEBSITE_URL
- Purpose - Adds a website link to the login page.
- Required - No.
- Default - Empty.
Legacy Build-time Fallbacks
These variables still work, but they exist for compatibility with older deployments where values were baked into the frontend bundle at build time.
NEXT_PUBLIC_APP_NAME
- Purpose - Legacy fallback for
APP_NAME. - Required - No.
- When to use it - Only if you still depend on build-time configuration.
NEXT_PUBLIC_JMAP_SERVER_URL
- Purpose - Legacy fallback for
JMAP_SERVER_URL. - Required - No.
- When to use it - Only if you still depend on build-time configuration.
Embedded SSO & iframe
AUTO_SSO_ENABLED
- Purpose - Automatically start the OAuth flow on the login page without user interaction.
- Required - No.
- Default -
false - Dependency - Requires
OAUTH_ENABLED=trueandOAUTH_ONLY=true. - When to set it - Set to
truewhen embedding Bulwark in an iframe with automatic SSO managed by a parent portal.
ALLOWED_FRAME_ANCESTORS
- Purpose - Sets the CSP
frame-ancestorsdirective to allow embedding in an iframe. - Required - No.
- Default -
'none'(iframe embedding disabled). - When to set it - Set to the origin of the parent portal (e.g.,
https://portal.example.com) to allow iframe embedding.
COOKIE_SAME_SITE
- Purpose - Sets the
SameSiteattribute on session cookies. - Allowed values -
lax,none,strict - Default -
lax - When to set it - Set to
nonewhen Bulwark is embedded cross-origin in an iframe. Requires HTTPS.
NEXT_PUBLIC_PARENT_ORIGIN
- Purpose - Origin of the parent frame for validating incoming
postMessageevents. - Required - No.
- Default - Empty (accepts messages from any origin).
- When to set it - Set to the origin of the parent portal for security when using the postMessage bridge.
Recommended Patterns
Small self-hosted setup
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
Stalwart with encrypted persistent sessions
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
SESSION_SECRET=replace-with-a-random-secret
Stalwart with cross-device settings sync
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
SESSION_SECRET=replace-with-a-random-secret
SETTINGS_SYNC_ENABLED=true
SETTINGS_DATA_DIR=/data/settings
Multi-account with encrypted settings
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
SESSION_SECRET=replace-with-a-random-secret
SETTINGS_SYNC_ENABLED=true
SETTINGS_DATA_DIR=/data/settings
OAuth-only deployment
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
OAUTH_ENABLED=true
OAUTH_ONLY=true
OAUTH_CLIENT_ID=webmail
OAUTH_ISSUER_URL=https://id.example.com/realms/mail
Non-Stalwart JMAP server
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
STALWART_FEATURES=false
Embedded SSO in an iframe
APP_NAME=Bulwark Webmail
JMAP_SERVER_URL=https://mail.example.com
OAUTH_ENABLED=true
OAUTH_ONLY=true
OAUTH_CLIENT_ID=webmail
OAUTH_ISSUER_URL=https://auth.example.com
SESSION_SECRET=replace-with-a-random-secret
AUTO_SSO_ENABLED=true
ALLOWED_FRAME_ANCESTORS=https://portal.example.com
COOKIE_SAME_SITE=none
NEXT_PUBLIC_PARENT_ORIGIN=https://portal.example.com
Integration Status
At the time of writing, every variable listed in Bulwark's .env.example is integrated in the app.
APP_NAMEandJMAP_SERVER_URLare core runtime settings.- OAuth variables are used by the auth and config API routes.
SESSION_SECRET,SETTINGS_SYNC_ENABLED, andSETTINGS_DATA_DIRare used by encrypted session and settings-sync code paths.STALWART_FEATURESandSTALWART_API_URLcontrol Stalwart-specific behavior.LOG_FORMATandLOG_LEVELare used by the server logger.- Login branding variables are exposed through the runtime config endpoint and used by the login page.
- Favicon and app logo variables are served through the config endpoint and rendered by the layout and sidebar.
- Embedded SSO variables (
AUTO_SSO_ENABLED,ALLOWED_FRAME_ANCESTORS,COOKIE_SAME_SITE,NEXT_PUBLIC_PARENT_ORIGIN) are used by the auth middleware and SSO API routes. NEXT_PUBLIC_*values remain as fallback support for older build-time setups.