Infrastructure
This document describes how Confinity is installed in a production environment. Since the host application decides how the hosting is done, many possible exist. The full list can be found at https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy (all the provided deployments are supported).
The complete system configuration follows the Configuration fundamentals in ASP.NET Core. This allows, that all configuration can be set in the appsettings.json, overridden by Environment variables and/or command-line arguments. Parts of the configuration in the appsettings.json can be changed at runtime. Therefore most of the configuration should be made in appsettings.json file.
Overwrite settings in environment variables
To overwrite configuration defined in appsettings.json files set environment variables. To go into an object, use two underlines __
For example: to set the default log level:
{
"Logging": {
"LogLevel": {
"Default": "Trace"
}
}
}
one can also set this variable:
Logging__LogLevel__Default=Trace
Confinity Configuration
appsettings Key: Confinity
| Configuration Key | Description | Default |
|---|---|---|
| Database__ConnectionString | required: The connection string to the database. This depends on the database provider. | |
| LoadUnstableModules | Enables Confinity Features which are not in a stable form. | false |
| IsAuthorInstance | Defines if this instance is an author instance. /1/ This can only be true for a single instance at any given time. | true |
| EnableSensitiveDataLogging | Enables application data to be included in exception messages, logging, etc. This can include the values assigned to properties of your entity instances, parameter values for commands being sent to the database, and other such data. You should only enable this flag if you have the appropriate security measures in place based on the sensitivity of this data. | false |
| EnableDetailedErrors | Enables detailed errors when handling of data value exceptions that occur during processing of store query results. Such errors most often occur due to misconfiguration of entity properties. E.g. If a property is configured to be of type 'int', but the underlying data in the store is actually of type 'string', then an exception will be generated at runtime during processing of the data value. When this option is enabled and a data error is encountered, the generated exception will include details of the specific entity property that generated the error. | false |
| ServeUiFromAssembly | Whether the UI is served from the host application or not (leave this on). | true |
| AllowedOrigins | Which domains are allowed to access the cms. This is used to verify the websockets origin (improves security). The origin must include the protocol. Ex. ["https://foo.bar.local:8443", "https://my-cms.local"] | all |
| LoginEnabled | By default, logging in to Confinity is only enabled on the author instance. Set this to true to enablelogin on public instances. | false |
| SeedData | Flag indicating if the implementations of IDataSeeder should be executed on startup. | true |
| AllowedFileEndings | List of allowed file endings for the asset management. Default: ["AI", "AIFF", "APK", "AVI", "BMP", "CSV", "DOC", "DOCM", "DOCX", "DOT", "DOTM", "DOTX", "EPS", "FLV", "GIF", "IPA", "JPEG", "JPG", "MID", "MOV", "MP3", "MP4", "MPG", "PDF", "PNG", "PPS", "PPSX", "PPT", "PPTM", "PPTX", "PSD", "RAR", "RTF", "SVG", "SWF", "TIF", "TIFF", "TXT", "VSD", "WAV", "WEBP", "WEBM", "WMF", "XLS", "XLSM", "XLSX", "XLT", "XLTM", "XLTS", "XML", "XSD", "ZIP",] | list |
| AllowedFileUploadSizeInMB | Allowed asset management file upload size in MB. | 200 |
| PathBase | Adds a prefix for all URL paths. The path must have a leading slash and no tailing. This is useful, if the application is running in a sub path. | |
| AuthJwk__JsonWebKey | Json Web Key (JWK) used for the login.* Expected is the JWK as an object. | |
| AuthJwk__Filepath | File path to the Json Web Key.* |
** When the key Confinity__AuthJwk_JsonWebKey or Confinity__AuthJwk_Filepath is not configured one is generated at startup. All generated tokens between restarts will be invalidated by this.
Minimal configuration:
{
"Confinity": {
"Database": {
"ConnectionString": "./file.db"
}
}
}
Mail Configuration
The configuration must be provided if the module is used: Mail Configuration
Asset Configuration
The configuration is optional. For details see: Asset Configuration
Pages Configuration
For details see: Pages Configuration
Replication Configuration
For details see: Replication Configuration
Http Header Configuration
The configuration is optional. For details see: Http Header Configuration
Cookie Configuration
The configuration is optional. For details see: Cookie Configuration
Search: Elasticsearch Configuration
The configuration is optional. For details see: Elasticsearch Configuration
The recommended way is to use an installation method from bitnami. https://bitnami.com/stack/elasticsearch
Search: Lucene Configuration
The configuration is optional. For details see: Lucene Configuration
Media Player Configuration
The configuration is optional. For details see: Media Player Configuration
Form Configuration
see: Form Configuration
Proxy
The proxy set by the system will be used for all connections by default. The custom modules offer ways to disable the proxy configuration or set a different proxy at all.
For details see
Kestrel
Confinity uses the internal Kestrel webserver. Like Confinity it can be configured in the appsettings (key: Kestrel) to match the needed requirements.
The Kestrel entry maps to (KestrelServerOptions)[https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.server.kestrel.core.kestrelserveroptions#replace-the-default-certificate-from-configuration] . In a few cases the limits ( under Kestrel.Limits) must be configured.
For more details see
Useful links:
- (setup Kestrel with certificates)[https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints]
Database
The database configuration is primary done in the host application. There are a few exception:
- Confinity.Database.ConnectionString must be set for the connection to the application.
- For Microsoft SQL Server follow their documentation how to define the Connection String
- For PostgreSQL PG* Environment variables can be configured to overwrite / append to the connection string. List of environment variables
https://www.postgresql.org/docs/current/libpq-envars.html
Linux recommendations
Set the correct timezone.
Add 3rd party trusted root certificate
Third party certificates can be added, but must be in the right location. The configuration depends on the distro.
Debian / Default docker image mcr.microsoft.com/dotnet/aspnet
Mount / Copy the certificates to /usr/local/share/ca-certificates/ and run update-ca-certificates
For a docker setup, the recommended way is to set the entry point to a script
Dockerfile
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["dotnet", "YourApp.dll"]
docker-entrypoint.sh
#!/bin/sh
set -e
update-ca-certificates
echo "Start application: ${*}"
exec "$@"
Firewall / WAF Configuration
Please consider the following best practices when configuring the firewall / waf:
- The Confinity backend should only be reachable from a known set of IP addresses. This greatly reduces the attack surface.
- If possible enable Anti-Virus scanning for these paths:
- POST : /.mod/api/confinity-forms/file
- POST : /.confinity/api/asset/file
- Web sockets should be enabled for /.confinity
- Setup a health check for /.confinity/health (the response conde should be 200 and the Body "Healthy")
- Temporary: set the max request time for /.confinity to 90 seconds.
Example configuration 2 nodes 3 stages with microsoft sql server und elastic search as docker container
Common configuration for Confinity docker containers:
- Environment variables:
- key:
TZ
value:Europe/Zurich
set the correct timezone - key:
ASPNETCORE_ENVIRONMENT
value:Production
use the appsettings.Production.json file as well.
- key:
- File: appsettings.json mounted to /app/appsettings.json
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", "Confinity": { "Database": { "ConnectionString": "by ENV" } }, "ConfinityElasticsearch": { "Host": "http://localhost:9200" } } - Mount a semi persistent directory to
/app/cachefor better performance
Common configuration for Elasticsearch:
Author: Environment variables:
- key:
Confinity__Database__ConnectionString
value:Server=<db-server>;Database=<confinity-author-database>;User Id=<confinity-author-user>;Password=<confinity-author-password>;Persist Security Info=True"
connection string to the database (replace placeholders) - key:
ASPNETCORE_URLS
value:http://*:6000
Author instance does listen on port 6000 - key:
ConfinityElasticsearch__InstanceKey
value:author
Elasticsearch index for author stage File appsettings.Production.json:
{
"ConfinityReplication": {
"Stages": {
"previewStage": {
"Key": "previewStage",
"Order": 1,
"Label": "Preview",
"Instances": {
"preview1": {
"Key": "preview1",
"ServerUrl": "http://node1:7000",
"Secret": "<password-preview1>"
},
"preview2": {
"Key": "preview2",
"ServerUrl": "http://node2:7000",
"Secret": "<password-preview2>"
}
}
},
"publicStage": {
"Key": "publicStage",
"Order": 2,
"Label": "Public",
"Instances": {
"public1": {
"Key": "public1",
"ServerUrl": "http://node1:8000",
"Secret": "<password-public1>"
},
"public2": {
"Key": "public2",
"ServerUrl": "http://node2:8000",
"Secret": "<password-public1>"
}
}
}
}
}
}
Preview:
Environment variables:
- key:
Confinity__Database__ConnectionString
value:Server=<db-server>;Database=<confinity-preview-database>;User Id=<confinity-preview-user>;Password=<confinity-preview-password>;Persist Security Info=True
connection string to the database (replace placeholders) - key:
ASPNETCORE_URLS
value:http://*:7000
Preview instance does listen on port 7000 - key:
ConfinityElasticsearch__InstanceKey
value:preview
Elasticsearch index for preview stage
Environment variables Node1:
- key:
ConfinityReplication__ReplicationHubSecret
value:<password-preview1>
password to connect form author instance to preview on node1
Environment variables Node2:
- key:
ConfinityReplication__ReplicationHubSecret
value:<password-preview2>
password to connect form author instance to preview on node2
Public:
Environment variables:
- key
Confinity__Database__ConnectionString
value:Server=<db-server>;Database=<confinity-public-database>;User Id=<confinity-public-user>;Password=<confinity-public-password>;Persist Security Info=True"
connection string to the database (replace placeholders) - key:
ASPNETCORE_URLS
value:http://*:8000
Author instance does listen on port 8000 - key:
ConfinityElasticsearch__InstanceKey
value:public
Elasticsearch index for public stage
Environment variables Node1:
- key:
ConfinityReplication__ReplicationHubSecret
value:<password-public1>
password to connect form author instance to public on node1
Environment variables Node2:
- key:
ConfinityReplication__ReplicationHubSecret
value:<password-public2>
password to connect form author instance to public on node2
ENV TZ=Europe/Zurich
ENV ASPNETCORE_ENVIRONMENT=Production
ENV ASPNETCORE_URLS=http://*:5000