# docker-cluster Primary local Docker deployment — the full ScadaLink reference topology used for day-to-day development and integration testing. Runs on the developer workstation under Docker / OrbStack. - **Deployment ID:** `docker-cluster` - **Transport.SourceEnvironment:** `docker-cluster` - **Source directory:** [`docker/`](../docker/) - **Container-name prefix:** `scadalink-` - **Host-port range:** `90XX` ## Topology ``` ┌───────────────────┐ │ Traefik LB :9000 │ ◄── CLI / Browser │ Dashboard :8180 │ └────────┬──────────┘ │ routes to active node ┌──────────────────────┼──────────────────────────────┐ │ Central Cluster │ │ central-node-a (UI :9001, Akka :9011) │ │ central-node-b (UI :9002, Akka :9012) │ └───────────┬─────────────────────────────────────────┘ │ Akka.NET remoting + gRPC streaming ├──────────────────┬──────────────────┐ ▼ ▼ ▼ Site-A (Test Plant A) Site-B (Test Plant B) Site-C (Test Plant C) Akka 9021/9022 Akka 9031/9032 Akka 9041/9042 gRPC 9023/9024 gRPC 9033/9034 gRPC 9043/9044 ``` Two-node active/standby everywhere. Central runs the Blazor UI, Template Engine, Deployment Manager, Notification Outbox, Site Call Audit, Audit Log, and Inbound API. Each site runs the Site Runtime, Data Connection Layer, Store-and-Forward, and Site Event Logging, with a per-node gRPC streaming server (port 8083) that central nodes subscribe to for real-time attribute/alarm streams. ## Nodes | Node | Container Name | Host Web | Host Akka | Host gRPC | |------|----------------|----------|-----------|-----------| | Traefik LB | `scadalink-traefik` | 9000 | — | — | | Central A | `scadalink-central-a` | 9001 | 9011 | — | | Central B | `scadalink-central-b` | 9002 | 9012 | — | | Site-A A | `scadalink-site-a-a` | — | 9021 | 9023 | | Site-A B | `scadalink-site-a-b` | — | 9022 | 9024 | | Site-B A | `scadalink-site-b-a` | — | 9031 | 9033 | | Site-B B | `scadalink-site-b-b` | — | 9032 | 9034 | | Site-C A | `scadalink-site-c-a` | — | 9041 | 9043 | | Site-C B | `scadalink-site-c-b` | — | 9042 | 9044 | Port pattern: `90X1`/`90X2` (Akka), `90X3`/`90X4` (gRPC), where X = 0 (central), 2 (site-a), 3 (site-b), 4 (site-c). ## Sites | Site Identifier | Central UI Name | |-----------------|-----------------| | `site-a` | Test Plant A | | `site-b` | Test Plant B | | `site-c` | Test Plant C | ## Infrastructure Dependencies All from `infra/docker-compose.yml`, attached via the shared `scadalink-net` bridge network: | Service | Container | Host Port | Purpose | |---------|-----------|-----------|---------| | MS SQL 2022 | `scadalink-mssql` | 1433 | `ScadaLinkConfig`, `ScadaLinkMachineData` | | LDAP (GLAuth) | `scadalink-ldap` | 3893 | Authentication | | SMTP (Mailpit) | `scadalink-smtp` | 1025 / 8025 | Notification capture | | OPC UA | `scadalink-opcua` | 50000 / 8080 | Simulated device tags | | REST API | `scadalink-restapi` | 5200 | External REST integration testing | ## Databases | Database | Owner | |----------|-------| | `ScadaLinkConfig` | Configuration Database (#17) | | `ScadaLinkMachineData` | Machine data (template/instance runtime data) | ## Commands ```bash # Start infra first (creates scadalink-net, MS SQL, LDAP, SMTP, OPC UA, REST API) cd infra && docker compose up -d && cd .. # Build image + deploy all 8 nodes bash docker/deploy.sh # First-time only: seed test sites with Akka + gRPC addresses bash docker/seed-sites.sh # View logs docker compose -f docker/docker-compose.yml logs -f docker logs -f scadalink-central-a # Health curl -s http://localhost:9001/health/ready | python3 -m json.tool curl -s http://localhost:9002/health/ready | python3 -m json.tool # Stop application nodes (preserves SQLite + logs) bash docker/teardown.sh ``` ## CLI Access The CLI talks to the Traefik LB, which routes to the active central node. ```bash dotnet run --project src/ScadaLink.CLI -- \ --url http://localhost:9000 \ --username multi-role --password password \ template list ``` Direct node access: `http://localhost:9001` (central-a), `http://localhost:9002` (central-b). ## Test Users All passwords are `password`. See `infra/glauth/config.toml` for the full list. | Username | Roles | |----------|-------| | `admin` | Admin | | `designer` | Design | | `deployer` | Deployment | | `multi-role` | Admin, Design, Deployment | ## Notes - Reference deployment for the project — when a change ships, it gets validated here first. - Concurrent with [`docker-cluster-env2`](docker-cluster-env2.md) on the same host; the two stacks share the `scadalink-net` network and `infra/` services but use disjoint host ports (`90XX` vs `91XX`) and databases. - Detailed setup, failover testing, and build-cache notes live in [`docker/README.md`](../docker/README.md).