Skip to content

Installation and configuration – running nexxcite

This chapter describes what nexxcite needs to run, how the first start proceeds and which settings operators make in the configuration of the application. Running several servers side by side is described separately in Running several servers.

It is intended for operators who install and run nexxcite.


1. Installation at a glance

nexxcite is a web application. It is delivered as a container image and runs as one process per server. All data – definitions, records, history – is kept in a SQL Server database.

Component Required Remark
Container runtime (Docker, Kubernetes, …) yes The image contains the application and the .NET runtime.
SQL Server database yes An empty database and a login that may create tables in it. nexxcite creates and updates the tables itself.
License key yes Without a valid license key, nexxcite is locked. See Licensing.
Reverse proxy or load balancer with TLS recommended Terminates HTTPS. It must pass WebSocket connections through.
Directory for the key storage recommended, required for several servers Keeps users signed in across restarts. See section 5.
Azure Blob Storage or S3-compatible storage for images and files Configured in the global settings, see Global settings.
Redis for several servers Shared definition cache and message bus. See Running several servers.
Mail account (SMTP or Exchange Online) for password reset Configured in the global settings, see Global settings.

Where settings are made

Where What Who
Configuration of the application (appsettings.json or environment variables) Database, servers, key storage, proxies, monitoring endpoints, timings Operators
Admin Studio → System → Settings License key, sign-in rules, mail account, file storage, styles Administrators, see Global settings

2. The container

Property Value
Base The official ASP.NET Core runtime image of Microsoft (.NET 10)
User Runs as the non-root user app of the base image
Port 8080 (HTTP)
Working directory /app
Logs Written to the console (standard output)

Configuration through environment variables

Every setting of appsettings.json can be set as an environment variable. The sections are separated by two underscores: DataAccess:ConnectionString becomes DataAccess__ConnectionString. An environment variable overrides the value in the file, so no configuration file has to be mounted into the container.

Example – a single server with Docker:

docker run -d --name nexxcite -p 8080:8080 \
  -e DataAccess__ConnectionString="Server=sqlserver;Database=nexxcite;User Id=nexxcite;Password=…;TrustServerCertificate=True" \
  -e DataProtection__KeyRingPath=/keys \
  -v nexxcite-keys:/keys \
  -e Logging__File__Path= \
  -e Logging__LogLevel__Default=Information \
  <nexxcite image>

The user app must be allowed to write to the directory of the key storage.

Logging

nexxcite writes its log to the console, where container platforms collect it. In addition, the default configuration writes a file app.log next to the application.

Setting Default Meaning
Logging:LogLevel:Default Debug Lowest level that is logged. For production we recommend Information.
Logging:File:Path app.log File the log is also written to. Empty switches the file off – recommended in containers, where the file disappears with the container.
Logging:File:FileSizeLimitBytes 5242880 Size at which a new file is started (5 MB)
Logging:File:MaxRollingFiles 5 Number of files kept

HTTPS and the environment

nexxcite expects to be reached through HTTPS. In a typical setup, a reverse proxy, load balancer or ingress terminates TLS and forwards the requests to port 8080 over HTTP. Configure the forwarded headers (section 5) so that nexxcite knows the original scheme and the address of the client.

Run production installations with ASPNETCORE_ENVIRONMENT set to Production (the default when the variable is not set). It activates the error page for users and HSTS. Do not use Development in production: users would see technical error details.

Requirements for the proxy

  • WebSockets must be passed through. Every open browser tab keeps a permanent connection to the server.
  • Timeouts for idle connections must be long enough for permanent connections. Browser and server exchange a sign of life about every 15 seconds.
  • Request size: do not limit it below the size of the files your users upload.
  • With several servers, sticky sessions are required in addition. See Running several servers.

3. First start

On the first start against an empty database, nexxcite proceeds as follows:

  1. It creates all tables it needs (see section 4).
  2. It creates the basic definitions: the roles "Administrator" and "Default User", the user profile entity with a default form, and the user nxadmin with the role "Administrator". These changes are published as a sketch named "Scaffold System" followed by the time.
  3. It writes the password of nxadmin to its log:

    INFO: Default user created with password: "nxAdm!n2026"

  4. It starts to accept requests. Since there is no license key yet, every request leads to the page "License required".

Then:

  1. Open nexxcite in the browser and enter the license key on the page "License required".
  2. Sign in as nxadmin with the password from the log.
  3. Change the password of nxadmin immediately. The default password is the same for every installation.
  4. In the Admin Studio under System → Settings, set at least the company name, the mail account and the file storage. See Global settings.

The role "Administrator" has the permission "System Developer" and with it every permission of nexxcite. See Roles and permissions.

