Collection of useful Windows Docker Images
Image | Contains |
---|---|
VS2019-VCTools | Microsoft.VisualStudio.Workload.VCTools+Recommended |
VS2019-VCTools-Choco-Python | Microsoft.VisualStudio.Workload.VCTools+Recommended, Chocolatey, Python 3.9.0 |
NET4.8-VS2019-VCTools | NET4.8 SDK, Microsoft.VisualStudio.Workload.VCTools+Recommended |
Choco | Chocolatey |
Android-r20 | Android NDK r20, Android SDK 26.1.1 |
UWP (TODO) | UWP for x86,x64,ARM |
XboxOne (TODO) | XboxOne SDK explanation on how to create an image given you already have the Microsoft files |
Xbox Series XS (TODO) | Xbox Series XS SDK explanation on how to create an image given you already have the Microsoft files |
PS4 (TODO) | PS4 SDK explanation on how to create an image given you already have the Sony files |
PS5 (TODO) | PS5 SDK explanation on how to create an image given you already have the Sony files |
Build Tools install the .NET framework, but it can't be installed on Windows Server Core, you need to use an image with them already installed and only then install the build tools
Something like this:
FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019
Will work
By default Hyper-V will run a VM with just 2 cores and 512MB of RAM
Use --cpus=%NUMBER_OF_PROCESSORS%
and --memory=4GB
with docker run
⚠️ when doingdocker build
you can only use--memory
moby/moby#38387
Happens when using Hyper-V + host machine folder mounted inside using a bind volume
The linker gets crazy and dies because it uses some obscure Windows Kernel APIs to read the files it needs that Docker doesn't support
To prevent it:
- Disable .pdb files creation
or
- Use Process Isolation
or
- Don't mount host machine folders
or
- Mount a volume read only and copy the files
Ok so mspdbsrv.exe uses some type of kernel API/system call to let the linker CL.exe write the .pdb files in parallel when using multithreaded compilation /MT
context
Docker Windows containers by default run on Windows using actually a VM, so yeah, Docker is crap on Windows and just runs as a real VM running an entire kernel inside too (unlike Linux in which a Docker Linux container is actually just a process with less permissions)
the Hyper-V hypervisor when mounting files inside the Docker VM needs to let communicate the internal kernel with the external one
the problem?
my theory is that Microsoft forgot the kernel API in the internal simplified VM kernel...
OR
both kernels have the API but Hyper-V does a bad communication between the two kernels
the effect?
when something tries to use that asynchronous writing file API the process will corrupt/crash
how VS2019 fixed it?
considering there is no Hyper-V patch (otherwise it wouldn't happen even with VS2015) my theory is that Microsoft just removed the usage of that API and used one that is also inside the internal container kernel
the fix?
don't let mspdbsrv.exe write .pdb files inside a container volume that is actually a host directory mounted inside
This is confirmed to work with VS2017
Patch A "mirror":
- mount the source code inside as a read-only volume
- copy it to a real container folder
- start compilation there
- then copy the artifacts to a read/write volume so they can be extracted from the container as artifacts
⚠️ I have no idea if this works for VS2015
✔️ Seems to work well for VS2017
Patch B "layer":
- bake the source code inside the container as a new Docker layer on top
- start compilation
- then copy the artifacts to a read/write volume so they can be extracted from the container as artifacts
⚠️ I have never tried this solution
Patch C "black magic":
- add the source code inside the container as a new Docker layer on top
- actually start compilation not as a running container, but as an image creation process (docker build)
- run the container with read/write volume
- then copy the artifacts to a read/write volume so they can be extracted from the container as artifacts
✔️ Seems to work well for VS2015
⚠️ I have no idea if this works for VS2017
advantage?
the stablest one, there are never possibly unstable Hyper-V volumes mounted when compiling
disadvantage?
max dual-core compilation
'MSBuild' is not recognized as an internal or external command, operable program or batch file
OR VC Targets path cl.exe not found or similar errors
You need to initialize the msbuild environment
call C:\BuildTools\VC\Auxiliary\Build\vcvarsall.bat <architecture>
Check the vcvarsall documentation
Error response from daemon: hcsshim::CreateComputeSystem {container_guid}: The requested resource is in use.
- Restart Hyper-V Compute Service
- Wait a bit
- Restart Docker
You need an image with the .NET SDK installed
Use choco, it's stable for that
RUN choco install -y windows-sdk-8.1
You need a bare metal instance
https://aws.amazon.com/blogs/compute/running-hyper-v-on-amazon-ec2-bare-metal-instances/
Something like
<powershell>
docker run --rm imagename ...
</powershell>
After setting up the userdata remember to run:
C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 –Schedule
before shutdown and before saving the AMI
https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html
⚠️ Be careful of subnet gateways, you risk to mess up the route tables if you create the custom AMI in one subnet and then run it in another, the AMI will download the user data from a specific Amazon internal IP, as a rule of thumb just run it in the same subnet it was created if you don't want problems https://aws.amazon.com/premiumsupport/knowledge-center/waiting-for-metadata/