appsettings Reference¶
An exhaustive, per-host reference of every appsettings*.json file the Cargonerds
solution ships, every configuration key inside them, what each key is for and its
committed default value.
This page is the key-level catalogue. For how the files are layered, the
precedence order, the two {token} replacement engines and the driving environment
variables, read the companion page first:
- Configuration Settings — the loading pipeline, environment
axes (
SPARK_ENVIRONMENT/AZURE_ENVIRONMENT), token replacement, and recipes.
Committed secrets
Almost every value in these files is a real production secret — SQL
passwords, the SMTP password, the Entra client secret, Google / Algolia /
MapTiler / E-adapter / PricingManager API keys, the
StringEncryption:DefaultPassPhrase, the OpenIddict CertificatePassPhrase
and the ABP AbpLicenseCode. They live in the repo unencrypted. Treat any
value shown here as compromised and rotate before relying on it. The example
values below are reproduced from the committed files only so the structure is
unambiguous.
How a host assembles its configuration¶
Every host calls builder.AddServiceDefaults()
(src/Cargonerds.ServiceDefaults/HostApplicationBuilderExtensions.cs), which layers
extra JSON files and two IConfigurationSource rewriters on top of the standard
.NET chain. Later layers win.
flowchart TD
A["appsettings.json"] --> B["appsettings.{ASPNETCORE_ENVIRONMENT}.json"]
B --> C["User Secrets (Development only)"]
C --> D["Environment variables / CLI args"]
D --> E{"USE_ASPIRE_CONFIG = true?"}
E -- yes --> F["appsettings.aspire.json"]
E -- no --> G
F --> G{"AZURE_ENVIRONMENT set?"}
G -- yes --> H["appsettings.azure.json + per-segment overlays<br/>then ConfigurationParameters rewriter"]
G -- no --> I
H --> I["white-label file<br/>(WHITE_LABEL_SETTINGS_PATH ?? appsettings.rohlig.json)"]
I --> J["appsettings.spark.<SPARK_ENVIRONMENT>.json"]
J --> K["appsettings.spark.<env>.user.json"]
K --> L["ServiceDiscovery rewriter:<br/>resolve {service} tokens"]
Two databases, two connection-string names
ConnectionStrings:Default (constant SparkDb) is the ABP application DB
(Identity, OpenIddict, Settings, Features, AuditLogging, CmsKit, Saas, Chat,
BLOB-in-DB, and Hangfire storage). ConnectionStrings:Hub (constant HubDb)
is the Hub domain DB (shipments, organizations, tracking, pricing). The names
are defined once in
src/Cargonerds.Domain.Shared/Configuration/ConnectionStringNames.cs:
HubDb = "Hub", SparkDb = "Default", BlobStorage, HubServiceBus = "hubServiceBus".
Section glossary (shared across hosts)¶
These sections appear in more than one host. Per-host tables below reference them rather than repeating the explanation.
| Section | Bound to / consumed by | Meaning |
|---|---|---|
App |
AppConfiguration (src/Cargonerds.Domain.Shared/Configuration/AppConfiguration.cs) via GetAppConfiguration() |
Self URL, public URL, CORS list, PII switch, health-check path, customer id, booking-number prefix. See the App section table. |
ConnectionStrings |
IConfiguration.GetConnectionString(...) |
Default, Hub, BlobStorage, hubServiceBus, plus Aspire redis / messaging. |
AuthServer |
JWT bearer + OpenIddict + OIDC clients | Authority, RequireHttpsMetadata, MetaAddress, SwaggerClientId, ClientId / ClientSecret, CertificatePassPhrase, ResponseType, WellKnownConfigAddress. |
Redis |
Redis:Configuration read directly in modules |
StackExchange connection string for DataProtection key persistence and the distributed-lock provider. |
RabbitMQ |
AbpRabbitMqOptions via ConfigureRabbitMQ |
Connections:Default:HostName, Connections:Default:Override, EventBus:ClientName, EventBus:ExchangeName. |
StringEncryption |
ABP AbpStringEncryptionOptions |
DefaultPassPhrase used to decrypt the encrypted SMTP password and other encrypted settings. |
Settings |
ABP setting defaults seeded at startup | Abp.Mailing.Smtp.* and mail from-address defaults. |
WhiteLabelingOptions |
WhiteLabelingOptions (modules/hub/src/Hub.Domain.Shared/WhiteLabeling/WhiteLabelingOptions.cs) via GetRequiredValue<WhiteLabelingOptions>(...) |
Branding, EntraLogins, ExternalApis. See the White-label section. |
RemoteServices |
ABP dynamic C# client proxies | Default:BaseUrl, AbpAccountPublic:BaseUrl — where a host calls the API / auth server. |
OpenIddict |
OpenIddict app seeding | Applications[] — OIDC client definitions seeded into the DB. |
Logging |
.NET logging | LogLevel map. |
AbpLicenseCode |
ABP AddAppSettingsSecretsJson() |
The ABP commercial license; lives only in appsettings.secrets.json. |
ABP-pattern background: Settings, Features, Distributed cache, BLOB storing, OpenIddict / auth server, Background jobs.
The App section¶
App binds to AppConfiguration. Not every host sets every property; the table is
the union.
| Key | Type | Purpose | Typical local default |
|---|---|---|---|
App:SelfUrl |
string | This host's own public base URL (issuer/redirect base). | per host, e.g. https://localhost:44354 (API), :44345 (Auth), :44332 (Web.Public), :44381 (Blazor) |
App:MVCPublicUrl |
string | URL of the public MVC/Web site (AppUrlOptions.Applications["MVCPublic"]). |
https://localhost:44332 (API) |
App:CorsOrigins |
string (comma-list) | Allowed CORS origins. | wildcard *.rohlig.com / *.cargonerds.com / *.cargonerds.dev + localhost ports |
App:RedirectAllowedUrls |
string (comma-list) | Allowed post-login redirect URLs (AppUrlOptions.RedirectAllowedUrls); AuthServer also merges App:AllowedRedirectUrls. |
wildcard + localhost (AuthServer) |
App:DisablePII |
bool | Disables logging of personally identifiable info. | false |
App:HealthCheckUrl |
string | Path of the health-status UI page. | /health-status |
App:CargonerdsCustomerId |
Guid | Tenant/customer id that scopes Hub data; set per Spark env. | (none locally) / 2D524F51-… for dev/test/prod |
App:BookingNumberPrefix |
string | Prefix for generated booking numbers; per Spark env. | empty (local/prod), Booking- (dev) |
App:AllowedCorsOrigins |
string/array | Aspire-template variant of the CORS list (token form). | {realtime} / ["{api}","{realtime}","{admin}"] |
App:AllowedRedirectUrls |
array | Aspire-template redirect allow-list (AuthServer). | ["{api}","{realtime}","{admin}"] |
App:Realtime |
string | URL of the realtime (React) front-end. | {realtime} (API aspire file) |
AuthServer — src/Cargonerds.AuthServer/¶
The OpenIddict authority. Module: CargonerdsAuthServerModule.cs.
| File | Loaded | Contents |
|---|---|---|
appsettings.json |
always | App, ConnectionStrings:Default, AuthServer, StringEncryption, Redis. |
appsettings.Development.json |
Development | empty {}. |
appsettings.aspire.json |
USE_ASPIRE_CONFIG=true |
token template — see below. |
appsettings.secrets.json |
via AddAppSettingsSecretsJson() |
AbpLicenseCode only. |
appsettings.json keys¶
| Key | Default | Purpose |
|---|---|---|
App:SelfUrl |
https://localhost:44345 |
AuthServer base URL → OpenIddict issuer + MVC root. |
App:CorsOrigins |
wildcard + localhost list | CORS origins. |
App:RedirectAllowedUrls |
wildcard + localhost list | Login/logout redirect allow-list. |
App:DisablePII |
false |
PII logging switch. |
App:HealthCheckUrl |
/health-status |
Health UI path. |
ConnectionStrings:Default |
Server=(LocalDb)\MSSQLLocalDB;Database=CargonerdsAppDb;Trusted_Connection=True;TrustServerCertificate=true |
ABP application DB. |
AuthServer:Authority |
https://localhost:44345 |
OpenIddict issuer (SetIssuer). |
AuthServer:RequireHttpsMetadata |
true |
When false, disables transport-security requirement and enables X-Forwarded-Proto handling (reverse-proxy deploys). |
AuthServer:CertificatePassPhrase |
(committed in Dev file) | Passphrase for openiddict.pfx in non-Development. |
StringEncryption:DefaultPassPhrase |
vd7i8105O0jZ7xQl |
ABP string-encryption key. |
Redis:Configuration |
127.0.0.1 |
Redis endpoint for DataProtection persistence (non-Development) and distributed lock. |
Where the OpenIddict certificate passphrase actually lives
appsettings.json does not contain AuthServer:CertificatePassPhrase. It is
set in appsettings.Development.json
(d9efcd01-fbd8-42b1-a9d1-a5cf44afe714). In non-Development,
CargonerdsAuthServerModule.PreConfigureServices calls
AddProductionEncryptionAndSigningCertificate("openiddict.pfx", configuration["AuthServer:CertificatePassPhrase"]).
In Development, ABP's auto-generated dev certificate is used instead.
appsettings.aspire.json (token template)¶
Uses service-discovery
{token}s resolved from Aspire endpoints / connection strings.
{
"App": {
"SelfUrl": "{auth}",
"AllowedCorsOrigins": ["{api}", "{realtime}", "{admin}"],
"AllowedRedirectUrls": ["{api}", "{realtime}", "{admin}"]
},
"AuthServer": {
"Authority": "{auth}",
"WellKnownConfigAddress": "{auth}/.well-known/openid-configuration"
},
"Redis": { "Configuration": "{redis}" },
"RabbitMQ": { "Connections": { "Default": { "HostName": "{messaging}", "Override": true } } }
}
| Token key | Resolves to |
|---|---|
App:SelfUrl = {auth} |
The AuthServer's own Aspire endpoint. |
App:AllowedCorsOrigins / App:AllowedRedirectUrls |
{api}, {realtime}, {admin} endpoints (merged into RedirectAllowedUrls). |
AuthServer:Authority = {auth} |
Issuer. |
AuthServer:WellKnownConfigAddress |
{auth}/.well-known/openid-configuration. |
Redis:Configuration = {redis} |
ConnectionStrings:redis. |
RabbitMQ:Connections:Default:HostName = {messaging} (Override:true) |
ConnectionStrings:messaging AMQP URI; Override triggers URI parsing — see Cross-cutting gotchas. |
HttpApi.Host — src/Cargonerds.HttpApi.Host/¶
The REST/OData API and the only host that ships the per-Spark-env files. Module:
CargonerdsHttpApiHostModule.cs.
| File | Loaded | Contents |
|---|---|---|
appsettings.json |
always | Settings, App, ConnectionStrings:Default, Redis, RabbitMQ, AuthServer, StringEncryption. |
appsettings.Development.json |
Development | empty {}. |
appsettings.aspire.json |
USE_ASPIRE_CONFIG=true |
token template. |
appsettings.secrets.json |
AddAppSettingsSecretsJson() |
AbpLicenseCode. |
appsettings.spark.<env>.json |
per SPARK_ENVIRONMENT (reloadOnChange) |
Hub/BlobStorage/hubServiceBus connection strings + per-env App + per-env WhiteLabelingOptions:ExternalApis. |
appsettings.spark.<env>.user.json |
per env (reloadOnChange) |
developer-local overrides; only the local variant is gitignored. |
appsettings.json keys¶
| Key | Default | Purpose |
|---|---|---|
Settings:Abp.Mailing.Smtp.Host |
smtp.office365.com |
SMTP host (seeded ABP setting default). |
Settings:Abp.Mailing.Smtp.Port |
587 |
SMTP port. |
Settings:Abp.Mailing.Smtp.UserName |
smtp.cargonerds@cargonerds.com |
SMTP user. |
Settings:Abp.Mailing.Smtp.Password |
4aJ38… (// Encrypted) |
SMTP password, encrypted with StringEncryption:DefaultPassPhrase. |
Settings:Abp.Mailing.Smtp.EnableSsl |
true |
TLS. |
Settings:Abp.Mailing.Smtp.UseDefaultCredentials |
false |
Use explicit creds. |
Settings:Abp.Mailing.DefaultFromAddress |
smtp.cargonerds@cargonerds.com |
Default From. |
Settings:Abp.Mailing.DefaultFromDisplayName |
Cargonerds Mail |
Default From display name. |
App:SelfUrl |
https://localhost:44354 |
API base URL. |
App:MVCPublicUrl |
https://localhost:44332 |
Public web URL. |
App:CorsOrigins |
wildcard + localhost list | CORS origins. |
App:DisablePII |
false |
PII switch. |
App:HealthCheckUrl |
/health-status |
Health UI path. |
ConnectionStrings:Default |
Server=(LocalDb)\MSSQLLocalDB;Database=CargonerdsAppDb;… |
ABP application DB + Hangfire storage. |
Redis:Configuration |
127.0.0.1 |
Redis endpoint (DataProtection / distributed lock). |
RabbitMQ:Connections:Default:HostName |
localhost |
AMQP host. |
RabbitMQ:EventBus:ClientName |
HttpApiHost |
Distributed event-bus client name. |
RabbitMQ:EventBus:ExchangeName |
Cargonerds |
Exchange name. |
AuthServer:Authority |
https://localhost:44345 |
JWT issuer/authority (AddAbpJwtBearer). |
AuthServer:RequireHttpsMetadata |
true |
HTTPS metadata requirement. |
AuthServer:MetaAddress |
https://localhost:44345 |
OIDC metadata address. |
AuthServer:SwaggerClientId |
api |
Client id used by the Swagger OIDC flow. |
StringEncryption:DefaultPassPhrase |
vd7i8105O0jZ7xQl |
String-encryption key. |
Fixed values set in code (not appsettings)
The JWT bearer Audience is hard-coded to "Cargonerds", and the distributed
cache KeyPrefix is built in code as "Cargonerds:", suffixed with
"<AZURE_ENVIRONMENT>:" when that variable is set (ConfigureCache). Neither is
a configuration key. DataProtection keys persist to Redis under
Cargonerds-Protection-Keys (non-Development only).
appsettings.aspire.json (token template)¶
{
"App": {
"SelfUrl": "{api}",
"AllowedCorsOrigins": "{realtime}",
"CorsOrigins": "{realtime},{admin}",
"Realtime": "{realtime}"
},
"AuthServer": {
"Authority": "{auth}",
"MetaAddress": "{auth}",
"WellKnownConfigAddress": "{auth}/.well-known/openid-configuration"
},
"Redis": { "Configuration": "{redis}" },
"RabbitMQ": { "Connections": { "Default": { "HostName": "{messaging}", "Override": true } } }
}
Spark files — Hub data-source selection¶
SPARK_ENVIRONMENT picks one file; it carries the Hub DB, BlobStorage,
hubServiceBus and the per-env App:CargonerdsCustomerId / BookingNumberPrefix.
Some files also override WhiteLabelingOptions:ExternalApis (PricingManager,
E-adapter) for that backend.
| Key (in every spark file) | Purpose |
|---|---|
App:CargonerdsCustomerId |
Tenant id for the backend (absent in local). |
App:BookingNumberPrefix |
Booking-number prefix (e.g. Booking- in dev). |
ConnectionStrings:Hub |
Hub domain SQL DB for this backend. |
ConnectionStrings:BlobStorage |
Azure Storage / Azurite account. |
ConnectionStrings:hubServiceBus |
Azure Service Bus namespace (empty for local). |
WhiteLabelingOptions:ExternalApis:PricingManager / :Eadapter |
Per-env pricing / E-adapter overrides (present in dev/test/prod/prod-read-only). |
| Spark env | Hub DB server | Blob storage | Service bus | Notes |
|---|---|---|---|---|
local |
localhost,1401 db hub-main, user sa |
Azurite devstoreaccount1 on :10100 |
empty | offline dev; BookingNumberPrefix empty. |
dev |
sql-cargonerds-db-gerwc-development app user |
cnhubgerwcdevelopment |
cn-hub-gerwc-development |
BookingNumberPrefix=Booking-. |
test |
sql-cargonerds-db-gerwc-test app user |
cnhubgerwctest |
cn-hub-gerwc-test |
E-adapter ServerId=TRN. |
prod |
sql-cargonerds-db-gerwc-production app user |
cnhubgerwcproduction |
cn-hub-gerwc-production |
E-adapter ServerId=SYD; prod pricing URL. |
prod-read-only |
same prod DB, read user | cnhubgerwcproduction |
cn-hub-gerwc-production |
read-only SQL credential; only PricingManager overridden. |
The Hub pool reads ConnectionStrings:Hub directly with retry + a 3-minute command
timeout (HubEntityFrameworkCoreModule.cs):
var cs = sp.GetRequiredService<IConfiguration>().GetConnectionString(ConnectionStringNames.HubDb);
opts.UseSqlServer(cs, sql => { sql.EnableRetryOnFailure(); sql.CommandTimeout((int)TimeSpan.FromMinutes(3).TotalSeconds); });
// AddDbContextPool<HubDbContext>(..., poolSize: 256)
Blazor admin server — src/Cargonerds.Blazor/¶
The ABP/LeptonX admin UI host. It ships no committed root appsettings.json — it
relies entirely on the layered files plus Aspire env vars.
| File | Loaded | Contents |
|---|---|---|
appsettings.aspire.json |
USE_ASPIRE_CONFIG=true |
token template, wrapped in a ClientConfiguration root. |
{
"ClientConfiguration": {
"App": { "SelfUrl": "{admin}" },
"AuthServer": {
"Authority": "{auth}",
"WellKnownConfigAddress": "{auth}/.well-known/openid-configuration"
},
"RemoteServices": {
"Default": { "BaseUrl": "{api}" },
"AbpAccountPublic": { "BaseUrl": "{api}" }
}
}
}
ClientConfiguration wrapper is Blazor-specific
Unlike the other hosts, the admin Blazor appsettings.aspire.json nests its
settings under a ClientConfiguration root (the values are forwarded to the
Blazor WebAssembly client). App:SelfUrl={admin}, AuthServer:Authority={auth},
RemoteServices:Default:BaseUrl={api} and RemoteServices:AbpAccountPublic:BaseUrl={api}.
Blazor WebAssembly client — src/Cargonerds.Blazor.Client/wwwroot/¶
The WASM client is served statically and does not go through the
AddServiceDefaults() pipeline; its config is plain static JSON.
| File | Contents |
|---|---|
wwwroot/appsettings.json |
committed localhost wiring (see keys below). |
wwwroot/appsettings.Development.json |
{} (empty). |
wwwroot/appsettings.json keys:
| Key | Default | Purpose |
|---|---|---|
Logging:LogLevel:* |
Default=Warning, framework loggers Warning |
Client log levels. |
App:SelfUrl |
https://localhost:44381 |
The Blazor admin client's own base URL. |
AuthServer:Authority |
https://localhost:44345 |
OIDC authority. |
AuthServer:ClientId |
admin |
OIDC client id used by the WASM client. |
AuthServer:ResponseType |
code |
Authorization-code flow. |
RemoteServices:Default:BaseUrl |
https://localhost:44354 |
API base. |
RemoteServices:AbpAccountPublic:BaseUrl |
https://localhost:44354 |
Account API base. |
ConnectivityCheck:Enabled |
false |
Toggle for the client connectivity probe. |
ConnectivityCheck:PingPath |
/odata |
Path the connectivity probe pings. |
Under Aspire these localhost values are superseded by the ClientConfiguration token
template forwarded from the Blazor admin server's appsettings.aspire.json (above).
Web.Public — src/Cargonerds.Web.Public/¶
The public-facing MVC/Razor site.
| File | Loaded | Contents |
|---|---|---|
appsettings.json |
always | App, Redis, RemoteServices, AuthServer (confidential web client). |
appsettings.Development.json |
Development | empty {}. |
appsettings.aspire.json |
USE_ASPIRE_CONFIG=true |
token template. |
appsettings.secrets.json |
AddAppSettingsSecretsJson() |
AbpLicenseCode. |
appsettings.json keys¶
| Key | Default | Purpose |
|---|---|---|
App:SelfUrl |
https://localhost:44332 |
Public site base URL. |
App:DisablePII |
false |
PII switch. |
App:HealthCheckUrl |
/health-status |
Health UI path. |
Redis:Configuration |
127.0.0.1 |
Redis (DataProtection / lock). |
RemoteServices:Default:BaseUrl |
https://localhost:44354/ |
API base for dynamic proxies. |
RemoteServices:AbpAccountPublic:BaseUrl |
https://localhost:44345/ |
Account API base (AuthServer). |
AuthServer:Authority |
https://localhost:44345 |
OIDC authority. |
AuthServer:RequireHttpsMetadata |
true |
HTTPS metadata requirement. |
AuthServer:ClientId |
web |
Confidential OIDC client id. |
AuthServer:ClientSecret |
1q2w3e* |
Confidential client secret. |
appsettings.aspire.json (token template)¶
{
"App": { "SelfUrl": "{web}" },
"RemoteServices": {
"Default": { "BaseUrl": "{api}/" },
"AbpAccountPublic": { "BaseUrl": "{auth}/" }
},
"AuthServer": { "Authority": "{auth}" },
"Redis": { "Configuration": "{redis}" },
"RabbitMQ": { "Connections": { "Default": { "HostName": "{messaging}", "Override": true } } }
}
Note the public site's account API points at {auth} here, whereas its committed
local appsettings.json points AbpAccountPublic at the AuthServer (:44345) and
Default at the API (:44354).
DbMigrator — src/Cargonerds.DbMigrator/¶
A console app that applies EF Core migrations and seeds data. It composes config a
little differently (see Program.cs): it loads appsettings.aspire.json as
non-optional when USE_ASPIRE_CONFIG=true, and when AZURE_ENVIRONMENT is set it
calls AddAzureJsonFiles(azureEnvironment, "azure.migrator") so the
appsettings.azure.migrator.<env>.json overlays load alongside the standard azure
files, supplying DB-admin credentials with DDL rights.
| File | Loaded | Contents |
|---|---|---|
appsettings.json |
always | ConnectionStrings:Default, Redis, and an OpenIddict:Applications[] client-seed list (Cargonerds_App, admin, api, web). |
appsettings.aspire.json |
USE_ASPIRE_CONFIG=true (non-optional) |
Redis/RabbitMQ tokens plus a richer OpenIddict:Applications[] seed (api, realtime, bruno, admin) using {api}/{realtime}/{admin} endpoints. |
appsettings.azure.migrator.<env>.json |
when AZURE_ENVIRONMENT set |
admin ConnectionStrings:Default + SPARK_ENVIRONMENT. |
appsettings.secrets.json |
AddAppSettingsSecretsJson(false) |
AbpLicenseCode. |
appsettings.json keys¶
| Key | Default | Purpose |
|---|---|---|
ConnectionStrings:Default |
Server=(LocalDb)\MSSQLLocalDB;Database=CargonerdsAppDb;… |
App DB the migrator targets locally. Also read by the design-time factory. |
Redis:Configuration |
127.0.0.1 |
Redis (unless --disable-redis). |
OpenIddict:Applications[] |
Cargonerds_App, admin, api, web |
OIDC clients seeded into the DB (client id, type, grant types, redirect/post-logout URIs, secret). |
appsettings.azure.migrator.<env>.json keys¶
| Key | Example | Purpose |
|---|---|---|
ConnectionStrings:Default |
…User ID=spark-db-admin-dev;…Database={spark-db-name} |
Admin SQL user (DDL rights), {spark-db-name} filled by the ConfigurationParameters from the parallel appsettings.azure.<env>.json. |
SPARK_ENVIRONMENT |
dev / prod / prod-read-only |
Pins the Hub backend for the migrator run. |
Variants present: dev, dev.hub-prod, dev.hub-test, prod, prod.staging
(the prod.staging overlay only sets SPARK_ENVIRONMENT=prod-read-only).
Runtime flags & the migration-status endpoint
--enable-api boots a slim web host exposing GET /migration/status, guarded by
comparing the ?token= query value to the PIPELINE_AUTH_TOKEN config value
(returns 503 if the token is not configured). --disable-redis skips Redis.
VALIDATE_MIGRATIONS_ONLY=1 validates without applying. Details:
Migrations.
Design-time EF factory reads only this file
CargonerdsDbContextFactory reads Default from the DbMigrator project's
appsettings.json (no secrets/azure layering). Add-Migration /
Update-Database therefore need that connection string pointing at a reachable
DB. See Migrations and
Entity Framework.
AppHost — src/Cargonerds.AppHost/¶
The .NET Aspire orchestrator. Its own appsettings*.json only configure logging; the
interesting configuration is the white-label file it owns and forwards, and the env
vars it sets on child resources (see Aspire integration).
| File | Loaded | Contents |
|---|---|---|
appsettings.json |
always | Logging:LogLevel (Default=Information, Microsoft.AspNetCore=Warning, Aspire.Hosting.Dcp=Warning). |
appsettings.Development.json |
Development | Logging:LogLevel (Default=Information, Microsoft.AspNetCore=Warning). |
appsettings.rohlig.json |
the canonical white-label file (linked into ServiceDefaults, copied to every host's output). | WhiteLabelingOptions. |
appsettings.rohlig.Development.json |
Development | Logging:LogLevel only (Default=Information, Microsoft.AspNetCore=Warning). |
AppHost-driving environment variables¶
The AppHost reads/forwards these (see
src/Cargonerds.AppHost/EnvVars.cs). They are env vars, not appsettings keys, but
they determine which appsettings files the children load.
| Variable | Read/Set by | Effect |
|---|---|---|
USE_ASPIRE_CONFIG |
set on each child by AddProjectWithDefaults |
makes children load appsettings.aspire.json. Mandatory under Aspire. |
SPARK_ENVIRONMENT |
forwarded to children | selects the spark file / Hub backend. |
WHITE_LABEL_SETTINGS_PATH |
set by WithWhiteLabelSettingsPath |
absolute path to appsettings.rohlig.json (children run with their project dir as cwd). |
APPHOST_AZURE_ENVIRONMENT |
read by AppHost (SparkDbRunModeConfiguration) |
run the local AppHost against an Azure Spark DB. |
APPHOST_AZURE_DATABASE_COPY_SUFFIX |
read by AppHost | append a suffix so it targets a copy of the Azure DB. |
VALIDATE_MIGRATIONS_ONLY |
forwarded to migrator | validate-only migration mode. |
DEPLOYMENT_DOMAIN |
read by AppHost (publish mode) | hostname suffix for services__* in publish mode; throws if missing. |
SKIP_WAITING_IN_BACKEND / EXPLICIT_FRONTEND_START |
read by AppHost | local-start convenience toggles. |
Cloud / Azure overlays — src/Cargonerds.ServiceDefaults/appsettings.azure*.json¶
These files are not per host — they live in ServiceDefaults and are loaded by any
host (and the migrator) when AZURE_ENVIRONMENT is set. The dotted env name expands
cumulatively: AZURE_ENVIRONMENT=dev.hub-test loads appsettings.azure.json →
appsettings.azure.dev.json → appsettings.azure.dev.hub-test.json, then the
ConfigurationParameterReplacementSource rewrites {token}s.
| File | Sets |
|---|---|
appsettings.azure.json |
Services block (admin/api/web/realtime/auth) with {spark-dev-domain} tokens — the resolution table for service-discovery {api} etc. in cloud. |
appsettings.azure.dev.json |
ConnectionStrings:Default (spark-dev), redis, messaging; SPARK_ENVIRONMENT=dev; ConfigurationParameters (spark-dev-domain=dev, rabbit-mq-port=5672, spark-db-name=spark-dev). |
appsettings.azure.prod.json |
prod Default/redis/messaging; SPARK_ENVIRONMENT=prod; prod ConfigurationParameters; real-hostname Services (*.rt3.rohlig.com). |
appsettings.azure.dev.hub-test.json |
overlay: ConfigurationParameters (spark-db-name=spark-dev-hub-test, rabbit-mq-port=5674) + SPARK_ENVIRONMENT=test. |
appsettings.azure.dev.hub-prod.json |
overlay: ConfigurationParameters (spark-db-name=spark-dev-hub-prod, rabbit-mq-port=5673) + SPARK_ENVIRONMENT=prod-read-only. |
appsettings.azure.prod.staging.json |
overlay: ConfigurationParameters (spark-db-name=spark-prod-staging) + SPARK_ENVIRONMENT=prod-read-only + a Services block re-pointing to {spark-dev-domain}.spark.cargonerds.dev. |
Keys in the azure files¶
| Key | Purpose |
|---|---|
ConnectionStrings:Default |
The deployment's ABP application (Spark) DB; uses {spark-db-name}. |
ConnectionStrings:redis |
Azure Redis connection string (consumed via Aspire AddRedisClient("redis")). |
ConnectionStrings:messaging |
RabbitMQ AMQP URI; uses {rabbit-mq-port}. |
SPARK_ENVIRONMENT |
Pins the Hub backend for this Azure deployment (this is how the two axes are kept in sync in cloud). |
ConfigurationParameters |
spark-dev-domain, rabbit-mq-port, spark-db-name — substituted into the values above and into Services URLs. |
Services:<name>:https[] |
Public URLs that service-discovery {admin}/{api}/{web}/{realtime}/{auth} tokens resolve to at runtime. |
// appsettings.azure.dev.json (abbreviated)
{
"ConnectionStrings": {
"Default": "Server=tcp:sql-spark-dev.database.windows.net,1433;User ID=spark-app;Password='…';Initial Catalog={spark-db-name}",
"messaging": "amqp://sparkuser:…@rabbitmq.dev.spark.cargonerds.dev:{rabbit-mq-port}/"
},
"SPARK_ENVIRONMENT": "dev",
"ConfigurationParameters": { "spark-dev-domain": "dev", "rabbit-mq-port": 5672, "spark-db-name": "spark-dev" }
}
Nested tokens
The Services URLs deliberately nest a ConfigurationParameters token inside a
service-discovery target, e.g.
"api": { "https": ["https://api.{spark-dev-domain}.spark.cargonerds.dev"] }.
{spark-dev-domain} is resolved by the ConfigurationParameters source first; the
finished URL then becomes the value that {api} resolves to.
White-label — appsettings.rohlig.json¶
One canonical file in the AppHost project; linked into ServiceDefaults via the csproj
and copied to every host's output. Bound to WhiteLabelingOptions
(modules/hub/src/Hub.Domain.Shared/WhiteLabeling/). Spark files override
sub-sections of WhiteLabelingOptions:ExternalApis per environment.
| Key | Type | Purpose |
|---|---|---|
AppName |
string | Product name (Realtime). |
CompanyName / CompanyNameShort |
string | Röhlig Logistics / Röhlig. |
Logo / AppLogo / BackgroundImage / BackgroundVideo / Favicon |
string | Branding asset paths under /_content/Cargonerds.UI.Shared/rohlig/…. |
DisableCustomUserName |
bool | Hide the custom-username feature (true). |
AdditionalJavaScriptFiles / AdditionalStyleSheetFiles |
string[] | Extra JS/CSS injected into the UI. |
CopyrightLinks[] / FooterLinks[] |
FooterLink (Label/Url/Target) |
Footer/copyright links. |
EntraLogins[] |
EntraLogin (Name/TenantId/ClientId/Secret) |
Microsoft Entra external-login providers (registered via AddEntraId). |
ExternalApis:Google |
DistanceMatrixApiKey, PlacesApiKey, DistanceUrlTemplate |
Google Maps keys. |
ExternalApis:Algolia |
AppId, ApiKey, IndexName |
Algolia search. |
ExternalApis:PricingManager |
Url, ApiKey |
Pricing engine endpoint (overridden per Spark env). |
ExternalApis:Eadapter |
Url, ApiKey, ServerId, EnterpriseId |
Röhlig E-adapter (overridden per Spark env; ServerId TRN/SYD). |
ExternalApis:MapTiler |
ApiKey |
MapTiler tiles. |
[PublicConfiguration] controls what reaches the browser
Most WhiteLabelingOptions members carry [PublicConfiguration] so they are
exposed to front-ends. EntraLogins is not marked public (it holds the
client secret) and is consumed server-side only.
secrets files — appsettings.secrets.json¶
Loaded by ABP's AddAppSettingsSecretsJson() in every host's Program.cs. In this
solution each one contains exactly one key.
| Key | Purpose |
|---|---|
AbpLicenseCode |
The ABP commercial license (identical copy committed in AuthServer, HttpApi.Host, Web.Public and DbMigrator). |
There is no per-developer .NET User Secrets store in play except the UserSecretsId
on the AppHost project; everything else is committed JSON.
Cross-cutting gotchas¶
RabbitMQ override is opt-in and silent
ConfigureRabbitMQ only rewrites AbpRabbitMqOptions when
RabbitMQ:Connections:Default:Override == true and the HostName parses as a
URI — then it splits the AMQP URI into user/pass/host/port. If Override is false
or the value is not a URI, the raw HostName is used verbatim with no warning.
The Aspire templates set Override: true so the {messaging} AMQP URI is parsed.
SPARK_ENVIRONMENT typos crash startup
SparkEnvironment.FromName(null) returns Dev, but any unknown non-empty value
throws ArgumentException at startup rather than defaulting.
Cache prefix isolates environments on shared Redis
The cache key prefix is Cargonerds: plus <AZURE_ENVIRONMENT>: when set. An empty
AZURE_ENVIRONMENT shares the base Cargonerds: prefix.
Edit the source file, not the build copy
appsettings.rohlig.json is copied to every host's bin/ output. There is exactly
one editable copy (the AppHost project, plus the TestBase copy used by tests).
Editing a bin/.../appsettings.rohlig.json has no lasting effect.
Filename typo
The AppHost helper file is misspelled ConfigruationExtensions.cs — grep for that
exact spelling.
See also¶
- Configuration Settings — the loading pipeline, precedence, token systems, environment axes and recipes.
- Deployment configuration — applying these files in Azure environments.
- Aspire integration — how the AppHost wires env vars and service references.
- Solution structure — the hosts and the two DbContexts / connection strings.
- Caching — Redis, the cache key prefix, DataProtection.
- Messaging — RabbitMQ / distributed event bus.
- Migrations — DbMigrator flags and the design-time factory.
- Public Web and Blazor — host-specific
consumption of
RemoteServices,AuthServerand white-label options. - Repo-root files referenced by the build:
common.props,AGENTS.md.