Azure / azure-functions-docker

This repo contains the base Docker images for working with azure functions
MIT License
266 stars 118 forks source link

dotnet 8.0 in-proc "System.IO.FileNotFoundException: Could not load file or assembly" #1127

Closed Miloky closed 2 months ago

Miloky commented 2 months ago

I'm having this exception when trying trying to execute even the most basic function in docker container. Any ideas how to fix it? This is working fine with .net6, or when you try to run it locally.

fail: Function.Function1[3]
      Executed 'Function1' (Failed, Id=a611e8a9-2fbf-47ea-b372-df4952777a6a, Duration=40ms)
      Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Function1
       ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

      File name: 'System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
         at FunctionApp.Function1.Run(HttpRequest req)
         at lambda_method284(Closure , Function1 , Object[] )
         at Microsoft.Azure.WebJobs.Host.Executors.MethodInvokerWithReturnValue`2.InvokeAsync(TReflected instance, Object[] arguments) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\MethodInvokerWithReturnValue.cs:line 20
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 53
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 581
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 527
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 306
         --- End of inner exception stack trace ---
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 352
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 108
fail: Host.Results[0]
      Microsoft.Azure.WebJobs.Host.FunctionInvocationException: Exception while executing function: Function1
       ---> System.IO.FileNotFoundException: Could not load file or assembly 'System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified.

      File name: 'System.Linq, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
         at FunctionApp.Function1.Run(HttpRequest req)
         at lambda_method284(Closure , Function1 , Object[] )
         at Microsoft.Azure.WebJobs.Host.Executors.MethodInvokerWithReturnValue`2.InvokeAsync(TReflected instance, Object[] arguments) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\MethodInvokerWithReturnValue.cs:line 20
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`2.InvokeAsync(Object instance, Object[] arguments) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionInvoker.cs:line 53
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.InvokeWithTimeoutAsync(IFunctionInvoker invoker, ParameterHelper parameterHelper, CancellationTokenSource timeoutTokenSource, CancellationTokenSource functionCancellationTokenSource, Boolean throwOnTimeout, TimeSpan timerInterval, IFunctionInstance instance) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 581
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithWatchersAsync(IFunctionInstanceEx instance, ParameterHelper parameterHelper, ILogger logger, CancellationTokenSource functionCancellationTokenSource) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 527
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 306
         --- End of inner exception stack trace ---
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.ExecuteWithLoggingAsync(IFunctionInstanceEx instance, FunctionStartedMessage message, FunctionInstanceLogEntry instanceLogEntry, ParameterHelper parameterHelper, ILogger logger, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 352
         at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.TryExecuteAsync(IFunctionInstance functionInstance, CancellationToken cancellationToken) in D:\a\_work\1\s\src\Microsoft.Azure.WebJobs.Host\Executors\FunctionExecutor.cs:line 108

Function1.cs

using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;

namespace FunctionApp;

public class Function1
{
  [FunctionName("Function1")]
  public IActionResult Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req)
  {
    var arr = new int[] { 1, 2, 3 };
    var maxValue = arr.Max();
    return new OkObjectResult(maxValue);
  }
}

FunctionApp.csproj

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <AzureFunctionsVersion>v4</AzureFunctionsVersion>
        <DockerFastModeProjectMountDirectory>/home/site/wwwroot</DockerFastModeProjectMountDirectory>
        <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
        <DockerfileContext>.</DockerfileContext>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="4.4.0" />
        <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.20.1" />
    </ItemGroup>
    <ItemGroup>
        <None Update="host.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
        <None Update="local.settings.json">
            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
            <CopyToPublishDirectory>Never</CopyToPublishDirectory>
        </None>
    </ItemGroup>
</Project>

host.json

{
  "version": "2.0",
  "logging": {
    "applicationInsights": {
      "samplingSettings": {
        "isEnabled": true,
        "excludedTypes": "Request"
      },
      "enableLiveMetricsFilters": true
    },
    "fileLoggingMode": "always"
  }
}

local.settings.json

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "",
        "FUNCTIONS_INPROC_NET8_ENABLED": "1",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet"
    }
}

Dockerfile

FROM mcr.microsoft.com/azure-functions/dotnet:4 AS base
WORKDIR /home/site/wwwroot
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0-alpine AS build
ARG BUILD_CONFIGURATION=Debug
WORKDIR /src
COPY ["FunctionApp.csproj", "."]
RUN dotnet restore "./FunctionApp.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./FunctionApp.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Debug
RUN dotnet publish "./FunctionApp.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /home/site/wwwroot
COPY --from=publish /app/publish .
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

docker-compose.yml

services:
  azureFunction:
    image: azurefunction
    build:
      context: .
      dockerfile: Dockerfile
      args:
        IS_CONSOLE_LOGGING_ENABLED: 'true'
    ports:
    - '7777:8080'
    environment:
      - 'ASPNETCORE_ENVIRONMENT=Development'
      - 'AZURE_FUNCTIONS_ENVIRONMENT=Development'
      - 'ASPNETCORE_URLS=http://+:8080'
      - 'FUNCTIONS_INPROC_NET8_ENABLED=1'
      - 'FUNCTIONS_WORKER_RUNTIME=dotnet'
      - 'AzureWebJobsStorage=UseDevelopmentStorage=true'

Repository with the code could be found here: https://github.com/Miloky/function-app

asos-sasamilovic commented 2 months ago

We got this working by using azure-functions/dotnet:4-dotnet8.0, how ever our security scanner is complaining about CVE-2023-45853 when we do that.

Miloky commented 2 months ago

We got this working by using azure-functions/dotnet:4-dotnet8.0, how ever our security scanner is complaining about CVE-2023-45853 when we do that.

Thank you! Updating the tag to 4-dotnet8.0 solved this issue for me. How did you come up with it? I have not seen mentions of 4-dotnet8.0 anywhere

asos-sasamilovic commented 2 months ago

It was a result of looking through pull requests on this repo and finding this one

https://github.com/Azure/azure-functions-docker/pull/1096

This mentioned something about ".NET 8 in proc changes for dedicated linux images" and this is where we found this tag - we tried it out of sheer desperation but it did work. Although we are still blocked due to the CVE for zlib (I'm not sure but this image may be using bookworm as a distro for debian instead of bullseye?)

SeppeDev commented 2 months ago

Thanks you!

Have been stuck nearly an entire day getting my in-process .NET8 function working again after an upgrade. I was using all kinds of tags but dotnet:4-dotnet8.0 did it, specifically the .0 at the end.

The error I was getting was the following (for future reference), with the same result:

Error configuring services in an external startup class. Could not load file or assembly 'Microsoft.Extensions.Configuration.Abstractions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The system cannot find the file specified.

Miloky commented 2 months ago

Closing this issue. Using azure-functions/dotnet:4-dotnet8.0 solved the issue for me.