Do not delete the user nxadmin. nexxcite checks at every start whether it exists. If it does not, it creates it again – with the default password. Deactivate the user instead if you do not want to use it.


4. Schema migration at startup

Every time a server starts, it brings the database schema up to date before it accepts requests: it creates missing tables, columns and indexes. There is no separate migration tool and no manual step after an update.

  • Several servers migrate one after the other. A server that starts while another one migrates waits up to 10 minutes. If the migration is not finished by then, the server stops with an error rather than working on a half-migrated database. Started again, it migrates whatever is still missing.
  • While the migration runs, the server does not answer requests. The startup endpoint /health/startup therefore only answers once the migration is complete (section 5).
  • Back up the database before every update. A migration cannot be undone by nexxcite.

Tables of entities are changed when an entity is published, not at startup. Such a change can take a while on large tables; its time limit is set with DataAccess:SchemaMigrationTimeout.


5. Settings for operation

The following settings are made in the configuration of the application. The defaults are those of the delivered appsettings.json.

Database

Setting Default Meaning
DataAccess:ConnectionString – Required. Connection string of the SQL Server database. Without it, nexxcite does not start ("DataAccess:ConnectionString must be set").
DataAccess:SchemaMigrationTimeout 00:10:00 Time limit (hh:mm:ss) for each statement when the table of an entity is changed. Empty uses 10 minutes.

Keep the connection string out of files that are shared – it contains the password of the database. On container platforms, set it from a secret.

Application server

Setting Default Meaning
ApplicationServer:MultiServerMode false true when more than one server works with the same database. See Running several servers.
ApplicationServer:InstanceId a new random id at every start Name of the server in monitoring and in the history. Must be unique per server.
ApplicationServer:ProcessScheduledActions true Runs the scheduled actions on this server
ApplicationServer:ProcessMailboxListeners true Polls the mailboxes of the mailbox listeners on this server
ApplicationServer:ManagementPort empty Port on which the health and metrics endpoints answer. Empty: on every port.

With a single server, keep the defaults. With several servers, exactly one server may process scheduled actions and mailbox listeners.

Data protection keys

nexxcite encrypts the sign-in cookie, form tokens and stored tokens of connected services (OAuth 2.0) with a set of keys.

Setting Default Meaning
DataProtection:KeyRingPath empty Directory in which the keys are kept. Empty keeps them in memory only.
DataProtection:ApplicationName nexxcite Name the keys are bound to. Must be the same on every server. Only change it to separate two installations that share a directory.

Without a directory, every restart signs all users out, and stored tokens of connected services can no longer be read – such connections have to be authorised again. With MultiServerMode, the directory is mandatory and must be shared by all servers; without it, nexxcite does not start.

Back up the directory. Whoever can read it can decrypt sign-in cookies, so protect it like a password.

Secrets in definitions

Passwords, API keys and other secrets of credentials are encrypted with a key of their own, separate from the data protection keys above. The encryption is switched off by default.

Setting Default Meaning
DefinitionSecrets:Enabled false Encrypts secrets when a definition is stored.
DefinitionSecrets:Key empty 32 random bytes, Base64 encoded. Must be the same on every server.
DefinitionSecrets:PreviousKeys empty Keys used before the current one, to read what they encrypted.

Keep a copy of the key. Without it, every encrypted secret has to be entered again. See Secrets for switching the encryption on and replacing the key.

Forwarded headers

When a proxy forwards requests to nexxcite, the proxy is the sender as far as nexxcite can see. The headers X-Forwarded-For and X-Forwarded-Proto tell nexxcite the address of the client and whether the original request used HTTPS. nexxcite only trusts them when configured to.

Setting Default Meaning
ForwardedHeaders:Enabled false Trusts the forwarded headers. Leave it off only if nothing runs in front of nexxcite.
ForwardedHeaders:Headers XForwardedFor,XForwardedProto Which headers are trusted, separated by commas: XForwardedFor, XForwardedProto, XForwardedHost, XForwardedPrefix or All
ForwardedHeaders:ForwardedForHeaderName empty (X-Forwarded-For) The header the client address is read from. Set it when your proxy or CDN passes the client on in a header of its own, for example X-Real-IP, CF-Connecting-IP or True-Client-IP. Only used while XForwardedFor is among the trusted headers.
ForwardedHeaders:ForwardLimit empty (1) Number of proxies in a row whose entries are processed. Count every hop (a firewall, a load balancer and an ingress are three). 0 means unlimited.
ForwardedHeaders:KnownProxies empty IP addresses of trusted proxies, separated by commas
ForwardedHeaders:KnownNetworks empty Networks of trusted proxies in CIDR notation, for example 10.0.0.0/8
ForwardedHeaders:TrustAllProxies false Trusts every sender instead of the two lists above

