Skip to main content
Version: 0.1

Configuration

This page lists every key the gateway reads, how compose.yaml sets them, and what lives in the data directory. It is for the person who installs and operates the gateway.

How configuration is read​

The gateway is an ASP.NET Core application, so keys follow its conventions: an environment variable, with __ standing for the : of a section (EventBackbone__Url is EventBackbone:Url). On start the gateway also reads .env.local and then .env from its working directory; a value already in the process environment wins and is never overwritten. Lines starting with # are ignored and surrounding double quotes are stripped.

In Docker, compose.yaml passes a few environment variables into the container and the image's Dockerfile sets the rest as defaults. Everything is read once at start, so a change to any key below takes effect at the next restart. Nothing re-reads configuration while the gateway runs.

Gateway keys​

KeyDefaultPurpose
GATEWAY_PORT3000 (image: 8080)HTTP port. The gateway listens on http://0.0.0.0:<port>.
AUTH_BASE_URLhttp://localhost:3000Public address. An https:// value makes the session cookie Secure; otherwise it follows the request.
AUTH_TRUSTED_ORIGINS(empty)Comma-separated origins allowed to change anything or to open /sync. Empty means none, so signed-in writes get 403.
DATA_DIR<content-root>/data (image: /data)SQLite database, Data Protection keys and internal data.
DATABASE_PATH<DATA_DIR>/scadex.dbThe SQLite file. Set it only to put the database somewhere other than the data directory.

The session cookie is named scadex.session, is HttpOnly and SameSite=Lax, and expires 7 days after sign-in without sliding. These are not configurable.

Event backbone​

Section EventBackbone. NATS JetStream is the internal event timeline for tag values and metadata; the appliance runs it inside the container.

KeyDefaultPurpose
EventBackbone__Urlnats://127.0.0.1:4222The NATS endpoint.
EventBackbone__ValueRetention7.00:00:00How long tag values stay in the backbone: the window tag.replay and replays answer from without a historian.
EventBackbone__MetadataRetention30.00:00:00How long metadata events stay replayable.
EventBackbone__CheckpointInterval01:00:00How often every tag's last value is published as a checkpoint for replays to start from. A whole fraction of an hour. Checkpoints are kept for the value retention plus two hours.
EventBackbone__BatchMaxCount256Most values in one published batch.
EventBackbone__BatchMaxLatencyMs25Longest a batch waits before it is published.

Durations are .NET TimeSpan strings: d.hh:mm:ss.

Modules​

Section Modules. See Modules for what each path holds.

KeyDefaultPurpose
Modules__Path<app>/modules (image: /modules)The controlled module directory. Each subfolder is one installed module; compose.yaml mounts ./.local/modules here.
Modules__Disabled(empty)Comma-separated ids of installed modules not to load. They show as disabled with lockedByConfiguration, and an operator cannot start them. SCADEX_DISABLED_MODULES in compose.
Modules__DataPath<DATA_DIR>/modulesEach module's private data directory, <DataPath>/<module id>/.
Modules__LicensePath<DATA_DIR>/licensesWhere signed *.license grants are read from.
Modules__SettingsPath<DATA_DIR>/modules.jsonWhere the gateway remembers which modules an operator stopped and each module's log level. Empty keeps both in memory only.
Modules__LogPath<DATA_DIR>/logs/modulesOne folder of rotating log files per module. Empty keeps logs in memory only.
Modules__LogFileBytes2097152 (2 MB)Size at which a module's log file rotates. Five files are kept.
Modules__StopTimeoutSeconds30How long a module gets to stop before the gateway moves on without it.
Modules__StartTimeoutSeconds120How long a module gets to start before the gateway gives up on it.

Alarms​

KeyDefaultPurpose
Alarms__EventRetention365.00:00:00How long alarm lifecycle events stay in the history table. A replay asking further back shows no alarms.

Image defaults​

deploy/Dockerfile sets these in the appliance image:

KeyValue
ASPNETCORE_ENVIRONMENTProduction
DOTNET_SYSTEM_GLOBALIZATION_INVARIANTfalse (ICU is installed for the SQL Server driver)
ASPNETCORE_HTTP_PORTSempty, so GATEWAY_PORT decides
GATEWAY_PORT8080
DATA_DIR/data
EventBackbone__Urlnats://127.0.0.1:4222
Modules__Path/modules

