Edge gateway
Install a plant-site edge gateway for store-and-forward telemetry when the hub is remote.
An edge gateway runs on a plant PC or industrial PC next to PLCs and MQTT brokers. It collects telemetry locally, buffers it on disk if the WAN is down, and dials outbound only to the DataHub hub (HTTPS + TLS NATS). The hub never opens inbound ports into the plant. Each gateway uses its own NATS user scoped to its plant’s telemetry subjects.
When to use it
| Use an edge gateway when… | Prefer central adapters when… |
|---|---|
| The hub is in another network / cloud | Devices are on the same LAN as the hub |
| WAN outages must not lose data | Lab / single-site demo |
| OT firewall allows outbound only | No plant PC available |
Prerequisites
- Docker on the plant box
- Hub stack running and reachable (API + NATS client port)
- NTP enabled on the plant box (
timedatectl set-ntp true) - Console user with permission to create gateways and assign devices
Console
The Gateways list shows fleet KPIs (online, config drift, queued outbox, disk warnings), status filters, and a pairing code until the box comes online. Open a gateway for health chips, assigned devices and programs, metrics, logs, revisions, and audit.
First-time labs can also create and pair a gateway in the setup wizard (/setup) after the simulator device — skip that step if you only need central adapters.
Install (plant box)
Production uses a prebuilt image (registry pull or air-gap docker load) — not a source build on the plant PC.
Primary — console deploy command
- In the console open Gateways → create a gateway → open its detail page.
- Click Deploy to edge. The Hub API URL is pre-filled from the address you opened the console with, falling back to the hub host's detected LAN IP — check that it is routable from the plant box (not
localhostorhost.docker.internal) and edit it if the hub is behind a reverse proxy. Then set target architecture (AMD64 / ARM64) and host ports (default health 8080, MQTT 1883). - Copy the generated
sudo sh -s <<'SH'command and run it on the plant Linux host (Docker required). The script writes.env.edge, embedsedge-compose.yml, starts the container, and waits for/healthz. - Fix any amber warnings before production — especially NATS host reachability and TLS CA when
NATS_TLSis enabled on the hub. - Wait until the gateway shows ONLINE (~15 s heartbeat), then assign devices.
Secondary — air-gap bundle (console)
- On the gateway detail page click Deploy to edge and choose Air-gap (offline bundle).
- Set Hub API URL, architecture, and edge release version (requires
deploy/releases/mounted on the hub asEDGE_RELEASE_DIR). - Click Download package — the zip includes the image tarball, pre-filled
.env.edge(pairing code),edge-compose.yml,install.bat,install.sh, andSHA256SUMS. - Copy the zip to the plant box (USB or file share), extract it.
- Windows: double-click
install.bat. Linux/macOS: double-clickinstall.shor run./install.sh. Wait for Health check OK before closing the window.
Tertiary — manual release bundle
On air-gapped sites you can also use the release bundle from release-edge.sh:
mkdir -p /opt/datahub-edge && cd /opt/datahub-edge
cp env.edge.example .env.edge
# EDGE_IMAGE=registry.example.com/datahub-edge:1.0.0
# HUB_API_URL=https://your-hub.example.com/api
# PAIRING_CODE=A3K9F2
docker login registry.example.com # read-only pull account
docker compose -f edge-compose.yml --env-file .env.edge pull
docker compose -f edge-compose.yml --env-file .env.edge up -dOr run ./deploy/scripts/install-edge.sh /opt/datahub-edge from the release bundle.
Pairing code — set PAIRING_CODE in .env.edge, or write the code to /data/pairing-code on the edge volume and restart the container. After pair, the token is stored in /data/gateway-state.json.
Air-gap: gunzip -c datahub-edge-1.0.0.tar.gz | docker load then the same compose (image tag must match).
Dev from repo: npm run up:edge (build override on a developer machine only).
Persistent volume /data holds gateway-state.json (token) and outbox.sqlite (store-and-forward). Do not delete /data unless you intend to re-pair.
Two buffers: the plant outbox grows when NATS or the hub API is unreachable (publish fails). When only hub workers are down but NATS accepts publishes, the edge outbox stays near zero — data waits on the hub JetStream stream until telemetry-worker and rule-worker catch up. See Edge gateway troubleshooting.
Local health
The edge exposes localhost health (default host port 8080):
curl -s http://localhost:8080/healthz200 means paired and healthy; 503 means unpaired, hub unreachable, or outbox nearly full.
Test connection and scan
For devices assigned to a gateway, Test connection and Scan tags in the console are proxied to the edge over NATS. If the gateway is offline, the API returns immediately with gateway.offline (no long timeout).
MQTT push ingress (Faz 7)
For devices that publish to the gateway (instead of the gateway polling or subscribing):
- Create a device with adapter type MQTT push (edge broker).
- Copy the ingest token when shown (once at create or after rotate).
- Assign the device to the gateway — the edge opens MQTT port 1883 on the plant LAN (
EDGE_MQTT_HOST_PORTin compose). - Configure your PLC or sensor to publish:
- Broker: edge box IP, port 1883
- Username: ingest token
- Topic:
telemetry - Payload: JSON object — keys must match tag codes on the device (e.g.
{ "temp": 23.5 })
Publish policy (default on-change): new devices default to On change only with a 60s max interval heartbeat sample (latest values stay fresh without sending every poll). Use All samples only when you need every reading (e.g. energy counters). On change (full device snapshot) publishes every tag on the device when any one tag crosses deadband or max interval — useful for a consistent WAN-side view (Sparkplug-like birth/change bundles). On large tag counts (thousands+), All samples at 1 Hz can exceed the gateway drain ceiling and fill the outbox — the console warns when estimated production exceeds maxPerSec. Tune Outbox & drain policy on the gateway overview (recommended drain max 20,000 dp/s). Bad-quality samples and edge program outputs drain before routine telemetry when the outbox is backlogged.
Restrict port 1883 to the OT LAN — do not expose it to the internet.
Console: gateway list
The Gateways list shows four fleet KPI cards: online gateways, config drift, total outbox depth, and health warnings (low disk, clock skew, outdated edge version). Counts refresh every few seconds from the same list API that powers the table — no extra request.
Console: gateway detail
Open Gateways → a gateway for status, assigned devices, edge programs, metric charts, and the Logs tab (batched edge process logs; tokens/passwords are masked before shipping). Program runtime logs stay on the program detail page.
When the gateway has MQTT push devices assigned, the Metrics tab also charts accepted messages per sample interval and connected MQTT clients, plus a cumulative accept / reject / unknown-key summary since the edge process started.
Health chips warn when disk is low, the outbox is deep, clock skew exceeds ~30 s, or config revision has drifted. Sustained thresholds also create Alarms records (recover automatically when the condition clears) — same disk (<500 MiB free), outbox (>10k rows), skew, and drift rules as the console badges.
Token rotate / revoke / pause
| Action | What to do on the plant box |
|---|---|
| Rotate token | Paste the new token into .env.edge as GATEWAY_TOKEN=…, clear PAIRING_CODE, recreate the container |
| Pause | No box action — hub stops collectors via manifest; heartbeat and outbox drain continue |
| Resume | No box action — edge pulls manifest and restarts adapters automatically |
| Revoke | Edge stops adapters; use Re-pair in the console for a new pairing code (record and plant are kept; device assignments are not restored) |
Backup
Back up /data daily (token + undrained outbox). Example:
tar czf /backup/datahub-edge-$(date +%Y%m%d).tar.gz -C /opt/datahub-edge data/