|
| 1 | +# escape=` |
| 2 | +# Args used by from statements must be defined here: |
| 3 | +ARG InstallerVersion=nanoserver |
| 4 | +ARG InstallerRepo=mcr.microsoft.com/powershell |
| 5 | +ARG NanoServerRepo=mcr.microsoft.com/windows/nanoserver |
| 6 | + |
| 7 | +# Use server core as an installer container to extract PowerShell, |
| 8 | +# As this is a multi-stage build, this stage will eventually be thrown away |
| 9 | +FROM ${InstallerRepo}:$InstallerVersion AS installer-env |
| 10 | + |
| 11 | +# Arguments for installing PowerShell, must be defined in the container they are used |
| 12 | +ARG PS_VERSION=7.0.0-rc.1 |
| 13 | + |
| 14 | +ARG PS_PACKAGE_URL=https://github.com/PowerShell/PowerShell/releases/download/v$PS_VERSION/PowerShell-$PS_VERSION-win-x64.zip |
| 15 | + |
| 16 | +# disable telemetry |
| 17 | +ENV POWERSHELL_TELEMETRY_OPTOUT="1" |
| 18 | + |
| 19 | +SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] |
| 20 | + |
| 21 | +ARG PS_PACKAGE_URL_BASE64 |
| 22 | + |
| 23 | +RUN Write-host "Verifying valid Version..."; ` |
| 24 | + if (!($env:PS_VERSION -match '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$' )) { ` |
| 25 | + throw ('PS_Version ({0}) must match the regex "^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$"' -f $env:PS_VERSION) ` |
| 26 | + } ` |
| 27 | + $ProgressPreference = 'SilentlyContinue'; ` |
| 28 | + if($env:PS_PACKAGE_URL_BASE64){ ` |
| 29 | + Write-host "decoding: $env:PS_PACKAGE_URL_BASE64" ;` |
| 30 | + $url = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($env:PS_PACKAGE_URL_BASE64)) ` |
| 31 | + } else { ` |
| 32 | + Write-host "using url: $env:PS_PACKAGE_URL" ;` |
| 33 | + $url = $env:PS_PACKAGE_URL ` |
| 34 | + } ` |
| 35 | + Write-host "downloading: $url"; ` |
| 36 | + [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12; ` |
| 37 | + New-Item -ItemType Directory /installer > $null ; ` |
| 38 | + Invoke-WebRequest -Uri $url -outfile /installer/powershell.zip -verbose; ` |
| 39 | + Expand-Archive /installer/powershell.zip -DestinationPath \PowerShell |
| 40 | + |
| 41 | +# Install PowerShell into NanoServer |
| 42 | +FROM ${NanoServerRepo}:20H2 |
| 43 | + |
| 44 | +ARG IMAGE_NAME=mcr.microsoft.com/powershell |
| 45 | + |
| 46 | +# Copy PowerShell Core from the installer container |
| 47 | +ENV ProgramFiles="C:\Program Files" ` |
| 48 | + # set a fixed location for the Module analysis cache |
| 49 | + PSModuleAnalysisCachePath="C:\Users\Public\AppData\Local\Microsoft\Windows\PowerShell\docker\ModuleAnalysisCache" ` |
| 50 | + # Persist %PSCORE% ENV variable for user convenience |
| 51 | + PSCORE="$ProgramFiles\PowerShell\pwsh.exe" ` |
| 52 | + # Set the default windows path so we can use it |
| 53 | + WindowsPATH="C:\Windows\system32;C:\Windows" ` |
| 54 | + POWERSHELL_DISTRIBUTION_CHANNEL="PSDocker-NanoServer-20H2" |
| 55 | + |
| 56 | +### Begin workaround ### |
| 57 | +# Note that changing user on nanoserver is not recommended |
| 58 | +# See, https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-containers/container-base-images#base-image-differences |
| 59 | +# But we are working around a bug introduced in the nanoserver image introduced in 1809 |
| 60 | +# Without this, PowerShell Direct will fail |
| 61 | +# this command sholud be like this: https://github.com/PowerShell/PowerShell-Docker/blob/f81009c42c96af46aef81eb1515efae0ef29ad5f/release/preview/nanoserver/docker/Dockerfile#L76 |
| 62 | +USER ContainerAdministrator |
| 63 | + |
| 64 | +# This is basically the correct code except for the /M |
| 65 | +RUN setx PATH "%PATH%;%ProgramFiles%\PowerShell;" /M |
| 66 | + |
| 67 | +USER ContainerUser |
| 68 | +### End workaround ### |
| 69 | + |
| 70 | +COPY --from=installer-env ["\\PowerShell\\", "$ProgramFiles\\PowerShell"] |
| 71 | + |
| 72 | +# intialize powershell module cache |
| 73 | +RUN pwsh ` |
| 74 | + -NoLogo ` |
| 75 | + -NoProfile ` |
| 76 | + -Command " ` |
| 77 | + $stopTime = (get-date).AddMinutes(15); ` |
| 78 | + $ErrorActionPreference = 'Stop' ; ` |
| 79 | + $ProgressPreference = 'SilentlyContinue' ; ` |
| 80 | + while(!(Test-Path -Path $env:PSModuleAnalysisCachePath)) { ` |
| 81 | + Write-Host "'Waiting for $env:PSModuleAnalysisCachePath'" ; ` |
| 82 | + if((get-date) -gt $stopTime) { throw 'timout expired'} ` |
| 83 | + Start-Sleep -Seconds 6 ; ` |
| 84 | + }" |
| 85 | + |
| 86 | +# re-enable telemetry |
| 87 | +ENV POWERSHELL_TELEMETRY_OPTOUT="0" |
| 88 | + |
| 89 | +CMD ["pwsh.exe"] |
0 commit comments