.NET 8 AOT Minimal API部署AWS Lambda启动失败求助
.NET 8 AOT Minimal API部署AWS Lambda时缺少.deps.json文件的解决办法
问题详情
AWS新手部署.NET 8 AOT编译的Minimal API到Lambda,使用x86_64架构的.NET 8运行时,通过dotnet lambda package打包上传ZIP后,测试触发初始化错误,提示/var/task目录缺少.deps.json文件,错误日志如下:
INIT_REPORT Init Duration: 20.68 ms Phase: init Status: error Error Type: Runtime.ExitError Error: .NET binaries for Lambda function are not correctly installed in the /var/task directory of the image when the image was built. The /var/task directory is missing the required .deps.json file. Error: .NET binaries for Lambda function are not correctly installed in the /var/task directory of the image when the image was built. The /var/task directory is missing the required .deps.json file. INIT_REPORT Init Duration: 21.40 ms Phase: invoke Status: error Error Type: Runtime.ExitError START RequestId: <redacted UUID> Version: $LATEST RequestId: <redacted UUID> Error: Runtime exited with error: exit status 105
项目及Lambda名称为BasicRules,相关文件如下:
Program.cs
using Amazon.Lambda.Serialization.SystemTextJson; using BasicRules; using Microsoft.Extensions.Options; var builder = WebApplication.CreateSlimBuilder(args); builder.Services.ConfigureHttpJsonOptions(options => { options.SerializerOptions.TypeInfoResolver = CustomSerializationContext.Default; }); builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi, options => { options.Serializer = new SourceGeneratorLambdaJsonSerializer<CustomSerializationContext>(); }); var app = builder.Build(); app.MapGet("/", () => "Welcome to running AOT compiled ASP.NET Core Minimal API on AWS Lambda"); app.MapGet("/_health", () => "We are healthy"); app.MapGet("/test", () => "Test endpoint"); app.Run();
BasicRules.csproj
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles> <AWSProjectType>Lambda</AWSProjectType> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> <PublishReadyToRun>true</PublishReadyToRun> <PublishAot>true</PublishAot> <OutputType>exe</OutputType> <StripSymbols>true</StripSymbols> </PropertyGroup> <ItemGroup> <PackageReference Include="Amazon.Lambda.AspNetCoreServer.Hosting" Version="1.7.0" /> <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.1" /> <PackageReference Include="AWS.Lambda.Powertools.Logging" Version="1.5.0" /> <PackageReference Include="AWS.Lambda.Powertools.Metrics" Version="1.6.0" /> <PackageReference Include="AWS.Lambda.Powertools.Tracing" Version="1.4.0" /> <PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.7.0" /> <!-- <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />--> <!-- <PackageReference Include="Amazon.Lambda.Annotations" Version="1.2.0" />--> <!-- <PackageReference Include="Amazon.Lambda.RuntimeSupport" Version="1.10.0" />--> <!-- <PackageReference Include="AWSXRayRecorder.Core" Version="2.14.0" />--> <!-- <PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.12.0" />--> </ItemGroup> <ItemGroup> <TrimmerRootAssembly Include="Amazon.Lambda.AspNetCoreServer.Hosting"/> <TrimmerRootAssembly Include="BasicRules" /> <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Logging" /> <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Tracing" /> <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Metrics" /> <TrimmerRootAssembly Include="Amazon.Lambda.APIGatewayEvents" /> <!-- <TrimmerRootAssembly Include="Amazon.Lambda.RuntimeSupport"/> <!-- <TrimmerRootAssembly Include="AWSSDK.Core" /> <!-- <TrimmerRootAssembly Include="AWSXRayRecorder.Core" /> <!-- <TrimmerRootAssembly Include="AWSXRayRecorder.Handlers.AwsSdk" /> </ItemGroup> </Project>
注:注释内容为之前尝试添加的其他包。
aws-lambda-tools-defaults.json
{ "function-memory-size" : 1024, "configuration": "Release", "function-runtime" : "dotnet8", "function-architecture": "x86_64" }
CustomSerializerContext.cs
using System.Text.Json.Serialization; using Amazon.Lambda.APIGatewayEvents; namespace BasicRules; [JsonSerializable(typeof(APIGatewayProxyRequest))] [JsonSerializable(typeof(APIGatewayProxyResponse))] [JsonSerializable(typeof(Dictionary<string, object>))] public partial class CustomSerializationContext : JsonSerializerContext { }
解决步骤
1. 修正.csproj配置
- 跳过.deps.json检查:AOT编译的Lambda函数不需要
.deps.json,但默认运行时会检查该文件。在<PropertyGroup>中添加以下属性跳过检查:<_LambdaSkipDepsFileCheck>true</_LambdaSkipDepsFileCheck> - 禁用PublishReadyToRun:AOT与ReadyToRun不兼容,将
<PublishReadyToRun>true</PublishReadyToRun>改为<PublishReadyToRun>false</PublishReadyToRun>,或者直接删除该行。 - 移除不必要的属性:
CopyLocalLockFileAssemblies和GenerateRuntimeConfigurationFiles对AOT编译无用,可以删除这两行,避免混淆。
修改后的<PropertyGroup>示例:
<PropertyGroup> <TargetFramework>net8.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <AWSProjectType>Lambda</AWSProjectType> <PublishReadyToRun>false</PublishReadyToRun> <PublishAot>true</PublishAot> <OutputType>exe</OutputType> <StripSymbols>true</StripSymbols> <_LambdaSkipDepsFileCheck>true</_LambdaSkipDepsFileCheck> </PropertyGroup>
2. 正确打包AOT程序
使用dotnet publish直接生成符合要求的输出,替代dotnet lambda package:
dotnet publish -c Release -r linux-x64 --self-contained true /p:PublishAot=true
进入发布目录(默认路径:bin/Release/net8.0/linux-x64/publish),将目录内所有文件直接压缩为ZIP包,确保ZIP根目录包含可执行文件(BasicRules),不要将文件嵌套在子文件夹中。
3. 配置Lambda处理程序
在Lambda控制台的函数配置中,将处理程序设置为可执行文件的名称BasicRules,而非传统的命名空间.类::方法格式。
验证
解压打包后的ZIP文件,确认根目录下存在BasicRules可执行文件,无需.deps.json文件(AOT已将所有依赖编译到可执行文件中)。重新上传ZIP包并测试函数,初始化错误即可解决。
内容的提问来源于stack exchange,提问作者Hallisloak
相关产品推荐
相关产品推荐

