Azure-docs: Is there a way to build a Windows container custom image?

Created on 18 Dec 2018  Â·  7Comments  Â·  Source: MicrosoftDocs/azure-docs

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.


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

azure-functionsvc cxp product-question triaged

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 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>

All 7 comments

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

issue

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"]
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Agazoth picture Agazoth  Â·  3Comments

spottedmahn picture spottedmahn  Â·  3Comments

spottedmahn picture spottedmahn  Â·  3Comments

AronT-TLV picture AronT-TLV  Â·  3Comments

DeepPuddles picture DeepPuddles  Â·  3Comments