xrmverse
Documentation menu

Configuration

← xrmverse documentation

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.