54f111e8b1
- 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
85 lines
3.9 KiB
Markdown
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.
|