Configuration
Variables in docker/.env of the repository compose file (mapped to the ASP.NET keys Section__Key). An installation
generated by xrmd server init uses the same keys for the shared settings and per-organization keys instead of
AUTH_AUDIENCE, SEED_ORG_NAME and SEED_ADMIN_OBJECT_ID; see Multiple organizations.
.env variable |
Configuration key | Notes |
|---|---|---|
SA_PASSWORD |
ConnectionStrings:Org (built by the compose file) |
SQL Server sa password, required |
MSSQL_PID |
(the sqlserver service) |
SQL Server edition or product key, default Express; see SQL Server editions |
AUTH_MODE |
Auth:Mode |
Entra or Development |
AUTH_AUDIENCE |
Auth:Audience |
server base URL, e.g. http://localhost:5000/ |
AUTH_TENANT_ID |
Auth:TenantId |
required with Entra: tenant GUID |
AUTH_DEV_SIGNING_KEY |
Auth:DevSigningKey |
Development only, required, at least 32 characters (openssl rand -hex 32) |
XRMD_SDK_HOST_DIR |
(the SDK mount of the compose file; XRMD_SDK_DIR=/var/lib/xrmd/sdk in the container) |
host folder of the Microsoft SDK, mounted read-only; default ${HOME}/.xrmd/sdk, where xrmd sdk install writes. See Installing the Microsoft SDK |
XRMD_BIND |
(port published by the compose file) | default 127.0.0.1: port 5000 is reachable only from the local machine; set 0.0.0.0 to expose it on the network |
SEED_ORG_NAME |
Seed:OrgName |
organization name (default xrmd) |
SEED_ADMIN_OBJECT_ID |
Seed:AdminObjectId |
administrator GUID (oid), required |
SEED_ADMIN_NAME |
Seed:AdminName |
administrator name |
SEED_BASE_CURRENCY |
Seed:BaseCurrency |
ISO 4217 code of the base currency; applies when the organization is first created. Empty or not set (the compose default) means not given: a new organization gets EUR, an existing one keeps its base currency without a warning. See Currencies |
(not in .env) |
Seed:BaseCurrencyName, Seed:BaseCurrencySymbol, Seed:BaseCurrencyPrecision |
optional: name (up to 100 characters), symbol (up to 5) and decimal places (0 to 4, default 2) of the base currency; the defaults are the code, the code and 2 (Euro, € for EUR) |
(not in .env) |
Seed:RootBusinessUnitId |
optional; by default derived from the organization name |
(not in .env) |
Startup:SqlRetries, Startup:SqlRetryDelaySeconds |
SQL Server wait, default 30 x 2 s |
(rendered from .env, see below) |
Proxy:TrustedProxies |
comma-separated IP addresses and CIDR networks (e.g. 172.30.0.2, 172.30.0.0/24) of the reverse proxies whose X-Forwarded-For, -Proto and -Host are honored (one hop); empty (default): forwarded headers are ignored. An invalid entry stops the server at startup with exit code 3, naming the entry |
(rendered from .env, see below) |
Proxy:AllowedHosts |
comma-separated host names (e.g. acme.example.com) a forwarded host must match; empty: any host forwarded by a trusted proxy. A request forwarded for another host keeps its own scheme, host and client address, and the host is logged once at warning |
FILES_STORE |
Files:Store |
FileSystem (default), S3Compatible or AzureBlob; see Files and images |
FILES_ROOT |
Files:FileSystem:Root |
default /var/lib/xrmd/files (the compose files mount the files volume there) |
FILES_S3_SERVICE_URL, FILES_S3_BUCKET, FILES_S3_ACCESS_KEY, FILES_S3_SECRET_KEY |
Files:S3:ServiceUrl, Files:S3:Bucket, Files:S3:AccessKey, Files:S3:SecretKey |
required with S3Compatible |
FILES_S3_REGION, FILES_S3_FORCE_PATH_STYLE |
Files:S3:Region, Files:S3:ForcePathStyle |
default us-east-1 and true |
(not in .env) |
Files:MaxNoteBodyBytesPerRead |
default 67108864 (64 MB): the most bytes of note bodies (annotation.documentbody) one query reads into memory; a page whose bodies add up to more is refused with a 400 that names the column, before any body is read. Leave documentbody out of the ColumnSet or $select, or read fewer notes per page. A server-side bound, not a Dataverse limit. A value that is not a whole number of 1 or more stops the server at startup |
FILES_AZURE_CONTAINER |
Files:Azure:Container |
required with AzureBlob; the container must exist |
FILES_AZURE_CONNECTION_STRING, FILES_AZURE_SERVICE_URI |
Files:Azure:ConnectionString, Files:Azure:ServiceUri |
with AzureBlob set exactly one: a connection string, or the https blob endpoint URL (signs in with Microsoft Entra ID) |
(not in .env) |
Admin:BackupDirectory, Admin:FilesBackupDirectory |
backup directory as SQL Server sees it (default /var/opt/mssql/backup); the .files.tar directory as xrmd sees it (default: the former) |
(rendered from .env, see SQL endpoint) |
Tds:Port, Tds:CertificatePath, Tds:PrivateKeyPath |
the read-only SQL (TDS) endpoint, off while Tds:Port is not set; Auth:Mode=Local only. The certificate and the key are PEM files, set together, required outside Development; the files are checked every 10 s and the listener restarts when they change. The generated compose file sets Tds__Port to 5558 inside the container and publishes ORG_<ORG>_TDS_PORT on it |
(not in .env) |
Tds:MaxRows, Tds:Timeout |
the most rows one query returns (default 50000; a larger result fails, never partial) and the time limit of one batch (default 00:05:00) |
(not in .env) |
Elastic:TtlSweepSeconds |
seconds between two sweeps that delete elastic rows whose ttlinseconds has run out (default 60; 0 switches the sweep off). A row expires at modifiedon plus its ttlinseconds; each sweep removes up to 500 expired rows per elastic table, as the system user, with audit and change tracking recording a Delete and without running plug-in steps. A sweep that deleted 500 rows or more runs again at once, so a backlog drains without waiting for the next interval. A row that cannot be deleted is logged and skipped, and does not hold back the rows behind it. Rows that have expired but are not swept yet can still be read |
Without ConnectionStrings:Org the host still starts and serves only /healthz. If Auth:Mode is set, an invalid
Auth configuration makes startup fail; without Auth:Mode the host starts but rejects every token. All endpoints
except /healthz require a token.
Installation keys
An installation generated by xrmd server init adds these keys to its .env (the organization keys XRMD_ORGS and
ORG_<ORG>_PORT|ADMIN_OBJECT_ID|AUDIENCE are in Multiple organizations). The CLI
re-renders docker-compose.yml and Caddyfile from them; an inconsistent value makes every server command exit 5
naming the key. See Installing xrmverse for the whole procedure.
.env key |
Written by | Meaning |
|---|---|---|
XRMD_IMAGE |
init (--image), upgrade --to |
the server image: ghcr.io/power-builders-italia/xrmd:<CLI version>, or xrmd:local for a development CLI |
XRMD_DOMAIN |
init --domain |
organization <org> gets the host <org>.<domain>; empty: no host unless ORG_<ORG>_HOST |
ORG_<ORG>_HOST |
init --public-host <org>=<host>, org add --public-host |
the public host of one organization, instead of <org>.<domain>. With a host the default audience is https://<host>/ |
PROXY_MODE |
init with a host (caddy, or external with --no-proxy) |
caddy (the default when an organization has a host: the generated proxy service) or external (your own proxy). Ignored while no organization has a host |
TLS_MODE |
init --tls |
caddy only, required there: acme, files (certs/server.crt and certs/server.key) or internal (Caddy's local CA) |
TLS_ACME_EMAIL |
init --acme-email |
required with TLS_MODE=acme, empty otherwise |
TRUSTED_PROXIES |
init --trusted-proxy |
external only, required there: comma-separated IPs and CIDRs of your proxy, rendered as Proxy__TrustedProxies |
EDGE_SUBNET |
init --edge-subnet |
caddy only: subnet of the compose network edge, default 172.31.250.0/24, /27 or larger; the proxy has its .10 address, which every organization with a host trusts (Proxy__TrustedProxies), and the other containers get addresses from the upper half only (ip_range, 172.31.250.128/25 by default), so none can take .10 |
EXPOSE_PORTS |
init --expose-ports |
caddy only: true keeps publishing each organization's port on XRMD_BIND for diagnostics; otherwise the organizations publish no host port. With external the ports are always published |
PROXY_BIND |
(add it by hand) | caddy only: the address the proxy publishes ports 80 and 443 on, default 0.0.0.0 |
XRMD_BIND |
(add it by hand) | the address of the organizations' published ports, default 127.0.0.1 |
ORG_<ORG>_TDS_PORT |
init --tds-port, org add --tds-port |
the host port of the organization's read-only SQL endpoint (1-65535); empty or absent: none. Needs AUTH_MODE=Local and a host for the organization; not 80 or 443 with the generated proxy; distinct from every other port of the installation. See SQL endpoint |
XRMD_TDS_BIND |
(add it by hand) | the address the SQL endpoints' ports are published on, default 0.0.0.0 |
Each organization with a host gets Proxy__AllowedHosts=<its host>, so a forwarded host of another organization is
ignored.