docs(docker)+docs(docker-env2)+infra: close P8-7 + P8-10 — LDAP doc drift + env2 gRPC port/teardown parity

P8-7: docker/README.md and docker-env2/README.md still listed the retired
scadabridge-ldap container. Verified against the running config
(central-node-*/appsettings.Central.json): both rigs actually bind to the
local redundant GLAuth pair (zb-ldap-primary :3893 + zb-ldap-backup :3894 on
host.docker.internal, source of truth scadaproj/infra/glauth-redundant), not
the shared 10.100.0.35 GLAuth the infra/docker-compose.yml retirement comment
claimed — that binding is itself stale, its serviceaccount password having
been rotated away by SEC-36. Corrected all three docs to name the actual
config each rig uses.

P8-10: docker-env2 mapped no host port for the central gRPC control plane
(docker/ maps 9013/9014->8083); added 9113/9114->8083 on both env2 centrals,
matching the free 91XX slots, plus the README port table. teardown.sh's
"preserved in node directories" data note predates the named-volume
migration; rewrote it honestly and added an explicit `docker volume rm`
recipe scoped to the env2 volume prefix, clearly labeled destructive,
mirroring docker/teardown.sh's existing pattern.

Gate: bash docker-env2/deploy.sh from this worktree — both centrals + both
site-x nodes recreated and came up with the new 9113/9114 ports open. The
simultaneous force-recreate split both pairs into independent 1-node
clusters (expected: BootstrapGuard is default-OFF on docker-env2, per
CLAUDE.md); a single restart of the b-side of each pair joined it to its
already-formed peer and both pairs converged (central: memberCount=2,
leader=central-a; site-x: node-b Welcome + singleton Younger). docker/ (the
primary rig) was not touched.
This commit is contained in:
Joseph Doherty
2026-08-19 16:17:49 -04:00
parent 428b8db024
commit 3bf1537ea0
5 changed files with 49 additions and 13 deletions
+21 -5
View File
@@ -41,8 +41,8 @@ Env2 host ports are the primary's ports + 100. Both stacks can run simultaneousl
| Node | Container Name | Host Web | Host Akka | Host gRPC | Internal | | Node | Container Name | Host Web | Host Akka | Host gRPC | Internal |
|------|----------------|----------|-----------|-----------|----------| |------|----------------|----------|-----------|-----------|----------|
| Traefik LB | `scadabridge-env2-traefik` | 9100 | — | — | 80 (proxy), 8080 (dashboard host:8181) | | Traefik LB | `scadabridge-env2-traefik` | 9100 | — | — | 80 (proxy), 8080 (dashboard host:8181) |
| Central A | `scadabridge-env2-central-a` | 9101 | 9111 | — | 5000 (web), 8081 (Akka) | | Central A | `scadabridge-env2-central-a` | 9101 | 9111 | 9113 | 5000 (web), 8081 (Akka), 8083 (gRPC) |
| Central B | `scadabridge-env2-central-b` | 9102 | 9112 | — | 5000 (web), 8081 (Akka) | | Central B | `scadabridge-env2-central-b` | 9102 | 9112 | 9114 | 5000 (web), 8081 (Akka), 8083 (gRPC) |
| Site-X A | `scadabridge-env2-site-x-a` | — | 9121 | 9123 | 8082 (Akka), 8083 (gRPC) | | Site-X A | `scadabridge-env2-site-x-a` | — | 9121 | 9123 | 8082 (Akka), 8083 (gRPC) |
| Site-X B | `scadabridge-env2-site-x-b` | — | 9122 | 9124 | 8082 (Akka), 8083 (gRPC) | | Site-X B | `scadabridge-env2-site-x-b` | — | 9122 | 9124 | 8082 (Akka), 8083 (gRPC) |
@@ -53,11 +53,17 @@ Env2 attaches to the existing `scadabridge-net` Docker bridge network and reuses
| Service | Container | What env2 uses it for | | Service | Container | What env2 uses it for |
|---------|-----------|-----------------------| |---------|-----------|-----------------------|
| MS SQL | `scadabridge-mssql` | Env2-specific databases `ScadaBridgeConfig2` / `ScadaBridgeMachineData2` | | MS SQL | `scadabridge-mssql` | Env2-specific databases `ScadaBridgeConfig2` / `ScadaBridgeMachineData2` |
| LDAP | `scadabridge-ldap` | Authentication (same test users) |
| SMTP | `scadabridge-smtp` | Notification capture in Mailpit (env2 emails distinguishable by `FromAddress`) | | SMTP | `scadabridge-smtp` | Notification capture in Mailpit (env2 emails distinguishable by `FromAddress`) |
| OPC UA | `scadabridge-opcua` | Simulated tags for site-x data connections | | OPC UA | `scadabridge-opcua` | Simulated tags for site-x data connections |
| REST API | `scadabridge-restapi` | External REST API testing | | REST API | `scadabridge-restapi` | External REST API testing |
LDAP is **not** one of the reused `infra/` containers (that stack's `ldap` service is
retired/commented out). Env2's central nodes bind to the same local redundant GLAuth pair
as `docker/` — `zb-ldap-primary` on `host.docker.internal:3893` with `zb-ldap-backup` on
`host.docker.internal:3894` as `FallbackServers` (source of truth:
`scadaproj/infra/glauth-redundant`); same test users, same bind credentials as the primary
stack.
## Commands ## Commands
### First-Time Setup ### First-Time Setup
@@ -108,7 +114,16 @@ Both UIs are now reachable:
bash docker-env2/teardown.sh bash docker-env2/teardown.sh
``` ```
Containers stop, volumes (data + logs) preserved. To also drop the env2 databases: Containers stop; node data lives in named Docker volumes (`scadabridge-env2-*-data`) and
logs in node directories, both left in place. To also remove the persistent data:
```bash
# Destructive: deletes all env2 SQLite data (site config cache, S&F buffers, LocalDb).
docker volume rm $(docker volume ls -q --filter name=scadabridge-env2-)
rm -rf docker-env2/*/logs
```
To also drop the env2 databases:
```bash ```bash
docker exec scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \ docker exec scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
@@ -134,7 +149,8 @@ docker logs -f scadabridge-env2-central-a
## Test Users ## Test Users
Same as primary (env2 shares LDAP). See `infra/glauth/config.toml` and primary `docker/README.md`. Same as primary (env2 shares the local redundant GLAuth pair, `scadaproj/infra/glauth-redundant`).
See "Shared Infrastructure" above and primary `docker/README.md`.
## Transport Testing Workflow ## Transport Testing Workflow
+2
View File
@@ -57,6 +57,7 @@ services:
ports: ports:
- "9101:5000" # Web UI + Inbound API - "9101:5000" # Web UI + Inbound API
- "9111:8081" # Akka remoting - "9111:8081" # Akka remoting
- "9113:8083" # gRPC control plane (CentralControlService) — mirrors docker/'s 9013
volumes: volumes:
- ./central-node-a/appsettings.Central.json:/app/appsettings.Central.json:ro - ./central-node-a/appsettings.Central.json:/app/appsettings.Central.json:ro
- central-node-a-data:/app/data - central-node-a-data:/app/data
@@ -113,6 +114,7 @@ services:
ports: ports:
- "9102:5000" # Web UI + Inbound API - "9102:5000" # Web UI + Inbound API
- "9112:8081" # Akka remoting - "9112:8081" # Akka remoting
- "9114:8083" # gRPC control plane (CentralControlService) — mirrors docker/'s 9014
volumes: volumes:
- ./central-node-b/appsettings.Central.json:/app/appsettings.Central.json:ro - ./central-node-b/appsettings.Central.json:/app/appsettings.Central.json:ro
- central-node-b-data:/app/data - central-node-b-data:/app/data
+5 -1
View File
@@ -10,7 +10,11 @@ docker compose -f "$SCRIPT_DIR/docker-compose.yml" down
echo "" echo ""
echo "Teardown complete." echo "Teardown complete."
echo "Site data (SQLite DBs) and logs are preserved in node directories." echo "Node data (SQLite DBs) is preserved in named docker volumes; logs in node directories."
echo ""
echo "To also remove persistent data:"
echo " docker volume rm \$(docker volume ls -q --filter name=scadabridge-env2-)"
echo " rm -rf $SCRIPT_DIR/*/logs"
echo "" echo ""
echo "Env2 databases (ScadaBridgeConfig2 / ScadaBridgeMachineData2) remain on" echo "Env2 databases (ScadaBridgeConfig2 / ScadaBridgeMachineData2) remain on"
echo "the shared scadabridge-mssql. To drop them:" echo "the shared scadabridge-mssql. To drop them:"
+11 -2
View File
@@ -71,11 +71,18 @@ Port block pattern: `90X1`/`90X2` (Akka), `90X3`/`90X4` (gRPC) where X = 0 (cent
| Service | Container Name | Host Port | Purpose | | Service | Container Name | Host Port | Purpose |
|---------|---------------|-----------|---------| |---------|---------------|-----------|---------|
| MS SQL 2022 | `scadabridge-mssql` | 1433 | Configuration and machine data databases | | MS SQL 2022 | `scadabridge-mssql` | 1433 | Configuration and machine data databases |
| LDAP (GLAuth) | `scadabridge-ldap` | 3893 | Authentication with test users |
| SMTP (Mailpit) | `scadabridge-smtp` | 1025 / 8025 | Email capture (SMTP / web UI) | | SMTP (Mailpit) | `scadabridge-smtp` | 1025 / 8025 | Email capture (SMTP / web UI) |
| OPC UA | `scadabridge-opcua` | 50000 / 8080 | Simulated OPC UA server (protocol / web UI) | | OPC UA | `scadabridge-opcua` | 50000 / 8080 | Simulated OPC UA server (protocol / web UI) |
| REST API | `scadabridge-restapi` | 5200 | External REST API for integration testing | | REST API | `scadabridge-restapi` | 5200 | External REST API for integration testing |
`infra/docker-compose.yml` no longer runs an LDAP container (its `ldap` service is commented
out, kept only for rollback). The central nodes bind to the local redundant GLAuth pair
instead — `zb-ldap-primary` on `host.docker.internal:3893` with `zb-ldap-backup` on
`host.docker.internal:3894` as `FallbackServers` (source of truth:
`scadaproj/infra/glauth-redundant`; see each central node's `appsettings.Central.json`). This
replaces the previously-used shared dev GLAuth at `10.100.0.35:3893` — its serviceaccount
password was rotated away (SEC-36) and is no longer valid for this rig.
All containers communicate over the shared `scadabridge-net` Docker bridge network using container names as hostnames. All containers communicate over the shared `scadabridge-net` Docker bridge network using container names as hostnames.
## Directory Structure ## Directory Structure
@@ -152,7 +159,9 @@ If you add a site to the rig, add its key in both places or its streams will fai
Start infrastructure services first, then build and deploy the application: Start infrastructure services first, then build and deploy the application:
```bash ```bash
# 1. Start test infrastructure (MS SQL, LDAP, SMTP, OPC UA) # 1. Start test infrastructure (MS SQL, SMTP, OPC UA — LDAP is the local
# redundant GLAuth pair on the Docker host, not started here; see
# "Infrastructure Services" above)
cd infra && docker compose up -d && cd .. cd infra && docker compose up -d && cd ..
# 2. Build and deploy all 8 ScadaBridge nodes # 2. Build and deploy all 8 ScadaBridge nodes
+10 -5
View File
@@ -41,11 +41,16 @@ services:
- scadabridge-net - scadabridge-net
restart: unless-stopped restart: unless-stopped
# RETIRED 2026-06-04: superseded by the shared dev GLAuth on 10.100.0.35:3893 # RETIRED 2026-06-04: originally superseded by the shared dev GLAuth on
# (scadaproj/infra/glauth/). The central nodes now bind there (see # 10.100.0.35:3893 (scadaproj/infra/glauth/). That binding is itself now stale —
# docker/ + docker-env2 central-node appsettings: Ldap:Server=10.100.0.35). # the shared GLAuth's serviceaccount password was rotated (SEC-36) and is no
# Kept here, commented, for rollback — uncomment + `docker compose up -d ldap` # longer valid, so both docker/ and docker-env2 central nodes now bind to the
# and revert the central-node Server back to "scadabridge-ldap". # local redundant GLAuth pair instead: zb-ldap-primary on
# host.docker.internal:3893 with zb-ldap-backup on host.docker.internal:3894 as
# FallbackServers (source of truth: scadaproj/infra/glauth-redundant; see each
# central node's appsettings.Central.json). Kept here, commented, for rollback —
# uncomment + `docker compose up -d ldap` and point the central-node Server back
# at "scadabridge-ldap".
# ldap: # ldap:
# image: glauth/glauth:latest # image: glauth/glauth:latest
# container_name: scadabridge-ldap # container_name: scadabridge-ldap