choco icon indicating copy to clipboard operation
choco copied to clipboard

Unable to Install Chocolatey in Dockerfile with PowerShell Core

Open greggbjensen opened this issue 3 years ago • 7 comments

What You Are Seeing?

The PowerShell install of Chocolatey gives the following error:

Initialize-Chocolatey: C:\Windows\TEMP\chocolatey\chocoInstall\tools\chocolateyInstall.ps1:75
Line |
  75 |  Initialize-Chocolatey
     |  ~~~~~~~~~~~~~~~~~~~~~
     | Cannot bind argument to parameter 'Path' because it is an
     | empty string.

I am creating a build inside a Dockerflile using mcr.microsoft.com/dotnet/sdk:6.0, and trying to add Chocolatey to it.

What is Expected?

Docker should install properly on a Windows Container using the getting started instructions on https://chocolatey.org/install#individual

How Did You Get This To Happen? (Steps to Reproduce)

  1. Create a Dockerfile with the following:

    FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
    SHELL ["pwsh", "-c", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
    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://community.chocolatey.org/install.ps1'))
    
  2. Run the docker build

  3. Notice that the following message is displayed:

    Cannot bind argument to parameter 'Path' because it is an empty string.

System Details

  • Host OS Build: Windows Host 10.0.22000.0 with Docker 20.10.17
  • Dockerfile build image: mcr.microsoft.com/dotnet/sdk:6.0
  • Container OS Build: Microsoft Windows 10.0.17763
  • Windows PowerShell version: 7.2.5 (Core)
  • Chocolatey version): 1.1.0

Output Log

Full Log Output

Sending build context to Docker daemon  602.8MB
Step 1/40 : FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
 ---> 48acdf8868a2
Step 2/40 : WORKDIR /app
 ---> Using cache
 ---> 11eb5c79eca9
Step 3/40 : EXPOSE 80
 ---> Using cache
 ---> 8e792940ada3
Step 4/40 : FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
 ---> 187d361065f2
Step 5/40 : SHELL ["pwsh", "-c", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
 ---> Using cache
 ---> 969fad16a51c
Step 6/40 : 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://community.chocolatey.org/install.ps1'))
 ---> Running in 01f16d4874a5
Forcing web requests to allow TLS v1.2 (Required for requests to Chocolatey.org)
Getting latest version of the Chocolatey package for download.
Not using proxy.
Getting Chocolatey from https://community.chocolatey.org/api/v2/package/chocolatey/1.1.0.
Downloading https://community.chocolatey.org/api/v2/package/chocolatey/1.1.0 to C:\Windows\TEMP\chocolatey\chocoInstall\chocolatey.zip
Not using proxy.
Extracting C:\Windows\TEMP\chocolatey\chocoInstall\chocolatey.zip to C:\Windows\TEMP\chocolatey\chocoInstall
Installing Chocolatey on the local machine
Initialize-Chocolatey: C:\Windows\TEMP\chocolatey\chocoInstall\tools\chocolateyInstall.ps1:75
Line |
  75 |  Initialize-Chocolatey
     |  ~~~~~~~~~~~~~~~~~~~~~
     | Cannot bind argument to parameter 'Path' because it is an
     | empty string.

1 error occurred:
        * Status: The command 'pwsh -c $ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue'; 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'))' returned a non-zero code: 1, Code: 1

greggbjensen avatar Sep 15 '22 23:09 greggbjensen

I tracked down the issue in: https://github.com/chocolatey/choco/blob/b6dbc3e0b7321fe88d13403b92027292bc35936f/nuspec/chocolatey/chocolatey/tools/chocolateysetup.psm1#L128

On the mcr.microsoft.com/dotnet/sdk:6.0 docker image, Windows returns an empty string for this call. This can be resolved with the following:

    $programData = [Environment]::GetFolderPath("CommonApplicationData")
    if ([string]::IsNullOrEmpty($programData)) {
      $programData = $env:ProgramData
    }

greggbjensen avatar Sep 16 '22 15:09 greggbjensen

Thanks for getting to the bottom of that. Great work!

I tried to run it on another image I use, mcr.microsoft.com/powershell:lts-nanoserver-1809 and it also failed with the same error.

@TheCakeIsNaOH any thoughts on this?

pauby avatar Sep 16 '22 16:09 pauby

So I ran into another issue once I got past that.

$chocolateyPath: C:\ProgramData\chocolatey
Creating ChocolateyInstall as an environment variable (targeting 'Machine')
  Setting ChocolateyInstall to 'C:\ProgramData\chocolatey'
WARNING: It's very likely you will need to close and reopen your shell
  before you can use choco.
ERROR: The system cannot find registry path specified.

This one looks to be harder to track down.

greggbjensen avatar Sep 16 '22 16:09 greggbjensen

@pauby offhand, I will note that nano server is not currently supported by Chocolatey: https://github.com/chocolatey/choco/issues/1371 From what I understand, full fat .Net 4.x is not available in nano server, so Chocolatey would not run in those images.

I will dig into this more.

TheCakeIsNaOH avatar Sep 16 '22 16:09 TheCakeIsNaOH

Yeah. I tried to run it on mcr.microsoft.com/windows/servercore:ltsc2019 and got a different error. That could be entirely because it's missing something obvious (I didn't dig into it at all). So I won't add the error here to confuse things but I will dig into it a bit more too.

pauby avatar Sep 16 '22 18:09 pauby

I had this issue surface today with some older containers that did not have .NET Framework 4.8 installed. Chocolatey 2.0.0 requires .NET Framework 4.8 and will fail with the error displayed in the original post if it is not available.

I temporarily resolved it by installing the 1.x version until we can upgrade our core images. I did this by adding ARG chocolateyVersion='1.4.0' in my dockerfile as shown below...

FROM mcr.microsoft.com/powershell:7.2.2-windowsservercore-20h2 as base
ARG chocolateyVersion='1.4.0'
SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

Installing a specific version is documented here.

ryanewtaylor avatar Jun 08 '23 19:06 ryanewtaylor