The Gateway
"The gateway" is the QUBIQ installation as a whole: the supervisor process, the services it manages, and the message bus they share. It is the unit you install, start, stop, back up and upgrade.
The supervisor
Running the binary with no subcommand starts the supervisor. In order, it:
- Provisions
.envif absent, generatingJWT_SECRETand a 64-hexENCRYPTION_KEYfrom a cryptographic RNG. - Starts the embedded message bus, bound to
127.0.0.1on a random free port, and exports the resulting URL into the environment children inherit. - Migrates the configuration database — once, single-threaded, before any child exists, so services never race on schema.
- Creates one hard link per service beside the binary, named
QBQ-<Service>, and spawns each. - Supervises: watches heartbeats, restarts a service that exits unexpectedly, and reports status to the interface.
If hard links are not possible (a cross-volume or non-NTFS install), the supervisor falls back to
spawning qubiq <subcommand> — still a separate process, just displayed under the generic name.
So that QBQ-OpcWorker shows up in Task Manager, ps and your monitoring agent under its own name.
It is the same file on disk; only the invocation name differs.
Secrets are strict
There are no insecure defaults and no fallbacks:
| Secret | Purpose | Rule |
|---|---|---|
JWT_SECRET | Protects Platform sign-ins | Required. Absent or malformed ⇒ hard startup failure. |
ENCRYPTION_KEY | 64 hex chars; derives the key protecting the configuration database and connection secrets | Required. Absent or malformed ⇒ hard startup failure. |
LIVE_JWT_SECRET | Protects LiveView sign-ins | Derived from JWT_SECRET if unset; set it explicitly to reset operator sign-ins on their own. |
Startup fails loudly rather than starting insecurely. Moving a data directory to another machine
requires bringing that machine's ENCRYPTION_KEY with it.
Service catalog
| Service | Process | Port | Restart impact |
|---|---|---|---|
| CoreServer | QBQ-CoreServer | 8182 | UI and API unavailable while down; devices keep being polled. |
| RealtimeGateway | QBQ-RealtimeGateway | 8183 | Screens stop updating; values are not lost. |
| Engine | QBQ-Engine | — | Pipeline execution pauses. |
| Bridge | QBQ-Bridge | — | Protocol adapters and pipeline runtime restart; subscriptions re-establish. |
| Historian | QBQ-Historian | — | Ingestion buffers; nothing is lost while store-and-forward holds. |
| Alarm | QBQ-Alarm | — | Evaluation pauses; state is restored from storage on restart. |
| Audit | QBQ-Audit | — | Events stay buffered on the durable stream until it returns. |
| ConnMonitor | QBQ-ConnMonitor | — | Health indicators go stale; data flow is unaffected. |
| OpcWorker | QBQ-OpcWorker | — | OPC-UA subscriptions re-establish on restart. |
| MqttWorker | QBQ-MqttWorker | — | Broker sessions reconnect; retained/Sparkplug birth messages resynchronise. |
| ModbusWorker | QBQ-ModbusWorker | — | Polling resumes. |
| SnmpWorker | QBQ-SnmpWorker | 162/udp (opt-in) | Polling resumes; traps sent while down are lost (SNMP is fire-and-forget). |
| TcpUdpWorker | QBQ-TcpUdpWorker | — | Sockets reconnect. |
| DbWorker | QBQ-DbWorker | — | Queued SQL/Mongo work retries. |
| RestGateway | QBQ-RestGateway | 8090 | Published REST endpoints return errors while down. |
| ScriptGateway | QBQ-ScriptGateway | 8091 | Script execution fails fast. |
| ImportService | QBQ-ImportService | — | Bulk imports queue. |
| AI | QBQ-AI | — | The assistant is unavailable. |
Monitoring and controlling services
Settings → System Services lists every service with its state and heartbeat.
| Action | Permission |
|---|---|
| View the service list | Access settings |
| Start / stop / restart a service | Manage services |
Stopping a service through the interface tells the supervisor not to restart it, so it stays down until you start it again. That is the safe way to take a protocol worker out of service for maintenance — killing the process merely triggers a restart.
Health and diagnostics
| Auth | Returns |
|---|---|
| none | Liveness — is the gateway process answering? |
| none | Aggregate service health, suitable for a load balancer. |
| View the status panel | Resource and throughput counters. |
| Access settings | Telemetry pipeline and WebSocket fan-out health. |
| View the status panel | Host CPU, memory, disk. |
| View the status panel | Per-connection state. |
| authenticated | What happened during boot — the first thing to read after a failed start. |
The message bus
Services communicate over an embedded publish/subscribe bus with a persistent stream layer. It provides:
- Subject-based messaging — telemetry, node status, connection state, alarm events, audit events.
- Durable streams — the store-and-forward buffers and the audit event stream survive a service restart.
- Key-value buckets — live tag values, internal (memory) tag values, alarm runtime state.
- Request/reply — e.g. a protocol worker asking CoreServer to resolve and decrypt a connection.
Because the bus is bound to loopback with a random port, there is nothing to expose, authenticate or firewall. It also means every service must run on the same host.
Wire contract
Telemetry travels as a compact binary message rather than JSON, which is what keeps a busy screen cheap to feed. Three kinds cross the bus: a tag value with its quality and timestamps, a pipeline node's status, and the pipeline payload envelope.
Web assets
In a production build the compiled frontend is embedded into the binary. There is no static file directory to deploy and no web server to configure; CoreServer serves the interface itself.
Ports summary
| Port | Bound by | Purpose |
|---|---|---|
| 8182 | CoreServer | HTTP API, web UI, WebSocket upgrade |
| 8183 | RealtimeGateway | Telemetry WebSocket |
| 8090 | RestGateway | Pipeline-defined REST ingress |
| 8091 | ScriptGateway | Script execution |
| 162/udp | SnmpWorker | Trap listener (opt-in) |
| random, loopback | Supervisor | Message bus — never exposed |
Override with PORT, REALTIME_PORT, REST_GATEWAY_PORT, SCRIPTING_GATEWAY_PORT.
→ Environment variables
Next
→ Projects