Reputation: 1579
I have a project which requires the Visual C++ Redistributable packages installed on-top of the standard ASP.NET Core and .NET runtimes and libraries in the Microsoft ASP.NET Core Runtime Docker image.
I've tried doing this by expanding the example Dockerfile
supplied in the Microsoft Lean .NET Containerize a .NET app tutorial to additionally install the Visual C++ Redistributables with VcRedist.
The resultant Dockerfile
looks like the following:
FROM mcr.microsoft.com/dotnet/sdk:8.0-nanoserver-1809 AS build-env
WORKDIR /App
# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
# Build and publish a release
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0-windowsservercore-ltsc2022
WORKDIR /App
COPY --from=build-env /App/out .
COPY --from=build-env /App/InstallVCPPRedist.ps1 .
SHELL ["powershell", "command" ]
RUN .\InstallVCPPRedist.ps1
CMD [ "ASPApp.exe" ]
Where the installation of the Visual C++ Redistrutable packages via VcRedist
is carried out in a PowerShell script copied to the instance during the build process, InstallVCPPRedist.ps1
, as follows:
try {
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted
Install-Module -Name VcRedist
Import-Module -Name VcRedist
mkdir C:\Temp
mkdir C:\Temp\VcRedist
$VcRedists = Save-VcRedist -VcList (Get-VcList) -Path "C:\Temp\VcRedist"
Install-VcRedist -VcList $VcRedists
} catch {
Write-Error "An error occurred: $_"
exit 1
}
exit 0
When I run docker build
it looks like the build process completes without issue, as below:
docker build -t docker-asp-vcpp-redist-image .
Sending build context to Docker daemon 38.69MB
Step 1/12 : FROM mcr.microsoft.com/dotnet/sdk:8.0-nanoserver-1809 AS build-env
---> 86c24fcbbcf6
Step 2/12 : WORKDIR /App
---> Using cache
---> fd9b6023d30a
Step 3/12 : COPY . ./
---> d90f3407e7b1
Step 4/12 : RUN dotnet restore
---> Running in 035fb5e7392a
Determining projects to restore...
Restored C:\App\Project.csproj (in 8.38 sec).
---> Removed intermediate container 035fb5e7392a
---> 5e17e340c728
Step 5/12 : RUN dotnet publish -c Release -o out
---> Running in a92c3d301887
MSBuild version 17.9.8+b34f75857 for .NET
Determining projects to restore...
All projects are up-to-date for restore.
C:\App\Program.cs(17,1): warning CS4014: Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call. [C:\App\Project.csproj]
Project-> C:\App\bin\Release\net6.0\Project.dll
Project -> C:\App\out\
---> Removed intermediate container a92c3d301887
---> e5c314cf35d2
Step 6/12 : FROM mcr.microsoft.com/dotnet/aspnet:6.0-windowsservercore-ltsc2022
---> 2ff1b8e8da5c
Step 7/12 : WORKDIR /App
---> Using cache
---> 417102a4468a
Step 8/12 : COPY --from=build-env /App/out .
---> Using cache
---> 034f52b6ffd6
Step 9/12 : COPY --from=build-env /App/InstallVCPPRedist.ps1 .
---> Using cache
---> 0b3bc1cbbf71
Step 10/12 : SHELL [ "powershell", "command" ]
---> Using cache
---> 646e586e2160
Step 11/12 : RUN .\InstallVCPPRedist.ps1
---> Running in bd8ae54f6d8d
---> Removed intermediate container bd8ae54f6d8d
---> 1c56dcb78841
Step 12/12 : CMD [ "Project.exe" ]
---> Running in fca2ef892d35
---> Removed intermediate container fca2ef892d35
---> 0c8694e5d0ba
Successfully built 0c8694e5d0ba
Successfully tagged docker-asp-vcpp-redist-image:latest
But for some reason the Visual C++ Redistributes still don't seem to be present on the machine.
What am I missing here?
For context, I've tried manually running .\InstallVCPPRedist.ps1
in a docker container launched from my built image and it seems to complete without issue and result in the VC++ Redistributable being installed correctly, so I'm not sure what's causing it not to work when running from the Dockerfile
during the build.
Upvotes: 0
Views: 178
Reputation: 1579
It would seem that the issue was caused by the way that PowerShell executes scripts by default.
As far as I understand, without explicitly telling it otherwise, PowerShell doesn't wait for the whole script to return before continuing.
Within the Dockerfile
, this meant that docker was happy to continue with the remainder of the steps after:
RUN .\InstallVCPPRedist.ps1
Before all the steps in the PowerShell script have actually finished executing.
As outlined in the following Stack Overflow answer: https://stackoverflow.com/a/48804143/7647013, telling PowerShell to execute with the $ProgressPreference='SilentlyContinue'
and $ErrorActionPreference = 'Stop'
options set forces PowerShell to only return that it's done running the .\InstallVCPPRedist.ps1
script when it's progressed through the whole script or failed.
Changing the:
SHELL ["powershell", "command" ]
Line to
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
In my Dockerfile
allowed docker build
to successfully create a version of the ASP.NET Core Runtime image for my project with the Visual C++ Redistributeables present.
Upvotes: 0