微軟官方 asp.net core 的image 其實是base 在 nano server上(https://github.com/dotnet/dotnet-docker/blob/master/2.2/runtime/nanoserver-1809/amd64/Dockerfile)
而nano server 為了縮小體積早就己經移除powershell。但是powershell是個好東西,沒有powershell對我們要做一些客製的行為很麻煩,所以才會想怎麼才能加回來。
其實也沒什麼密訣,現在微軟都把官方image的DockerFile 都放在Github上了,找到官方powershell image 的 Github,看一下人家怎麼做照做就是了
原理就是先找一個有powershell的image ,下載powershell core (註)裝起來後再Copy到 nano server 上
以下是我的DockerFile
# escape=`
FROM mcr.microsoft.com/windows/servercore:ltsc2019 AS installer-env
ARG PS_VERSION=6.2.0
ARG PS_PACKAGE_URL=https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/PowerShell-${PS_VERSION}-win-x64.zip
SHELL ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "-command"]
ARG PS_PACKAGE_URL_BASE64
RUN Write-host "Verifying valid Version..."; `
if (!($env:PS_VERSION -match '^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$' )) { `
throw ('PS_Version ({0}) must match the regex "^\d+\.\d+\.\d+(-\w+(\.\d+)?)?$"' -f $env:PS_VERSION) `
} `
$ProgressPreference = 'SilentlyContinue'; `
if($env:PS_PACKAGE_URL_BASE64){ `
Write-host "decoding: $env:PS_PACKAGE_URL_BASE64" ;`
$url = [System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String($env:PS_PACKAGE_URL_BASE64)) `
} else { `
Write-host "using url: $env:PS_PACKAGE_URL" ;`
$url = $env:PS_PACKAGE_URL `
} `
Write-host "downloading: $url"; `
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12; `
Invoke-WebRequest -Uri $url -outfile /powershell.zip -verbose; `
Expand-Archive powershell.zip -DestinationPath \PowerShell
# 裝到asp.net core 2.2 runtime 的 image上
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
# Copy PowerShell Core from the installer container
ENV ProgramFiles="C:\Program Files" `
# set a fixed location for the Module analysis cache
LOCALAPPDATA="C:\Users\ContainerAdministrator\AppData\Local" `
PSModuleAnalysisCachePath="$LOCALAPPDATA\Microsoft\Windows\PowerShell\docker\ModuleAnalysisCache" `
# Persist %PSCORE% ENV variable for user convenience
PSCORE="$ProgramFiles\PowerShell\pwsh.exe"
# Copy PowerShell Core from the installer container
COPY --from=installer-env ["\\PowerShell\\", "$ProgramFiles\\PowerShell\\latest"]
# Set the path 這裡要注意一下,setx /M 需要管理者的權限,
# 但原本的身分是ContainerUser,所以需要先切換身分到ContainerAdministrator ,設完再切回來
USER ContainerAdministrator
RUN setx /M PATH "%ProgramFiles%\PowerShell\latest;%PATH%;"
USER ContainerUser
# intialize powershell module cache
RUN pwsh `
-NoLogo `
-NoProfile `
-Command " `
$stopTime = (get-date).AddMinutes(15); `
$ErrorActionPreference = 'Stop' ; `
$ProgressPreference = 'SilentlyContinue' ; `
while(!(Test-Path -Path $env:PSModuleAnalysisCachePath)) { `
Write-Host "'Waiting for $env:PSModuleAnalysisCachePath'" ; `
if((get-date) -gt $stopTime) { throw 'timout expired'} `
Start-Sleep -Seconds 6 ; `
}"
P.S. 新版的powershell ,己經可以跨平台了,並且改名叫 powershell core 了,而且執行檔名稱也改叫 pwsh.exe,不再是 powershell.exe
沒有留言:
張貼留言