Stand up local dev infrastructure (OPC UA, LDAP, MS SQL) with Docker Compose, Python CLI tools for service interaction, and teardown script. Fix GLAuth config mount, OPC PLC node format, and document actual DN/namespace behavior discovered during testing. Resolve Q1-Q8,Q10: .NET 10, Akka.NET 1.5.x, monorepo with slnx, appsettings JWT, Windows Server 2022 site target.
4.0 KiB
Test Infrastructure: MS SQL 2022 Database
Overview
The test database uses Microsoft SQL Server 2022 Developer Edition running in Docker. It provides two empty databases for ScadaLink — schema creation is handled by EF Core migrations at application startup (dev mode).
Image & Ports
- Image:
mcr.microsoft.com/mssql/server:2022-latest - Port: 1433
- Edition: Developer (free, full-featured)
Credentials
| Account | Username | Password | Purpose |
|---|---|---|---|
| SA | sa |
ScadaLink_Dev1! |
Server admin (setup only) |
| App | scadalink_app |
ScadaLink_Dev1! |
Application login (db_owner on both databases) |
Databases
| Database | Purpose |
|---|---|
ScadaLinkConfig |
Configuration Database component — templates, deployments, users, audit log |
ScadaLinkMachineData |
Machine/operational data storage |
Both databases are created empty by infra/mssql/setup.sql. EF Core migrations populate the schema.
Data Persistence
SQL data is stored in the named Docker volume scadalink-mssql-data. Data survives container restarts and docker compose down. To reset the database completely:
docker compose down -v
docker compose up -d
# Re-run setup.sql after the container starts
First-Time Setup
After the first docker compose up -d, run the setup script:
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1!' -C \
-i /docker-entrypoint-initdb.d/setup.sql
This creates the databases and the scadalink_app login. You only need to run this once (or again after deleting the volume).
Connection Strings
For appsettings.Development.json:
Server=localhost,1433;Database=ScadaLinkConfig;User Id=scadalink_app;Password=ScadaLink_Dev1!;TrustServerCertificate=true
Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Password=ScadaLink_Dev1!;TrustServerCertificate=true
Verification
- Check the container is running:
docker ps --filter name=scadalink-mssql
- Query using
sqlcmdinside the container:
docker exec -it scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1!' -C \
-Q "SELECT name FROM sys.databases"
- Verify the app login:
docker exec -it scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U scadalink_app -P 'ScadaLink_Dev1!' -C \
-d ScadaLinkConfig \
-Q "SELECT DB_NAME()"
CLI Tool
The infra/tools/mssql_tool.py script provides a convenient CLI for interacting with the SQL Server.
Install dependencies (one-time):
pip install -r infra/tools/requirements.txt
Commands:
# Check connectivity and verify expected databases exist
python infra/tools/mssql_tool.py check
# Run the first-time setup script (uses autocommit mode for CREATE DATABASE)
python infra/tools/mssql_tool.py setup --script infra/mssql/setup.sql
# List tables in a database
python infra/tools/mssql_tool.py tables --database ScadaLinkConfig
# Run an ad-hoc query
python infra/tools/mssql_tool.py query --database ScadaLinkConfig --sql "SELECT name FROM sys.tables"
Use --host, --port, --user, --password to override defaults (localhost:1433, sa, ScadaLink_Dev1!). Run with --help for full usage.
Relevance to ScadaLink Components
- Configuration Database — primary consumer; EF Core context targets
ScadaLinkConfig. - Deployment Manager — reads/writes deployment records in
ScadaLinkConfig. - Template Engine — reads/writes template definitions in
ScadaLinkConfig. - Security & Auth — user/role data stored in
ScadaLinkConfig.
Notes
- The
sapassword must meet SQL Server complexity requirements (uppercase, lowercase, digit, special character, 8+ characters). - If the container fails to start, check Docker has at least 2GB RAM allocated (SQL Server minimum requirement).
- The setup script is idempotent — safe to run multiple times.