I have Docker and Azure Function Core Tools v2 installed on my local Windows 2019 server. I want to use Windows Hyper-v container running some Azure Functions on my local machine. As mentioned in this doc, func init MyFunctionProj --docker will generate a Dockerfile to build the Linux custom container. Is there a way to create a Windows custom image (e.g. modify the Dockerfile)? If so, what would be the proper way to do that? Thank you.
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
Hi @helloguo Thank you for your feedback! We will review and update as appropriate.
@helloguo Though not documented as such, in theory this should work.
So I went ahead and tried it out myself. 😄
Like you have already thought of, the Dockerfile would have to be updated accordingly. Here is what I finally end up with after getting it to work
# escape=`
# This is the same tag for the windows container too
FROM microsoft/dotnet:2.1-sdk AS installer-env
# Change these commands accordingly for Windows
COPY . C:/src/dotnet-function-app
RUN cd C:\\src\\dotnet-function-app; `
mkdir C:\\approot; `
dotnet publish --output C:\\approot
# Use the Windows Container instead
FROM mcr.microsoft.com/azure-functions/dotnet:2.0-nanoserver-1809
# Use the default AzureWebJobsScriptRoot folder for the Windows Container instead
COPY --from=installer-env ["C:\\approot", "C:\\approot"]
Here is a doc that talks about writing dockerfiles specifically for Windows, in case you were wondering about the # escape=` line.
Finally, since you are on Windows Server, you will have to use the --isolation=hyperv parameter with your docker run command like below
docker run -it --isolation=hyperv --rm -p 7071:80 <container-tag>
@helloguo getting below error every time while deploying the image is there any way to do it on local.
This is the example I tried is from Microsoft Ml tutorial
If so, what would be the proper way to do that? Thank you.
@abhijitdalavi You can open an issue at the bottom of the doc that you linked for better visibility and it may help others who are facing the same problem.
@helloguo Just following up... Hope my comment earlier helps.
@helloguo Since we have not heard back from you we will now proceed to close this thread. If there are further questions regarding this matter, please tag me in your reply. We will gladly continue the discussion and we will reopen the issue.
This was definitely helpful. I was able to tweak to work on server 2016 containers as well.
I took the Docker file from here:
https://github.com/Azure/azure-functions-docker/blob/master/host/2.0/nanoserver-1709/Dockerfile
And tweaked it slightly so that it now looks like this:
# Installer image
FROM microsoft/windowsservercore:ltsc2016 AS installer-env
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Retrieve .NET Core SDK
ENV DOTNET_SDK_VERSION=2.1.403
RUN Invoke-WebRequest -OutFile dotnet.zip https://dotnetcli.blob.core.windows.net/dotnet/Sdk/$Env:DOTNET_SDK_VERSION/dotnet-sdk-$Env:DOTNET_SDK_VERSION-win-x64.zip; `
$dotnet_sha512 = '52bb1117f170587eaceec1f78cdc41a41d4272154b5535bf61c86bfb75287323cac248434b05eabe4bc7716facabdb0f6475015cbb63f38d91af662618a06720'; `
if ((Get-FileHash dotnet.zip -Algorithm sha512).Hash -ne $dotnet_sha512) { `
Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
exit 1; `
}; `
`
Expand-Archive dotnet.zip -DestinationPath $Env:ProgramFiles\dotnet; `
Remove-Item -Force dotnet.zip; `
setx /M PATH $($Env:PATH + ';' + $Env:ProgramFiles + '\dotnet')
ENV PublishWithAspNetCoreTargetManifest=false `
NUGET_XMLDOC_MODE=skip `
HOST_COMMIT=dev `
BUILD_NUMBER=12134
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; `
Invoke-WebRequest -OutFile host.zip https://github.com/Azure/azure-functions-host/archive/$Env:HOST_COMMIT.zip; `
Expand-Archive host.zip .; `
cd azure-functions-host-$Env:HOST_COMMIT; `
dotnet publish /p:BuildNumber=$Env:BUILD_NUMBER /p:CommitHash=$Env:HOST_COMMIT src\WebJobs.Script.WebHost\WebJobs.Script.WebHost.csproj --output C:\runtime
# Runtime image
FROM microsoft/dotnet:2.1-aspnetcore-runtime-nanoserver-sac2016
COPY --from=installer-env ["C:\\runtime", "C:\\runtime"]
ENV AzureWebJobsScriptRoot=C:\approot
ENV WEBSITE_HOSTNAME=localhost:80
# Change these commands accordingly for Windows
COPY . C:/src/dotnet-function-app
RUN cd C:\\src\\dotnet-function-app; `
mkdir C:\\approot; `
dotnet publish --output C:\\approot
CMD ["dotnet", "C:\\runtime\\Microsoft.Azure.WebJobs.Script.WebHost.dll"]`
I published that image to an azure container registry and now my functions docker file looks like this:
# escape=`
# This is the same tag for the windows container too
FROM microsoft/dotnet:2.1-sdk AS installer-env
# Change these commands accordingly for Windows
COPY . C:/src/dotnet-function-app
RUN cd C:\\src\\dotnet-function-app; `
mkdir C:\\approot; `
dotnet publish --output C:\\approot
# Use the Windows Container instead
FROM <azure container registry>/dev/functions-poc:v1.0.0
# Use the default AzureWebJobsScriptRoot folder for the Windows Container instead
COPY --from=installer-env ["C:\\approot", "C:\\approot"]
Most helpful comment
@helloguo Though not documented as such, in theory this should work.
So I went ahead and tried it out myself. 😄
Like you have already thought of, the
Dockerfilewould have to be updated accordingly. Here is what I finally end up with after getting it to workHere is a doc that talks about writing dockerfiles specifically for Windows, in case you were wondering about the
# escape=`line.Finally, since you are on Windows Server, you will have to use the
--isolation=hypervparameter with yourdocker runcommand like below