简体   繁体   中英

'dotnet publish' in docker not including 'runtimes' folder - .NET 5 SDK - for AWS Lambda

I'm attempting to run a Docker container on AWS Lambda. The image builds fine and I can run it without issue locally. When triggering the function in AWS, I get dependency errors. The most recent one is:

An assembly specified in the application dependencies manifest (MyProject.deps.json) was not found:
package: 'System.Drawing.Common', version: '5.0.0'
path: 'runtimes/unix/lib/netcoreapp3.0/System.Drawing.Common.dll'

Looking at the MyProject.deps.json , I indeed see a reference to this assembly, like this:

"System.Drawing.Common/5.0.0": {
        "dependencies": {
          "Microsoft.Win32.SystemEvents": "5.0.0"
        },
        "runtime": {
          "lib/netcoreapp3.0/System.Drawing.Common.dll": {
            "assemblyVersion": "5.0.0.0",
            "fileVersion": "5.0.20.51904"
          }
        },
        "runtimeTargets": {
          "runtimes/unix/lib/netcoreapp3.0/System.Drawing.Common.dll": {
            "rid": "unix",
            "assetType": "runtime",
            "assemblyVersion": "5.0.0.0",
            "fileVersion": "5.0.20.51904"
          },
          "runtimes/win/lib/netcoreapp3.0/System.Drawing.Common.dll": {
            "rid": "win",
            "assetType": "runtime",
            "assemblyVersion": "5.0.0.0",
            "fileVersion": "5.0.20.51904"
          }
        }
      },

Upon inspection of my Docker image, it seems that do.net publish is publishing everything in the runtimeTargets path except for the first folder runtimes :

  • EXPECTED: <root-of-my-app-in-docker>/runtimes/unix/lib.netcoreapp3.0/System.Drawing.Common.dll
  • ACTUAL: <root-of-my-app-in-docker>/unix/lib.netcoreapp3.0/System.Drawing.Common.dll

Why would it do this?

Running do.net publish -o publish locally generates a publish folder with the expected directory structure.

Here's my Dockerfile:

FROM public.ecr.aws/lambda/dotnet:5.0 as aws
WORKDIR /var/task


FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build

WORKDIR /src
COPY . .

WORKDIR /src/MyProject/src/MyProject
RUN dotnet restore "MyProject.csproj"
RUN dotnet build "MyProject.csproj" -c Release -o /app/build


FROM build AS publish
RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish


FROM aws as final
WORKDIR /var/task
COPY --from=publish app/publish/* ./

CMD [ "MyProject::MyProject.Function::FunctionHandler" ]

Though I haven't tried, I'm guessing I can fix this in my Dockerfile by manually copying the runtime targets to a runtimes folder that I create manually.

  • But why should I have to do this?
  • Why is do.net publish creating a manifest that refers to files that don't exist?
  • Have I missed something simply in my Dockerfile that would be causing this?

Try specifying the runtime in the publish command:

RUN dotnet publish "MyProject.csproj" -c Release -o /app/publish -r linux-x64

That will publish for that particular target runtime and not for being run generically.

If you don't specify the runtime to publish for, all runtime-dependent binaries are included in the publish folder for every supported runtime in the runtimes folder. Lambda expects binaries published for a do.net runtime the lambda runtime is built for (linux-x64). Publishing for a runtime means the appropriate runtime-dependent binaries are simply copied over and the system global runtime is responsible for providing the specifics.

Hope this helps a little.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM