Skip to content

Configuration Overview

Relate Mail follows a deploy once, configure via environment variables philosophy. The same Docker images and binaries work across development, staging, and production environments -- only the configuration changes at runtime.

Configuration Hierarchy

The .NET backend uses a layered configuration system where later sources override earlier ones:

appsettings.json              (base defaults, checked into source)
  └── appsettings.{Env}.json  (environment-specific overrides)
       └── Environment variables  (highest priority, runtime overrides)

In practice, appsettings.json provides sensible defaults, and environment variables override specific values at deployment time. You rarely need to modify the JSON files.

Environment Variable Mapping

.NET configuration uses a hierarchical key structure (e.g., Smtp.Port). Environment variables map to this hierarchy using double underscores (__) as separators:

JSON PathEnvironment Variable
ConnectionStrings.DefaultConnectionConnectionStrings__DefaultConnection
Smtp.PortSmtp__Port
Smtp.Mx.EnabledSmtp__Mx__Enabled
Oidc.AuthorityOidc__Authority
Cors.AllowedOrigins[0]Cors__AllowedOrigins__0

Array Values

Array configuration values use numeric indices as keys:

bash
# JSON: { "Smtp": { "Mx": { "HostedDomains": ["example.com", "mail.example.com"] } } }
Smtp__Mx__HostedDomains__0=example.com
Smtp__Mx__HostedDomains__1=mail.example.com

# JSON: { "Cors": { "AllowedOrigins": ["https://app.example.com"] } }
Cors__AllowedOrigins__0=https://app.example.com

Boolean Values

Boolean settings accept true or false (case-insensitive):

bash
Smtp__Enabled=true
Smtp__Mx__Enabled=false
Pop3__Enabled=true

Frontend Runtime Configuration

The web frontend does not bake configuration into the build. Instead, it fetches runtime configuration from the API at startup:

GET /api/config

This endpoint returns the OIDC settings and other frontend-relevant configuration. The API reads these from its own configuration (environment variables or appsettings) and serves them to the frontend. This means you can change OIDC providers or other frontend settings by updating the API's environment variables and restarting -- no frontend rebuild required.

Build-time variables (VITE_*) are still available for cases where you build the frontend separately, but the Docker images use the runtime config endpoint.

Configuration Areas

AreaKey PrefixDescription
DatabaseConnectionStrings__PostgreSQL connection
AuthenticationOidc__, Jwt__OIDC provider, JWT settings
SMTPSmtp__SMTP server, MX endpoint, TLS
POP3Pop3__POP3 server, TLS
IMAPImap__IMAP server, TLS
Outbound MailOutboundMail__Email delivery, relay, retry
SecuritySecurity__Rate limiting, auth salt
CORSCors__Cross-origin request settings
InternalInternal__Service-to-service communication
FrontendVITE_Build-time frontend settings

Development Mode

When Oidc__Authority is not set (empty or missing), the system runs in development mode:

  • Authentication is relaxed -- the API accepts development JWT tokens
  • The web frontend skips the OIDC login flow
  • Auto-migration applies pending database migrations on startup

This makes it easy to get started without configuring an identity provider. For production, always set Oidc__Authority to your OIDC provider URL.

Next Steps

Released under the MIT License.