# docker-cluster-env2 Secondary local Docker deployment — a minimal ScadaBridge topology that runs **concurrently with** [`docker-cluster`](docker-cluster.md) so the Transport (#24) feature can be exercised end-to-end across two real environments (export a bundle from one, import into the other). - **Deployment ID:** `docker-cluster-env2` - **Transport.SourceEnvironment:** `docker-cluster-env2` - **Source directory:** [`docker-env2/`](../docker-env2/) - **Container-name prefix:** `scadabridge-env2-` - **Host-port range:** `91XX` (primary `90XX` + 100) ## Topology ``` ┌───────────────────┐ │ Traefik LB :9100 │ ◄── CLI / Browser │ Dashboard :8181 │ └────────┬──────────┘ │ routes to active node ┌──────────────────────┼──────────────────────────────┐ │ Env2 Central Cluster │ │ env2-central-a (UI :9101, Akka :9111) │ │ env2-central-b (UI :9102, Akka :9112) │ └───────────┬─────────────────────────────────────────┘ │ Akka.NET remoting + gRPC streaming ▼ Env2 Site-X (Env2 Site X) Akka 9121/9122 gRPC 9123/9124 ``` Same active/standby pattern as the primary, scaled down to a single site cluster to keep the footprint small. Built specifically for cross-environment Transport testing — not a general-purpose dev environment. ## Nodes | Node | Container Name | Host Web | Host Akka | Host gRPC | |------|----------------|----------|-----------|-----------| | Traefik LB | `scadabridge-env2-traefik` | 9100 | — | — | | Central A | `scadabridge-env2-central-a` | 9101 | 9111 | — | | Central B | `scadabridge-env2-central-b` | 9102 | 9112 | — | | Site-X A | `scadabridge-env2-site-x-a` | — | 9121 | 9123 | | Site-X B | `scadabridge-env2-site-x-b` | — | 9122 | 9124 | ## Sites | Site Identifier | Central UI Name | |-----------------|-----------------| | `site-x` | Env2 Site X | ## Infrastructure Dependencies Env2 reuses the primary's `infra/` containers via the shared `scadabridge-net` bridge network — there is no separate `infra/` stack to start. | Service | Shared Container | What env2 uses it for | |---------|------------------|-----------------------| | MS SQL | `scadabridge-mssql` | Env2 databases `ScadaBridgeConfig2` / `ScadaBridgeMachineData2` (separate DBs on the same instance) | | LDAP | `scadabridge-ldap` | Authentication (same test users) | | SMTP | `scadabridge-smtp` | Notification capture (env2 emails distinguishable by `FromAddress`) | | OPC UA | `scadabridge-opcua` | Simulated tags for `site-x` data connections | | REST API | `scadabridge-restapi` | External REST integration testing | ## Databases | Database | Owner | |----------|-------| | `ScadaBridgeConfig2` | Configuration Database (#17) — env2 instance | | `ScadaBridgeMachineData2` | Machine data — env2 instance | Created by `docker-env2/init-db.sh`, which `deploy.sh` runs automatically. ## Commands ```bash # Primary infra must already be up (creates scadabridge-net + MS SQL + LDAP + SMTP + OPC UA + REST) cd infra && docker compose up -d && cd .. # Build image (shared with primary), create env2 DBs, deploy env2 containers bash docker-env2/deploy.sh # First-time only: seed the env2 test site bash docker-env2/seed-sites.sh # View logs docker compose -f docker-env2/docker-compose.yml logs -f docker logs -f scadabridge-env2-central-a # Stop env2 (preserves SQLite + logs) bash docker-env2/teardown.sh # Also drop env2 databases docker exec scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \ -S localhost -U sa -P 'ScadaBridge_Dev1#' -C \ -Q "DROP DATABASE ScadaBridgeConfig2; DROP DATABASE ScadaBridgeMachineData2;" ``` ## CLI Access ```bash dotnet run --project src/ZB.MOM.WW.ScadaBridge.CLI -- \ --url http://localhost:9100 \ --username multi-role --password password \ template list ``` ## What's Different from `docker-cluster` - Single site (`site-x`) instead of three (`site-a`/`site-b`/`site-c`). - Host port range `91XX` instead of `90XX`. - Container names prefixed `scadabridge-env2-` instead of `scadabridge-`. - Databases `ScadaBridgeConfig2` / `ScadaBridgeMachineData2` on the **shared** `scadabridge-mssql`. - `Transport.SourceEnvironment = "docker-cluster-env2"` stamped into exported bundle manifests. - Distinct `Security.JwtSigningKey` so sessions cannot cross environments. ## Notes - Concurrent with [`docker-cluster`](docker-cluster.md) — both stacks share `scadabridge-net` and the `infra/` services. Disjoint host ports + DB names + container names allow them to run side-by-side. - Design rationale: [`docs/plans/2026-05-24-second-environment-design.md`](../docs/plans/2026-05-24-second-environment-design.md). - Transport golden-path verification: [`docs/plans/2026-05-24-second-environment-verification.md`](../docs/plans/2026-05-24-second-environment-verification.md). - Setup details, port table, and CLI examples in [`docker-env2/README.md`](../docker-env2/README.md).