From bf6741ba7fba8b93a982f1c0b582752ccb5cd293 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Fri, 17 Apr 2026 14:54:52 -0400 Subject: [PATCH] =?UTF-8?q?Doc=20=E2=80=94=20flesh=20out=20dev-environment?= =?UTF-8?q?.md=20inner-loop=20bootstrap=20with=20the=20explicit=20Windows?= =?UTF-8?q?=20install=20steps=20that=20surfaced=20when=20actually=20trying?= =?UTF-8?q?=20to=20stand=20up=20SQL=20Server=20on=20the=20local=20box:=20p?= =?UTF-8?q?rereq=20winget=20commands=20per=20tool=20(.NET=2010=20SDK=20/?= =?UTF-8?q?=20.NET=20Framework=204.8=20SDK=20+=20targeting=20pack=20/=20Gi?= =?UTF-8?q?t=20/=20PowerShell=207.4+);=20WSL2=20install=20(UAC-elevated)?= =?UTF-8?q?=20as=20a=20separate=20sub-step=20before=20Docker=20Desktop;=20?= =?UTF-8?q?Docker=20Desktop=20install=20(UAC-elevated)=20followed=20by=20s?= =?UTF-8?q?ign-out/sign-in=20for=20docker-users=20group=20membership;=20ex?= =?UTF-8?q?plicit=20post-install=20Docker=20Desktop=20config=20checklist?= =?UTF-8?q?=20(WSL=202=20based=20engine=20=3D=20checked,=20Windows=20conta?= =?UTF-8?q?iners=20=3D=20NOT=20checked,=20WSL=20Integration=20enabled=20fo?= =?UTF-8?q?r=20Ubuntu)=20per=20decision=20#134;=20named=20volume=20`otopcu?= =?UTF-8?q?a-mssql-data:/var/opt/mssql`=20on=20the=20SQL=20Server=20contai?= =?UTF-8?q?ner=20so=20DB=20files=20survive=20container=20restart=20and=20`?= =?UTF-8?q?docker=20rm`;=20sqlcmd=20verification=20command=20using=20the?= =?UTF-8?q?=20new=20`mssql-tools18`=20path=20that=20the=202022=20image=20s?= =?UTF-8?q?hips=20with;=20EF=20Core=20CLI=20install=20for=20use=20starting?= =?UTF-8?q?=20in=20Phase=201=20Stream=20B;=20bumped=20step=20count=20from?= =?UTF-8?q?=208=20=E2=86=92=2010.=20Also=20adds=20a=20Troubleshooting=20su?= =?UTF-8?q?bsection=20covering=20the=20seven=20most=20common=20Windows=20i?= =?UTF-8?q?nstall=20snags=20(WSL=20distro=20not=20auto-installed=20needs?= =?UTF-8?q?=20`-d=20Ubuntu`;=20Docker=20PATH=20not=20refreshed=20needs=20n?= =?UTF-8?q?ew=20shell=20or=20sign-in;=20docker-users=20group=20membership?= =?UTF-8?q?=20needs=20sign-out/in;=20WSL=202=20kernel=20update=20needs=20m?= =?UTF-8?q?anual=20install=20on=20legacy=20systems;=20SA=20password=20comp?= =?UTF-8?q?lexity=20rules;=20Linux=20vs=20Windows=20containers=20mode=20mi?= =?UTF-8?q?smatch;=20Hyper-V=20coexistence=20with=20Docker=20requires=20WS?= =?UTF-8?q?L=202=20backend=20not=20Hyper-V=20backend=20per=20decision=20#1?= =?UTF-8?q?34).=20Step=201=20acceptance=20criteria=20gain=20"docker=20ps?= =?UTF-8?q?=20shows=20otopcua-mssql=20Up"=20and=20explicit=20note=20that?= =?UTF-8?q?=20steps=204a/4b=20need=20admin=20elevation=20(no=20silent=20ad?= =?UTF-8?q?min-free=20path=20exists=20on=20Windows).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 (1M context) --- docs/v2/dev-environment.md | 106 +++++++++++++++++++++++++++++++++---- 1 file changed, 97 insertions(+), 9 deletions(-) diff --git a/docs/v2/dev-environment.md b/docs/v2/dev-environment.md index aa82789..a3310b0 100644 --- a/docs/v2/dev-environment.md +++ b/docs/v2/dev-environment.md @@ -108,25 +108,102 @@ The tier split keeps developer onboarding fast (no Docker required for first bui ## Bootstrap Order — Inner-loop Developer Machine -Order matters because some installs have prerequisites. ~30–60 min total on a fresh machine. +Order matters because some installs have prerequisites and several need admin elevation (UAC). ~60–90 min total on a fresh Windows machine, including reboots. + +**Admin elevation appears at**: WSL2 install (step 4a), Docker Desktop install (step 4b), and any `wsl --install -d` call. winget will prompt UAC interactively when these run; accept it. There is no fully-silent admin-free install path on Windows for Docker Desktop's prerequisites. 1. **Install .NET 10 SDK** (https://dotnet.microsoft.com/) — required to build anything + ```powershell + winget install --id Microsoft.DotNet.SDK.10 --accept-package-agreements --accept-source-agreements + ``` + 2. **Install .NET Framework 4.8 SDK + targeting pack** — only needed when starting Phase 2 (Galaxy.Host); skip for Phase 0–1 if not yet there + ```powershell + winget install --id Microsoft.DotNet.Framework.DeveloperPack_4 --accept-package-agreements --accept-source-agreements + ``` + 3. **Install Git + PowerShell 7.4+** -4. **Clone repos**: + ```powershell + winget install --id Git.Git --accept-package-agreements --accept-source-agreements + winget install --id Microsoft.PowerShell --accept-package-agreements --accept-source-agreements + ``` + +4. **Install Docker Desktop** (with WSL2 backend per decision #134, leaves Hyper-V free for the future TwinCAT XAR VM): + + **4a. Enable WSL2** — UAC required: + ```powershell + wsl --install + ``` + Reboot when prompted. After reboot, the default Ubuntu distro launches and asks for a username/password — set them (these are WSL-internal, not used for Docker auth). + + Verify after reboot: + ```powershell + wsl --status + wsl --list --verbose + ``` + Expected: `Default Version: 2`, at least one distro (typically `Ubuntu`) with `STATE Running` or `Stopped`. + + **4b. Install Docker Desktop** — UAC required: + ```powershell + winget install --id Docker.DockerDesktop --accept-package-agreements --accept-source-agreements + ``` + The installer adds you to the `docker-users` Windows group. **Sign out and back in** (or reboot) so the group membership takes effect. + + **4c. Configure Docker Desktop** — open it once after sign-in: + - **Settings → General**: confirm "Use the WSL 2 based engine" is **checked** (decision #134 — coexists with future Hyper-V VMs) + - **Settings → General**: confirm "Use Windows containers" is **NOT checked** (we use Linux containers for `mcr.microsoft.com/mssql/server`, `oitc/modbus-server`, etc.) + - **Settings → Resources → WSL Integration**: enable for the default Ubuntu distro + - (Optional, large fleets) **Settings → Resources → Advanced**: bump CPU / RAM allocation if you have headroom + + Verify: + ```powershell + docker --version + docker ps + ``` + Expected: version reported, `docker ps` returns an empty table (no containers running yet, but the daemon is reachable). + +5. **Clone repos**: ```powershell git clone https://gitea.dohertylan.com/dohertj2/lmxopcua.git git clone https://gitea.dohertylan.com/dohertj2/scadalink-design.git git clone https://gitea.dohertylan.com/dohertj2/3yearplan.git ``` -5. **Install SQL Server 2022 dev edition** (local install) OR start the Docker container (see Resource B): + +6. **Start SQL Server** (Linux container; runs in the WSL2 backend): ```powershell - docker run --name otopcua-mssql -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=OtOpcUaDev_2026!" ` - -p 1433:1433 -d mcr.microsoft.com/mssql/server:2022-latest + docker run --name otopcua-mssql ` + -e "ACCEPT_EULA=Y" ` + -e "MSSQL_SA_PASSWORD=OtOpcUaDev_2026!" ` + -p 1433:1433 ` + -v otopcua-mssql-data:/var/opt/mssql ` + -d mcr.microsoft.com/mssql/server:2022-latest ``` -6. **Install GLAuth** at `C:\publish\glauth\` per existing CLAUDE.md instructions; populate `glauth-otopcua.cfg` with the test users + groups (template in `docs/v2/dev-environment-glauth-config.md` — to be added in the setup task) -7. **Run `dotnet restore`** in the `lmxopcua` repo -8. **Run `dotnet build ZB.MOM.WW.OtOpcUa.slnx`** (post-Phase-0) or `ZB.MOM.WW.LmxOpcUa.slnx` (pre-Phase-0) — verifies the toolchain + + The `-v otopcua-mssql-data:/var/opt/mssql` named volume preserves database files across container restarts and `docker rm` — drop it only if you want a strictly throwaway instance. + + Verify: + ```powershell + docker ps --filter name=otopcua-mssql + docker exec -it otopcua-mssql /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "OtOpcUaDev_2026!" -C -Q "SELECT @@VERSION" + ``` + Expected: container `STATUS Up`, `SELECT @@VERSION` returns `Microsoft SQL Server 2022 (...)`. + + To stop / start later: + ```powershell + docker stop otopcua-mssql + docker start otopcua-mssql + ``` + +7. **Install GLAuth** at `C:\publish\glauth\` per existing CLAUDE.md instructions; populate `glauth-otopcua.cfg` with the test users + groups (template in `docs/v2/dev-environment-glauth-config.md` — to be added in the setup task) + +8. **Install EF Core CLI** (used to apply migrations against the SQL Server container starting in Phase 1 Stream B): + ```powershell + dotnet tool install --global dotnet-ef --version 10.0.* + ``` + +9. **Run `dotnet restore`** in the `lmxopcua` repo + +10. **Run `dotnet build ZB.MOM.WW.OtOpcUa.slnx`** (post-Phase-0) or `ZB.MOM.WW.LmxOpcUa.slnx` (pre-Phase-0) — verifies the toolchain 9. **Run `dotnet test`** with the inner-loop filter — should pass on a fresh machine ## Bootstrap Order — Integration Host @@ -213,11 +290,22 @@ Seeds are idempotent (re-runnable) and gitignored where they contain credentials ### Step 1 — Inner-loop dev environment (each developer, ~1 day with documentation) **Owner**: developer -**Prerequisite**: Bootstrap order steps 1–9 above +**Prerequisite**: Bootstrap order steps 1–10 above (note: steps 4a, 4b, and any later `wsl --install -d` call require admin elevation / UAC interaction — there is no fully-silent admin-free install path on Windows for Docker Desktop's prerequisites) **Acceptance**: - `dotnet test ZB.MOM.WW.OtOpcUa.slnx` passes - A test that touches the central config DB succeeds (proves SQL Server reachable) - A test that authenticates against GLAuth succeeds (proves LDAP reachable) +- `docker ps --filter name=otopcua-mssql` shows the SQL Server container `STATUS Up` + +### Troubleshooting (common Windows install snags) + +- **`wsl --install` says "Windows Subsystem for Linux has no installed distributions"** after first reboot — open a fresh PowerShell and run `wsl --install -d Ubuntu` (the `-d` form forces a distro install if the prereq-only install ran first). +- **Docker Desktop install completes but `docker --version` reports "command not found"** — `PATH` doesn't pick up the new Docker shims until a new shell is opened. Open a fresh PowerShell, or sign out/in, and retry. +- **`docker ps` reports "permission denied" or "Cannot connect to the Docker daemon"** — your user account isn't in the `docker-users` group yet. Sign out and back in (group membership is loaded at login). Verify with `whoami /groups | findstr docker-users`. +- **Docker Desktop refuses to start with "WSL 2 installation is incomplete"** — open the WSL2 kernel update from https://aka.ms/wsl2kernel, install, then restart Docker Desktop. (Modern `wsl --install` ships the kernel automatically; this is mostly a legacy problem.) +- **SQL Server container starts but immediately exits** — SA password complexity. The default `OtOpcUaDev_2026!` meets the requirement (≥8 chars, upper + lower + digit + symbol); if you change it, keep complexity. Check `docker logs otopcua-mssql` for the exact failure. +- **`docker run` fails with "image platform does not match host platform"** — your Docker is configured for Windows containers. Switch to Linux containers in Docker Desktop tray menu ("Switch to Linux containers"), or recheck Settings → General per step 4c. +- **Hyper-V conflict when later setting up TwinCAT XAR VM** — confirm Docker Desktop is on the **WSL 2 backend**, not Hyper-V backend. The two coexist only when Docker uses WSL 2. ### Step 2 — Integration host (one-time, ~1 week)