The bundled NATS server reads /etc/scadex/nats-server.conf: it listens on 127.0.0.1:4222 only, stores JetStream under /data/nats/jetstream, and exposes its monitoring endpoint on 127.0.0.1:8222, inside the container only.

Compose variables​

compose.yaml and compose.dev.yaml read these from .env (copy .env.example). Every value is optional.

VariableDefaultMaps to
SCADEX_BIND0.0.0.0The host interface the port is published on. 127.0.0.1 keeps the gateway on the loopback, for a reverse proxy or for creating the first account.
SCADEX_PORT8080The host port, mapped to 8080 in the container.
SCADEX_TAGdevThe image tag of registry.gitlab.com/scadex.io/platform/gateway.
SCADEX_MODULESallBuild argument: the module folders built into the image (all, a list such as mqtt opcua, or empty for none).
SCADEX_DISABLED_MODULES(empty)Modules__Disabled.
AUTH_BASE_URLhttp://localhost:8080AUTH_BASE_URL.
AUTH_TRUSTED_ORIGINShttp://localhost:8080AUTH_TRUSTED_ORIGINS.
SCADEX_DEV_DASHBOARD_PORT5173compose.dev.yaml only: host port of the Vite dev server.
SCADEX_DEV_GATEWAY_PORT3000compose.dev.yaml only: host port of the gateway.
COMPOSE_FILELayer another compose file over compose.yaml, as the repository does for its Traefik labels.

compose.dev.yaml sets GATEWAY_PORT=3000, AUTH_BASE_URL=http://localhost:3000 and AUTH_TRUSTED_ORIGINS=http://localhost:5173 on its gateway, so the dev dashboard's origin is trusted.

Other settings live in the dashboard​

Some things that look like configuration are stored in the database and changed from the dashboard, not from the environment: the project directory (Gateway > System > Project), the historian's retention (retentionDays, 90 by default, on the historian's settings), module log levels, which modules are stopped, database connections, identity providers and API keys. They survive a restart because they are in the data directory.

The data directory​

DATA_DIR (/data in the container, the scadex-data volume) is the gateway's whole state. What is in it:

PathHolds
scadex.db (with -wal and -shm)Configuration and the current-state projection: users, sessions, tags, types, screens, alarms and their history, module state, audit rows. SQLite in WAL mode.
keys/ASP.NET Data Protection keys. Module state (driver passwords included) is encrypted with them; without this folder the stored state cannot be read. Back it up with the database.
nats/jetstream/The JetStream store: the recent value and metadata timeline and the checkpoints.
modules.jsonWhich modules an operator stopped, and each module's log level. Delete it to forget both.
modules/<id>/Each module's private data directory, such as modules/io.scadex.historian/history.db and modules/io.scadex.cron/runs.db.
logs/modules/<id>/module.logEach module's rotating log files, 2 MB each, newest five kept.
licenses/Signed *.license grants for paid modules. Copy a grant here and restart.
backups/Database backups made from Backup & restore, and the previous database kept when a staged restore is applied at start.
certificates/, historian/, internal/Created by the container's entrypoint for the OPC UA stack, the historian and internal use.

A restore staged from the dashboard is applied at the next start, before anything opens the database, and the previous file is kept under backups/. See Backup and restore.

warning

keys/ is stored unencrypted beside the database. Encryption at rest protects a leaked scadex.db, not a copied volume. Treat the whole data directory as secret, and keep keys/ with every backup of the database.

What needs a restart​

ChangeTakes effect
Any environment key above (GATEWAY_PORT, AUTH_*, DATA_DIR, EventBackbone__*, Modules__*, Alarms__*)At the next restart.
A module dropped into /modules on diskAt the next restart, or when the module is restarted from Modules
A module installed, started, stopped or removed from Modules or the APIAt once
A module's log levelAt once, and remembered in modules.json
A licence file copied to licenses/At the next restart; expiry is also checked only when the module loads
Historian retention, project directory, users, connections, screens, alarmsAt once
RolesOn the user's next request; an open /sync socket closes within 30 seconds if its session no longer holds a known role