Files
scadaproj/ZB.MOM.WW.Overview/docker/README.md
T
Joseph Doherty 54f111e8b1 docs(btdb): register BTDB Manager in the Overview docker registry; record the local rig
- ZB.MOM.WW.Overview appsettings.Docker.json: application "BTDB Manager", instance manager at
  http://zb-btdb-manager:9877 (HasActiveRole false); docker/README.md fleet row.
- CLAUDE.md BTDB row and sister-project-history/btdb.md §7/§9: docker/ layout, the
  dacpac + SQL CLR side-project build, scadabridge-mssql as the BT host.

Claude-Session: https://claude.ai/code/session_015dYqtaTxgf6NK2KuwriMSg
2026-09-04 06:14:22 -04:00

85 lines
3.9 KiB
Markdown

# `docker/` — containerised overview dashboard
Runtime-only image, the HistorianGateway pattern: publish on the host (which has the Gitea feed
credentials), copy the output into `mcr.microsoft.com/dotnet/aspnet:10.0`. Docker never restores.
```bash
# from ZB.MOM.WW.Overview/
dotnet publish src/ZB.MOM.WW.Overview/ZB.MOM.WW.Overview.csproj \
-c Release -o docker/publish -p:UseAppHost=false
cd docker && docker compose up -d --build
open http://localhost:5320
```
`docker/publish/` is build output and is gitignored.
## Why the container, and not just `dotnet run`
The dev rigs publish only some node ports to the host:
| Fleet | Health endpoint | Reachable from the Mac host? |
|---|---|---|
| ScadaBridge central-a/b | container `:5000` | yes — `localhost:9001` / `:9002` |
| ScadaBridge site-\* (6) | container `:8084` | **no** — not published |
| OtOpcUa central-1/2 | container `:9000` | **no** — only Traefik `:9200`, load-balanced across the pair |
| OtOpcUa site-\* (4) | container `:8080` | **no** — not published |
| HistorianGateway | container `:5220` | yes — `localhost:5220` |
| BTDB Manager | container `:9877` | yes — `localhost:9877` |
| MxAccessGateway | windev `:5130` | yes, with the VPN up |
So a host-run dashboard can only see part of the fleet. This stack joins the three rig networks
(`otopcua-dev_default`, `scadabridge-net`, `zb-historiangw_default`, all declared `external`) and
addresses every node by container DNS name, which is how it sees all of them. BTDB Manager
(`~/Desktop/BTDB/docker`) sits on `scadabridge-net` too, because its BT database lives on
ScadaBridge's infra MSSQL container, so no fourth network is needed for it.
Ports above were established by probing the running rigs on 2026-07-24, **not** read off the
compose files — the two disagree. In particular OtOpcUa's site nodes serve health on `:8080`, not
the `:9000` their compose anchor implies, because their explicit Kestrel listeners for LocalDb sync
re-bind the primary HTTP port.
Start the rigs before this stack. The networks are `external`, so bringing the dashboard up or
down never disturbs a running rig.
## Registry shape
Bound from the `Overview` section; `appsettings.Docker.json` is the worked example.
```jsonc
"Overview": {
"PollIntervalSeconds": 10, // sweep cadence; per-app and per-instance overrides allowed
"TimeoutSeconds": 3, // per-request timeout
"StaleAfterSeconds": 45, // must exceed the poll interval, or every card reads Stale
"Applications": [
{
"Name": "ScadaBridge",
"ManagementLabel": "CentralUI", // label on each instance's management link
"Instances": [
{
"Name": "central-a",
"Group": "central", // one Akka cluster = one group; leader + split-brain
// detection are scoped to it. Omit for standalone apps.
"BaseUrl": "http://host:5000", // /health/ready and /health/active are probed under this
"ManagementUrl": "http://localhost:9001/", // followed by the OPERATOR'S browser, so it
// must be host-reachable, not container DNS
"HasActiveRole": true // false for single-instance gateways: no Active badge,
// and /health/active is never probed
}
]
}
]
}
```
`appsettings.json` ships the tuning defaults with an **empty** `Applications` list, so a deployment
that supplies no registry fails at startup naming the missing key rather than booting into an empty
dashboard.
## Configuration traps
- **Never set `ASPNETCORE_URLS` alongside `Kestrel__Endpoints__*`.** Declaring both puts Kestrel
into explicit-endpoints mode and one of them is silently discarded.
- No `env_file`, no secrets, no login. The dashboard reads anonymous health endpoints and holds no
credentials. That is a requirement of the design, not an omission.