Files
scadalink-design/docker-env2
Joseph Doherty f1c3019eca fix(docker-env2): seed Design + Deployment LDAP mappings post-deploy
SecurityConfiguration.HasData declares 4 LdapGroupMapping seed rows
(Admin / Design / Deployment-All / Deployment-SiteA) but the
InitialSchema migration only INSERTs the Admin row -- the other three
were never captured into a migration. A fresh ScadaLinkConfig2 starts
with multi-role getting Admin only, no Design or Deployment access.
(The same divergence exists on primary's ScadaLinkConfig, but it has
the rows from earlier history.)

Insert the missing three idempotently from seed-sites.sh so env2's
fresh deploys end up role-aligned with the running primary cluster.
The longer-term fix is a new EF migration that captures the HasData
diff -- intentionally not done here to avoid touching the primary
cluster's existing rows.
2026-05-24 08:01:06 -04:00
..
2026-05-24 07:17:38 -04:00

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 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

# 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 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 docker/deploy.sh         # primary
bash docker-env2/deploy.sh    # env2

Both UIs are now reachable:

Teardown

bash docker-env2/teardown.sh

Containers stop, volumes (data + logs) preserved. To also drop the env2 databases:

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

dotnet run --project src/ScadaLink.CLI -- \
    --url http://localhost:9100 \
    --username multi-role --password password \
    template list

View Logs

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 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).