diff --git a/docker-env2/README.md b/docker-env2/README.md new file mode 100644 index 0000000..9064a3e --- /dev/null +++ b/docker-env2/README.md @@ -0,0 +1,140 @@ +# ScadaLink Env2 Docker Infrastructure + +A second Docker deployment of a minimal ScadaLink cluster topology, designed to run **concurrently with** the primary `docker/` stack so the Transport (#24) feature can be exercised end-to-end across two real environments. + +See [`docs/plans/2026-05-24-second-environment-design.md`](../docs/plans/2026-05-24-second-environment-design.md) for the design rationale. + +## Cluster Topology + +``` + ┌───────────────────┐ + │ Traefik LB :9100 │ ◄── CLI / Browser + │ Dashboard :8181 │ + └────────┬──────────┘ + │ routes to active node +┌──────────────────────┼──────────────────────────────┐ +│ Env2 Central Cluster │ +│ │ +│ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ env2-central-a │◄──►│ env2-central-b │ │ +│ │ Web UI :9101 │ │ Web UI :9102 │ │ +│ │ Akka :9111 │ │ Akka :9112 │ │ +│ └────────┬─────────┘ └─────────────────┘ │ +│ │ │ +└───────────┼─────────────────────────────────────────┘ + │ Akka.NET Remoting + ▼ +┌────────────────────┐ +│ Env2 Site-X │ +│ (Env2 Site X) │ +│ │ +│ node-a ◄──► node-b│ +│ Akka :9121 :9122 │ +│ gRPC :9123 :9124 │ +└────────────────────┘ +``` + +## Port Allocation + +Env2 host ports are the primary's ports + 100. Both stacks can run simultaneously. + +| Node | Container Name | Host Web | Host Akka | Host gRPC | Internal | +|------|----------------|----------|-----------|-----------|----------| +| Traefik LB | `scadalink-env2-traefik` | 9100 | — | — | 80 (proxy), 8080 (dashboard host:8181) | +| Central A | `scadalink-env2-central-a` | 9101 | 9111 | — | 5000 (web), 8081 (Akka) | +| Central B | `scadalink-env2-central-b` | 9102 | 9112 | — | 5000 (web), 8081 (Akka) | +| Site-X A | `scadalink-env2-site-x-a` | — | 9121 | 9123 | 8082 (Akka), 8083 (gRPC) | +| Site-X B | `scadalink-env2-site-x-b` | — | 9122 | 9124 | 8082 (Akka), 8083 (gRPC) | + +## Shared Infrastructure + +Env2 attaches to the existing `scadalink-net` Docker bridge network and reuses these primary infra containers: + +| Service | Container | What env2 uses it for | +|---------|-----------|-----------------------| +| MS SQL | `scadalink-mssql` | Env2-specific databases `ScadaLinkConfig2` / `ScadaLinkMachineData2` | +| LDAP | `scadalink-ldap` | Authentication (same test users) | +| SMTP | `scadalink-smtp` | Notification capture in Mailpit (env2 emails distinguishable by `FromAddress`) | +| OPC UA | `scadalink-opcua` | Simulated tags for site-x data connections | +| REST API | `scadalink-restapi` | External REST API testing | + +## Commands + +### First-Time Setup + +```bash +# 1. Make sure primary infra is up (creates scadalink-net, scadalink-mssql, etc.) +cd infra && docker compose up -d && cd .. + +# 2. Build image + create env2 databases + deploy env2 containers +bash docker-env2/deploy.sh + +# 3. Seed env2's single test site (first-time only) +bash docker-env2/seed-sites.sh +``` + +### After Code Changes + +```bash +bash docker-env2/deploy.sh +``` + +The Docker build is shared with the primary stack — if you've just run `docker/deploy.sh`, the env2 build hits a fully cached image. + +### Running Both Stacks Concurrently + +```bash +bash docker/deploy.sh # primary +bash docker-env2/deploy.sh # env2 +``` + +Both UIs are now reachable: +- Primary: http://localhost:9000 +- Env2: http://localhost:9100 + +### Teardown + +```bash +bash docker-env2/teardown.sh +``` + +Containers stop, volumes (data + logs) preserved. To also drop the env2 databases: + +```bash +docker exec scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \ + -S localhost -U sa -P 'ScadaLink_Dev1#' -C \ + -Q "DROP DATABASE ScadaLinkConfig2; DROP DATABASE ScadaLinkMachineData2;" +``` + +### CLI Access + +```bash +dotnet run --project src/ScadaLink.CLI -- \ + --url http://localhost:9100 \ + --username multi-role --password password \ + template list +``` + +### View Logs + +```bash +docker compose -f docker-env2/docker-compose.yml logs -f +docker logs -f scadalink-env2-central-a +``` + +## Test Users + +Same as primary (env2 shares LDAP). See `infra/glauth/config.toml` and primary `docker/README.md`. + +## Transport Testing Workflow + +See [`docs/plans/2026-05-24-second-environment-verification.md`](../docs/plans/2026-05-24-second-environment-verification.md) for the manual golden-path checklist. + +## What's Different from Primary + +- Single site (`site-x`) instead of three (`site-a/b/c`). +- Host port range 91XX vs primary 90XX. +- Container names prefixed `scadalink-env2-`. +- Databases `ScadaLinkConfig2` / `ScadaLinkMachineData2` on the **shared** `scadalink-mssql`. +- `Transport.SourceEnvironment` = `"docker-cluster-env2"` (stamped into exported bundle manifests). +- Distinct `Security.JwtSigningKey` (sessions cannot cross envs).