I'm trying to build a docker image from a really simple project, just to start understanding how docker works and communicate. So, I have created a WebApi project, with just one method that returns a 200.
Once the project has been created, I created the dockerfile:
# TP5 for technology preview (will not be needed when we go GA)
# FROM microsoft/iis
FROM microsoft/iis:TP5
MAINTAINER Roman_Hervas
# Install Chocolatey (tools to automate commandline compiling)
ENV chocolateyUseWindowsCompression='false'
RUN #powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
# Install build tools
RUN powershell add-windowsfeature web-asp-net45 \
&& choco install microsoft-build-tools -y --allow-empty-checksums -version 14.0.23107.10 \
&& choco install dotnet4.6-targetpack --allow-empty-checksums -y \
&& choco install nuget.commandline --allow-empty-checksums -y \
&& nuget install MSBuild.Microsoft.VisualStudio.Web.targets -Version 14.0.0.3 \
&& nuget install WebConfigTransformRunner -Version 1.0.0.1
RUN powershell remove-item C:\inetpub\wwwroot\iisstart.*
# Copy files (temporary work folder)
RUN md c:\build
WORKDIR c:/build
COPY . c:/build
# Restore packages, build, copy
RUN nuget restore \
&& "c:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /p:Platform="Any CPU" /p:VisualStudioVersion=12.0 /p:VSToolsPath=c:\MSBuild.Microsoft.VisualStudio.Web.targets.14.0.0.3\tools\VSToolsPath WebApiDocker.sln \
&& xcopy c:\build\WebApiDocker\* c:\inetpub\wwwroot /s
# NOT NEEDED ANYMORE –> ENTRYPOINT powershell .\InitializeContainer
And the InitializeContainer:
If (Test-Path Env:\ASPNET_ENVIRONMENT)
{
\WebConfigTransformRunner.1.0.0.1\Tools\WebConfigTransformRunner.exe \inetpub\wwwroot\Web.config "\inetpub\wwwroot\Web.$env:ASPNET_ENVIRONMENT.config" \inetpub\wwwroot\Web.config
}
# prevent container from exiting
powershell
So, finally, I try to execute the command to build the project: docker build -t dockerexample .
The result is a failure with the following message (step 4):
Step 1/10 : FROM microsoft/iis:TP5
---> accd044753c1
Step 2/10 : MAINTAINER Roman_Hervas
---> Using cache
---> e42af9c57e0d
Step 3/10 : ENV chocolateyUseWindowsCompression 'false'
---> Using cache
---> 24621a9f18d9
Step 4/10 : RUN #powershell -NoProfile -ExecutionPolicy unrestricted -Command "(iex ((New-Object System.Net.WebClient).D
ownloadString('https://chocolatey.org/install.ps1'))) >$null 2>&1" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
---> Running in 61199189917a
container 61199189917a0057fb54dddca6d80a6c6f9e8b77d2326379537684f58fefbe50 encountered an error during CreateContainer:
failure in a Windows system call: A connection could not be established with the Virtual Machine hosting the Container.
(0xc0370108) extra info: {"SystemType":"Container","Name":"61199189917a0057fb54dddca6d80a6c6f9e8b77d2326379537684f58fefb
e50","Owner":"docker","IsDummy":false,"IgnoreFlushesDuringBoot":true,"LayerFolderPath":"C:\\ProgramData\\Docker\\windows
filter\\61199189917a0057fb54dddca6d80a6c6f9e8b77d2326379537684f58fefbe50","Layers":[{"ID":"08b847bd-7f7e-5758-90be-43262
e170e22","Path":"C:\\ProgramData\\Docker\\windowsfilter\\64e43de6efd9eee001b12f6ed8add83d1aefff6cb5f8b55e9a44c4b1b2f27b8
0"},{"ID":"293472e6-599f-5a8e-b531-ac7499b0c900","Path":"C:\\ProgramData\\Docker\\windowsfilter\\cfb71fcbe2f95caa2a5306d
800c3d649067c00702a26a208ead6f5fed58e49c8"},{"ID":"baacc247-5374-5761-812f-e1ad911fda31","Path":"C:\\ProgramData\\Docker
\\windowsfilter\\89144a071d22e130e0ca9a069857a181b8976e9557c95395fb58116358dd5a02"},{"ID":"3d538ae4-eaf0-574c-b274-30bba
ce1a9b0","Path":"C:\\ProgramData\\Docker\\windowsfilter\\e2ff3bea019eaee94ab33312b6a39d6305b85df9b0b950680aa38e55eec5437
1"},{"ID":"937e8340-c320-5f09-a87e-9cd5912f40bb","Path":"C:\\ProgramData\\Docker\\windowsfilter\\0dd23a484fe7eea9da274be
8e6e1f0768b52a8a121e7bf274d5974ada02400d8"}],"HostName":"2ac70997c0f2","MappedDirectories":[],"SandboxPath":"C:\\Program
Data\\Docker\\windowsfilter","HvPartition":true,"EndpointList":["deb85df1-5dba-4394-a1ac-77f4a106e31a"],"HvRuntime":{"Im
agePath":"C:\\ProgramData\\Docker\\windowsfilter\\0dd23a484fe7eea9da274be8e6e1f0768b52a8a121e7bf274d5974ada02400d8\\Util
ityVM"},"Servicing":false,"AllowUnqualifiedDNSQuery":true}
I'm totally noob with Docker, so I have no idea of the problem here, and Google has not been too much helpful. My operating system is Windows 10 Pro, and Docker version is 17.03.1-ce-win12 (12058).
Question:
Why is it launching an error in step 4?
Thank you very much in advance.
Related
I'm trying to move our self-hosted DevOps agent hosts from being stand-alone VMs to being docker containers, and I'm having some issues satisfying the requirements some of our pipelines have.
Specifically, vstest and visualstudio seem to be most troublesome, since I reckon I should be using a Server Core image as the base.
I was hoping these requirements would be satisfied by following this MS guide on installing build tools in a container, but alas pipelines will still not work.
Here's my current DockerFile:
# escape=`
FROM mcr.microsoft.com/windows/servercore:ltsc2022
RUN powershell add-windowsfeature web-asp-net45
RUN powershell "Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))"
RUN choco install dotnet4.7 -y
RUN choco install dotnet-sdk -y
RUN `
# Download the Build Tools bootstrapper.
curl -SL --output vs_buildtools.exe https://aka.ms/vs/17/release/vs_buildtools.exe `
`
# Install Build Tools with the Microsoft.VisualStudio.Workload.AzureBuildTools workload, excluding workloads and components with known issues.
&& (start /w vs_buildtools.exe --quiet --wait --norestart --nocache --includeRecommended `
--installPath "%ProgramFiles(x86)%\Microsoft Visual Studio\2022\BuildTools" `
--add Microsoft.VisualStudio.Workload.AzureBuildTools `
--add Microsoft.VisualStudio.Workload.DataBuildTools `
--add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools `
--add Microsoft.VisualStudio.Workload.MSBuildTools `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 `
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 `
--remove Microsoft.VisualStudio.Component.Windows81SDK `
|| IF "%ERRORLEVEL%"=="3010" EXIT 0) `
`
# Cleanup
&& del /q vs_buildtools.exe
RUN choco install nodejs -y
RUN choco install azure-cli -y
RUN choco install openjdk -y
WORKDIR /azp
COPY start.ps1 .
CMD powershell .\start.ps1
The start.ps1 is taken from this MS document.
Do I absolutely need to install the full Visual Studio suite to be able to satisfy the vstest and visualstudio pipeline requirements? If not, what kind of package do I need? If yes, is it even possible to install the whole VS suite inside a docker container?
I've ended up using the mcr.microsoft.com/dotnet/framework/sdk:4.8.1 image as the base for the agent. It contains the vstest tool (however the path needs to be manually specified using ENV). This satisfies the vstest demand and I think I'll push to have the visualstudio demand dropped, as it's likely NOT needed in our cases and our pipeline admins have simply been adding it in error.
I am having trouble running test inside a docker container in TeamCity. The project is a test project which includes: openjdk, maven, selenium, chrome (headless). Below command works locally:
cd to/my/src/code
mvn clean
mvn test
However, when I try to run the same command using TC build step which uses below dockerfile to run all the test I get error.
DockerFile:
# escape=`
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8-windowsservercore-ltsc2016
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Install Chocolatey
RUN write-host "*********** Install Chocolatey"
ARG chocolateyVersion='0.10.11'
RUN Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
# Install googlechrome
RUN write-host "*********** Install googlechrome"
RUN choco install googlechrome -y
# Install openjdk
RUN write-host "*********** Install openjdk"
RUN choco install openjdk --version=18.0.1.1 -y
# Install maven
RUN write-host "*********** Install maven"
RUN choco install maven --version=3.8.6 -y
# Verify installation
RUN java --version
RUN mvn −version
Error from TeamCity:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for visibility of Proxy element for: DefaultElementLocator 'By.id: LoginName' (tried for 40 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:95)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:272)
at com.mycompany.pages.PublishAccountPage.loginFunctionForJCR(PublishAccountPage.java:44)
at com.mycompany.tests.SampleTest.Sample(SampleTest.java:25)
Caused by: org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#LoginName"}
(Session info: headless chrome=103.0.5060.134)
For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
TC build step:
I'm trying to do some basic containers in Windows. I've been using Docker on Linux for years, but this issue is new for me.
Running the command
docker build -f windowsTest3.df -t dockertest . results in a good, tagged build.
...
---> 04064df75127
Step 13/13 : ENTRYPOINT C:/BuildTools/Common7/Tools/VsDevCmd.bat
---> Using cache
---> 9e098cff37a2
Successfully built 9e098cff37a2
Successfully tagged dockertest:latest
However, attempting to run an interactive shell inside the container gives an error. The system cannot find the path specified.
Edit: Can't believe I forgot to list the command...
To start the container interactively, I'm running docker run -it dockertest, but I've also tried docker run -it dockertest cmd and variations of that.
Running docker images shows that the tagged image exists, so I can't figure out what's causing the error.
docker images
C:\Users\devuser.DESKTOP-UV8CO47\Desktop\tmp>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
dockertest latest 9e098cff37a2 41 minutes ago 12.3GB
Here are my path locations:
C:\ProgramData\DockerDesktop\version-bin;C:\Program Files\Docker\Docker\Resources\bin;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Python37-32\Scripts\;C:\Program Files (x86)\Python37-32\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Git\cmd;C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\common\bin;C:\Program Files\Amazon\AWSCLI\bin\;C:\Program Files (x86)\GnuWin32\bin;C:\Program Files\CMake\bin;C:\Program Files\dotnet\;C:\Windows\Microsoft.NET\Framework\v4.0.30319;C:\ProgramData\chocolatey\bin;C:\PRQA\PRQA-Framework-2.4.0\common\bin;C:\Users\DevUser\AppData\Local\Microsoft\WindowsApps;C:\Program Files (x86)\IAR Systems\Embedded Workbench 8.2\arm\bin;C:\Program Files\Git\bin;C:\Program Files\7-Zip;C:\Program Files\nssm-2.24\win64
Here is a slightly abridged version of the dockerfile
FROM mcr.microsoft.com/windows:10.0.17763.316-amd64
# Restore the default Windows shell for correct batch processing.
SHELL ["cmd", "/S", "/C"]
# Download the Build Tools bootstrapper.
ADD https://aka.ms/vs/16/release/vs_buildtools.exe C:/tmp/vs_buildtools.exe
# Install Build Tools excluding workloads and components with known issues.
RUN C:/tmp/vs_buildtools.exe --quiet --wait --norestart --nocache \
--installPath C:\BuildTools \
--all \
--remove Microsoft.VisualStudio.Component.Windows10SDK.10240 \
--remove Microsoft.VisualStudio.Component.Windows10SDK.10586 \
--remove Microsoft.VisualStudio.Component.Windows10SDK.14393 \
--remove Microsoft.VisualStudio.Component.Windows81SDK \
|| IF "%ERRORLEVEL%"=="3010" EXIT 0
ENV chocolateyUseWindowsCompression=false
RUN powershell set-executionpolicy remotesigned
RUN powershell -Command Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
RUN powershell -Command Install-PackageProvider -Name chocolatey -Force
RUN powershell -command "choco install -y git"
ENTRYPOINT C:/BuildTools/Common7/Tools/VsDevCmd.bat
Please check if VsDevCmd.bat is available inside the container when it's starting, at C:/BuildTools/Common7/Tools/ path
Also as per this Doc reference
On Windows, file paths specified in the CMD instruction must use
forward slashes or have escaped backslashes \.
CMD c:\Apache24\bin\httpd.exe -w
Maybe try your ENTRYPOINT like this.
ENTRYPOINT C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat
You can also use CMD
CMD C:\\BuildTools\\Common7\\Tools\\VsDevCmd.bat
Can also try this as well but recommended is above one
ENTRYPOINT C:\BuildTools\Common7\Tools\VsDevCmd.bat
I have docker on windows server 2016. The Dockerfile contains some build tools to be installed via chocolatey. It fails every time when I am trying to build image from mentioned Dockerfile. The chocolatey tool is not running in container.
# Use the latest Windows Server Core image.
FROM microsoft/windowsservercore
ENV chocolateyUseWindowsCompression false
RUN powershell -Command \
iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); \
choco feature disable --name showDownloadProgress
RUN choco install visualstudio2015professional
RUN choco install qtcreator
RUN choco install curl
RUN choco install jq
RUN choco install 7zip.install
RUN choco install jfrog-cli
RUN choco install jom
Build command here.........
C:\Program Files\Docker>docker build -t test -f Dockerfile.txt .
Sending build context to Docker daemon 54.73MB
Step 1/10 : FROM microsoft/windowsservercore
latest: Pulling from microsoft/windowsservercore
3889bb8d808b: Pull complete
fb1ebf2c42b6: Pull complete
Digest: sha256:750440935dd3ef8ea148a8e4f83a0397540a8014938ae7b59eb78211da1d5969
Status: Downloaded newer image for microsoft/windowsservercore:latest
---> 7d89a4baf66c
Step 2/10 : ENV chocolateyUseWindowsCompression false
---> Running in 8a7b1fc97da5
---> 0f3c89daf01c
Removing intermediate container 8a7b1fc97da5
Step 3/10 : RUN powershell -Command iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); choco feature disable --name showDownloadProgress
---> Running in f7088454db37
Exception calling "DownloadString" with "1" argument(s): "Unable to connect to
the remote server"
At line:1 char:1
+ iex ((new-object net.webclient).DownloadString('https://chocolatey.or ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
choco : The term 'choco' is not recognized as the name of a cmdlet, function,
script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:88
+ ... .DownloadString('https://chocolatey.org/install.ps1')); choco feature ...
+ ~~~~~
+ CategoryInfo : ObjectNotFound: (choco:String) [], CommandNotFou
ndException
+ FullyQualifiedErrorId : CommandNotFoundException
The command 'cmd /S /C powershell -Command iex ((new-object net.webclient).DownloadString('https://chocolatey.org/install.ps1')); choco feature disable --name showDownloadProgress' returned a non-zero code: 1
I had this problem a while ago. It was destroying me for some time, I could not work out why one Docker image I had was building fine while the next one was not.
I finally traced it to an issue with restricted TLS, whereby the newer Windows docker base images required TLS1.2 which is not enabled by default. You may be encountering this with your windows server core base container.
The Chocolatey documentation refers to this situation in their section about installing-with-restricted-tls.
Their fix at time of writing was to do a little musical chairs with the TLS settings before putting them back - see below
$securityProtocolSettingsOriginal = [System.Net.ServicePointManager]::SecurityProtocol
try {
# Set TLS 1.2 (3072), then TLS 1.1 (768), then TLS 1.0 (192), finally SSL 3.0 (48)
# Use integers because the enumeration values for TLS 1.2 and TLS 1.1 won't
# exist in .NET 4.0, even though they are addressable if .NET 4.5+ is
# installed (.NET 4.5 is an in-place upgrade).
[System.Net.ServicePointManager]::SecurityProtocol = 3072 -bor 768 -bor 192 -bor 48
} catch {
Write-Warning 'Unable to set PowerShell to use TLS 1.2 and TLS 1.1 due to old .NET Framework installed. If you see underlying connection closed or trust errors, you may need to do one or more of the following: (1) upgrade to .NET Framework 4.5 and PowerShell v3, (2) specify internal Chocolatey package location (set $env:chocolateyDownloadUrl prior to install or host the package internally), (3) use the Download + PowerShell method of install. See https://chocolatey.org/install for all install options.'
}
iex ((New-Object
System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
[System.Net.ServicePointManager]::SecurityProtocol = $securityProtocolSettingsOriginal
Failing that, run your container without choco using docker run --name mycontainer -d [your container id] then use an interactive shell using docker exec -it mycontainer powershell and you'll be able to run the choco install interactively to get more information about the failure.
For me this turned out to be my antivirus specifically Symantec in my case, worked as soon as it was disabled.
Did you research following from https://github.com/chocolatey/choco/issues/1055
SET chocolateyUseWindowsCompression='false' REM No spaces in the equals
#powershell -NoProfile -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
And closest question here: Powershell unable to connect to internet at all
I managed to install choco from web in a corp network with proxy settings.
first step is creating a proxy.ps1:
$ProxyAddress = "http://proxy:port"
[system.net.webrequest]::defaultwebproxy = New-Object system.net.webproxy($ProxyAddress)
$CredCache = [System.Net.CredentialCache]::new()
$NetCreds = [System.Net.NetworkCredential]::new("username","password","")
$CredCache.Add($ProxyAddress, "Basic", $NetCreds)
[system.net.webrequest]::defaultwebproxy.credentials = $CredCache
[system.net.webrequest]::defaultwebproxy.BypassProxyOnLocal = $true
and then in Dockfile, do it this way:
FROM mcr.microsoft.com/windows:1809-amd64 AS base
SHELL ["cmd", "/S", "/C"]
# add proxy to powershell profile for all users
ADD proxy.ps1 C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1
# Install Chocolatey
RUN powershell -ExecutionPolicy unrestricted -Command `
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
The key is in the error message:
"Unable to connect to the remote server"
Your Docker container doesn't have internet connectivity to download the Chocolatey install script.
I asked this question originally at: https://github.com/aspnet/aspnet-docker/issues/349 as a part of the deprecation announcement, and I am hoping the SO community may have a good answer for this:
I am trying to use the windows side for a SPA build using the microsoft/dotnet:2.1-sdk. I know, I may be the only one trying to stay on the windows side for an ASP.NET Core Application, but our swarm initially will only have windows servers running in the native OS mode and not Hyper-V mode.
As a consequence, I need to install node.js for windows (because node.js/grunt/gulp are no longer a part of the image like they were in the microsoft/aspnetcore:2.0 image) and I tried:
RUN msiexec.exe /a https://nodejs.org/dist/v8.11.3/node-v8.11.3-x64.msi /quiet
but msiexec.exe isn't in the c:\windows\system32 of this image or in any other directory for that matter.
curl also is not in this image so I can't use that to download anything, and even if I could how do I un-tar or unzip anything?
I can't run a powershell invocation of:
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
to try to install chocolatey to install node from there as System.Net.WebClient is not available in this image.
I guess my question is is there any container native way to get node.js installed internally without having to download something outside the container, copying it in, and then executing it. Kinda defeats the purpose of a multistage build if I have to do that or at least in my opinion makes it an ugly solution.
instead curl use powershell's Invoke-WebRequest
instead unzip use Expand-Archive
installing MSI in nanoserver is not possible. For solution see: Powershell Silent Install in Nano Server with Docker
Working off the answer from Miq I was able to create an initial Dockerfile which uses the 2.1 SDK image and pulls in node manually, here is what it looks like:
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /app
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
ENV NODE_VERSION 8.11.3
ENV NODE_FULL_NAME node-v8.11.3-win-x64
#install node and npm as MS no longer does this in any .NET Core nanoserver based images since 2.1
RUN New-Item -ItemType directory -Path /build; \
Invoke-WebRequest https://nodejs.org/dist/v${env:NODE_VERSION}/${env:NODE_FULL_NAME}.zip -OutFile /build/${env:NODE_FULL_NAME}.zip; \
Expand-Archive -LiteralPath /build/${env:NODE_FULL_NAME}.zip /build; \
$newPath = (Get-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH).path; \
$nodeFullName = ${env:NODE_FULL_NAME}; \
$newPath = $newPath + ';/build/' + $nodeFullName; \
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment' -Name PATH -Value $newPath;
They added Tar and Curl to the base runtimes.
FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
#Download the package we want and unzip it to our destination
RUN curl.exe -o node.zip https://nodejs.org/dist/v10.15.3/node-v10.15.3-win-x64.zip && \
mkdir "C:\\Program Files\\node" && \
tar.exe -xf node.zip -C "C:\\Program Files\\node" --strip-components=1
A different approach, using ADD and running as Administrator so I can set the PATH.
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2-nanoserver-1903 as base
USER Administrator
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 1433
ADD https://nodejs.org/dist/v12.9.1/node-v12.9.1-win-x64.zip C:\\build\\node-v12.9.1-win-x64.zip
RUN mkdir "C:\\Program Files\\node" && \
tar.exe -xf C:\\build\\node-v12.9.1-win-x64.zip -C "C:\\Program Files\\node" --strip-components=1
RUN setx /M PATH "C:\Program Files\node;%PATH%"