Example – one reverse proxy in the network 10.0.4.0/24: set Enabled to true and KnownNetworks to 10.0.4.0/24.

Use TrustAllProxies only when nexxcite cannot be reached other than through the proxy (for example secured by a firewall or network policy). Otherwise a caller could fake their address.

Example – a CDN that passes the client in CF-Connecting-IP: set Enabled to true, Headers to XForwardedFor,XForwardedProto, ForwardedForHeaderName to CF-Connecting-IP, and list the addresses of the CDN in KnownNetworks.

Symptoms of a missing configuration: every user appears with the address of the proxy – also in the authentication log – all users share one limit of sign-in attempts (see LoginProtection below), and nexxcite may consider requests as plain HTTP although the browser uses HTTPS – which can lead to redirect loops.

Health and metrics endpoints

nexxcite offers endpoints for the probes of a container platform and for metrics. They answer without sign-in and do not reveal any details – the health endpoints answer only with the status word (Healthy, Degraded or Unhealthy).

Endpoint Checks Use
/health/startup nothing – answers once the start (migration included) is complete Startup probe: wait until it answers
/health/live whether the process answers Liveness probe: restart the server if it fails
/health/ready whether the database can be reached Readiness probe: send no requests while it fails
/metrics – Metrics in Prometheus format

/health/live deliberately does not check the database: an outage of the database would otherwise restart every server in turn without fixing anything.

Setting Default Meaning
ApplicationServer:ManagementPort empty When set, the four endpoints answer only on this port. nexxcite must also listen on it, for example with ASPNETCORE_HTTP_PORTS=8080;8081. Do not publish this port to users.
Telemetry:MetricsEnabled true Collects metrics and serves them under the metrics route
Telemetry:MetricsRoute /metrics Address of the metrics
Telemetry:OtlpEndpoint empty Additionally sends metrics (and traces, if switched on) to an OpenTelemetry collector, for example http://collector:4317
Telemetry:TracesEnabled false Records traces of requests, outgoing HTTP calls and database statements. Only useful with a collector.
Telemetry:ServiceName nexxcite Name the servers report under. The InstanceId is added to tell the servers apart.

The metrics include requests and their duration, open connections, active user connections (Blazor circuits), memory and thread pool figures. The names of the metrics follow the .NET runtime and may change with new .NET versions; check them against /metrics of your installation before you build alerts or scaling rules on them.

Without ManagementPort, the endpoints are reachable for everybody who can reach nexxcite. Set the port or block the paths at your proxy.

Definition cache and messaging

Setting Default Meaning
DefinitionCache:Provider InMemory InMemory or Redis
DefinitionCache:RedisConnectionString empty Address of the Redis, for example redis:6379,password=…
DefinitionCache:RedisKeyPrefix nexxcite:defs: Prefix of all keys nexxcite writes to Redis
DefinitionCache:TimeToLiveSeconds 1800 How long an unused cache entry is kept
DefinitionCache:TimeToLiveJitterSeconds 10 Random offset added to the lifetime
DefinitionCache:Disabled false Switches the cache off. For diagnosis only – nexxcite is not usable like this.
Messaging:Provider None None or Redis. (Nats is not available; nexxcite does not start with it.)
Messaging:ConnectionString empty Address of the Redis for the message bus
Messaging:SubjectPrefix nexxcite Servers with the same prefix see each other's messages. Use a different prefix per installation that shares a Redis.

A single server needs none of this. For several servers, see Running several servers.

Execution history

nexxcite records every run of background processing (background actions, scheduled actions, mailbox listener rounds that handled mails) and shows it under Monitoring → Background Processes. See Monitoring.

Setting Default Meaning
ExecutionHistory:Enabled true Records the history. Off, nothing new is recorded; the health of the servers is still shown.
ExecutionHistory:LogCaptureMode OnFailure Whether the log of a run is stored: Never, OnFailure (failed runs and runs with warnings) or Always. Scheduled actions, rules, mailbox listeners and actions can override it.
ExecutionHistory:MaxLogEntries 2000 Lines of the log kept per run
ExecutionHistory:LogCaptureMinLevel Debug Lowest level of the captured log
ExecutionHistory:MaxProtocolNodes 2000 Size limit of the stored protocol of a run
ExecutionHistory:HeartbeatIntervalSeconds 15 Interval in which every server reports its state
ExecutionHistory:HousekeepingIntervalMinutes 5 Interval of the clean-up (failed servers, retention)
ExecutionHistory:JobQueueProbeIntervalMinutes 5 Interval of a small test job that checks whether the job queue of a server executes jobs. 0 switches it off.
ExecutionHistory:ServerLostAfterMinutes 10 After this time without a sign of life, a server is considered lost
ExecutionHistory:ServerDisplayHours 6 Hours a stopped or lost server is still shown
ExecutionHistory:ServerRetentionDays 2 Days after which a stopped or lost server is removed
ExecutionHistory:MetricsSnapshotIntervalMinutes 5 Interval in which every server stores its figures for the history charts. 0 switches it off.
ExecutionHistory:MetricsRetentionDays 90 Days the figures for the history charts are kept

