# ScadaLink Installation Guide ## Prerequisites - Windows Server 2019 or later - .NET 10.0 Runtime - SQL Server 2019+ (Central nodes only) - Network connectivity between all cluster nodes (TCP ports 8081-8082) - LDAP/Active Directory server accessible from Central nodes - SMTP server accessible from all nodes (for Notification Service) ## Single Binary Deployment ScadaLink ships as a single executable (`ScadaLink.Host.exe`) that runs in either Central or Site role based on configuration. ### Windows Service Installation ```powershell # Central Node sc.exe create "ScadaLink-Central" binPath="C:\ScadaLink\ScadaLink.Host.exe" start=auto sc.exe description "ScadaLink-Central" "ScadaLink SCADA Central Hub" # Site Node sc.exe create "ScadaLink-Site" binPath="C:\ScadaLink\ScadaLink.Host.exe" start=auto sc.exe description "ScadaLink-Site" "ScadaLink SCADA Site Agent" ``` ### Directory Structure ``` C:\ScadaLink\ ScadaLink.Host.exe appsettings.json appsettings.Production.json data\ # Site: SQLite databases site.db # Deployed configs, static overrides store-and-forward.db # S&F message buffer logs\ # Rolling log files scadalink-20260316.log ``` ## Configuration Templates ### Central Node — `appsettings.json` ```json { "ScadaLink": { "Node": { "Role": "Central", "NodeHostname": "central-01.example.com", "RemotingPort": 8081 }, "Cluster": { "SeedNodes": [ "akka.tcp://scadalink@central-01.example.com:8081", "akka.tcp://scadalink@central-02.example.com:8081" ] }, "Database": { "ConfigurationDb": "Server=sqlserver.example.com;Database=ScadaLink;User Id=scadalink_svc;Password=;Encrypt=true;TrustServerCertificate=false", "MachineDataDb": "Server=sqlserver.example.com;Database=ScadaLink_MachineData;User Id=scadalink_svc;Password=;Encrypt=true;TrustServerCertificate=false" }, "Security": { "LdapServer": "ldap.example.com", "LdapPort": 636, "LdapUseTls": true, "AllowInsecureLdap": false, "LdapSearchBase": "dc=example,dc=com", "JwtSigningKey": "", "JwtExpiryMinutes": 15, "IdleTimeoutMinutes": 30 }, "HealthMonitoring": { "ReportInterval": "00:00:30", "OfflineTimeout": "00:01:00" }, "Logging": { "MinimumLevel": "Information" } }, "Serilog": { "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "Akka": "Warning" } } } } ``` ### Site Node — `appsettings.json` ```json { "ScadaLink": { "Node": { "Role": "Site", "NodeHostname": "site-01-node-a.example.com", "SiteId": "plant-north", "RemotingPort": 8081 }, "Cluster": { "SeedNodes": [ "akka.tcp://scadalink@site-01-node-a.example.com:8081", "akka.tcp://scadalink@site-01-node-b.example.com:8081" ] }, "Database": { "SiteDbPath": "C:\\ScadaLink\\data\\site.db" }, "DataConnection": { "ReconnectInterval": "00:00:05", "TagResolutionRetryInterval": "00:00:30" }, "StoreAndForward": { "SqliteDbPath": "C:\\ScadaLink\\data\\store-and-forward.db", "DefaultRetryInterval": "00:00:30", "DefaultMaxRetries": 50, "ReplicationEnabled": true }, "SiteRuntime": { "ScriptTimeoutSeconds": 30, "StaggeredStartupDelayMs": 50 }, "SiteEventLog": { "RetentionDays": 30, "MaxStorageMB": 1024, "PurgeIntervalHours": 24 }, "Communication": { "CentralSeedNode": "akka.tcp://scadalink@central-01.example.com:8081" }, "HealthMonitoring": { "ReportInterval": "00:00:30" }, "Logging": { "MinimumLevel": "Information" } } } ``` ## Database Setup (Central Only) ### SQL Server 1. Create the configuration database: ```sql CREATE DATABASE ScadaLink; CREATE LOGIN scadalink_svc WITH PASSWORD = ''; USE ScadaLink; CREATE USER scadalink_svc FOR LOGIN scadalink_svc; ALTER ROLE db_owner ADD MEMBER scadalink_svc; ``` 2. Create the machine data database: ```sql CREATE DATABASE ScadaLink_MachineData; USE ScadaLink_MachineData; CREATE USER scadalink_svc FOR LOGIN scadalink_svc; ALTER ROLE db_owner ADD MEMBER scadalink_svc; ``` 3. Apply EF Core migrations (development): - Migrations auto-apply on startup in Development environment. 4. Apply EF Core migrations (production): - Generate SQL script: `dotnet ef migrations script --project src/ScadaLink.ConfigurationDatabase` - Review and execute the SQL script against the production database. ## Network Requirements | Source | Destination | Port | Protocol | Purpose | |--------|------------|------|----------|---------| | Central A | Central B | 8081 | TCP | Akka.NET remoting | | Site A | Site B | 8081 | TCP | Akka.NET remoting | | Site nodes | Central nodes | 8081 | TCP | Central-site communication | | Central nodes | LDAP server | 636 | TCP/TLS | Authentication | | All nodes | SMTP server | 587 | TCP/TLS | Notification delivery | | Central nodes | SQL Server | 1433 | TCP | Configuration database | | Users | Central nodes | 443 | HTTPS | Blazor Server UI | ## Firewall Rules Ensure bidirectional TCP connectivity between all Akka.NET cluster peers. The remoting port (default 8081) must be open in both directions. ## Post-Installation Verification 1. Start the service: `sc.exe start ScadaLink-Central` 2. Check the log file: `type C:\ScadaLink\logs\scadalink-*.log` 3. Verify the readiness endpoint: `curl http://localhost:5000/health/ready` 4. For Central: verify the UI is accessible at `https://central-01.example.com/`