Always makes the history grow quickly. Use it for a limited time to analyse a problem.

How long runs and their logs are kept is not set here but in the global settings: one value for the installation, because every server cleans the same history.

Processes of event based workflow rules

The processes of event based workflow rules wait in the database and are continued by the servers with ApplicationServer:ProcessScheduledActions = true.

Setting Default Meaning
RuleProcesses:PollIntervalSeconds 10 How often a server looks for processes whose wait time has passed
RuleProcesses:PollBatchSize 100 How many due processes one look continues before the next one takes over
RuleProcesses:StaleClaimMinutes 10 After this time, a process a stopped server was continuing is taken over by another server
RuleProcesses:MaxAttempts 5 Attempts to continue a process whose step fails, before it ends with "Failed"
RuleProcesses:RetryDelayMinutes [1, 5, 15, 60] Minutes to wait before each attempt; the last value repeats
RuleProcesses:LoopLimit 100 Items a process may pass without a wait before it is stopped as a loop

How long finished processes are kept is set in the global settings, see also Event based workflow rules.

Licensing

The license itself is entered in the global settings. The timings around it are described in Licensing.

Further settings

Setting Default Meaning
LoginProtection:MaxAttemptsPerWindow 20 Sign-in attempts one caller (one address) may make within the window, regardless of the account. See Sign-in and sessions.
LoginProtection:WindowInSeconds 60 Length of that window
ApiAuthentication:SigningKey empty Key the access tokens of the REST API are signed with, at least 32 characters. Empty switches the REST API sign-in off. Must be the same on every server. See API access and credentials.
ApiAuthentication:Issuer nexxcite Issuer written into the access tokens
ApiAuthentication:Audience nexxcite-api Audience written into the access tokens
ApiAuthentication:AccessTokenLifetimeInSeconds 3600 Lifetime of an access token
ApiDocumentation:Enabled true Serves the description (OpenAPI) and the interactive documentation of the REST API. Both are reachable without sign-in. See REST API.
ApiDocumentation:UiRoute api/v1/docs Address of the interactive documentation
ApiDocumentation:DocumentRoute api/{documentName}/openapi.json Address of the OpenAPI document
ActionRuntime:UIInteractionTimeoutSeconds 120 How long a step of an action waits for the user interface to report that, for example, a form was opened. Steps that wait for the user (prompts, popups with buttons) are not affected; a popup without buttons is – see Show Popup.
ActionRuntime:MaxRecursionDepth 5 How often the same action may be nested within its own run before it ends with an error
ActionRuntime:MaxActionCallDepth 25 How many actions one chain of calls may contain at all
BusinessRuleRuntime:MaxFieldChangeDepth 50 How many field changes may be nested within one another – a value that starts a rule, whose value starts the next rule and so on. 0 switches the limit off.
BusinessRuleRuntime:MaxRepeatedFieldChanges 5 How often the same rule may set the same field of the same record within the changes it started itself. 0 switches the limit off.

The limits of ActionRuntime protect against endless loops – for example an action that saves a record, which triggers a rule that starts the same action again. A single action can raise them in its own settings. The limits of BusinessRuleRuntime do the same for business rules that keep setting each other's fields; a change beyond them is not made and is written to the application log (see Business rules, section 7).


6. Limitations

  • The database must be Microsoft SQL Server. Other databases are not supported.
  • nexxcite stores images and files only in Azure Blob Storage or an S3-compatible storage, not on the file system of the server.
  • Changes to the configuration of the application are read when the server starts. Apart from the log levels, they take effect only after a restart. Settings made in the Admin Studio take effect without a restart.
  • There is no separate tool to roll back a schema migration. Restore the database backup if you have to return to a previous version.

7. Frequently asked questions

Where do I find the password of the default administrator? In the log of the first start: INFO: Default user created with password: "…". The line appears only when the user is created.

Do I have to create the tables myself? No. Only the empty database and a login that may create tables. nexxcite creates and updates the tables at every start.

All users are signed out after every restart. Why? DataProtection:KeyRingPath is not set, or the directory is not kept across restarts (for example a directory inside the container). Point it at a persistent volume.

The browser reports "too many redirects" behind our proxy. Most likely the proxy terminates HTTPS, but nexxcite does not trust its forwarded headers. Configure the section ForwardedHeaders.

Do changes to appsettings.json take effect while nexxcite runs? No, apart from the log levels. Restart the server after changing the configuration.