如何用SAM CLI、AWS CLI和Docker本地开发部署NestJS Lambda函数
无Serverless框架:用SAM CLI部署NestJS Lambda到AWS
以下是不依赖Serverless框架,仅用SAM CLI、AWS CLI和Docker完成从本地创建到部署的完整流程:
1. 初始化NestJS项目并添加路由
先搭建基础NestJS项目,创建两个测试路由:
# 全局安装Nest CLI(未安装时执行) npm i -g @nestjs/cli # 创建项目 nest new nestjs-lambda-sam cd nestjs-lambda-sam
修改src/app.controller.ts添加两个路由:
import { Controller, Get } from '@nestjs/common'; import { AppService } from './app.service'; @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Get('hello') getHello(): string { return this.appService.getHello(); } @Get('status') getSystemStatus(): { status: string; timestamp: number } { return { status: 'healthy', timestamp: Date.now() }; } }
2. 适配NestJS到Lambda运行环境
Lambda需要特定入口处理AWS事件,直接用NestJS的Express适配器配合AWS Lambda类型:
# 安装依赖 npm install @nestjs/platform-express aws-lambda @types/aws-lambda --save
在项目根目录创建lambda.ts作为Lambda入口文件:
import { NestFactory } from '@nestjs/core'; import { ExpressAdapter } from '@nestjs/platform-express'; import { AppModule } from './src/app.module'; import * as express from 'express'; import { Handler, Context, APIGatewayProxyEvent } from 'aws-lambda'; const expressApp = express(); const adapter = new ExpressAdapter(expressApp); // 缓存NestJS实例,避免冷启动重复初始化 let cachedHandler: Handler; async function bootstrap() { const app = await NestFactory.create(AppModule, adapter); app.enableCors(); await app.init(); return expressApp; } export const handler: Handler = async (event: APIGatewayProxyEvent, context: Context) => { if (!cachedHandler) { const server = await bootstrap(); cachedHandler = server; } return cachedHandler(event, context); };
3. 编写SAM模板(template.yaml)
在项目根目录创建SAM配置文件,定义Lambda函数和API Gateway:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: NestJS Lambda deployed via SAM (no Serverless Framework) Resources: NestJSLambda: Type: AWS::Serverless::Function Properties: CodeUri: ./dist/ Handler: lambda.handler Runtime: nodejs20.x MemorySize: 256 Timeout: 15 Events: ApiGatewayProxy: Type: Api Properties: Path: /{proxy+} Method: ANY Outputs: ApiEndpoint: Description: API Gateway endpoint URL Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
4. 配置打包脚本
修改package.json的scripts字段,添加打包命令,确保编译后的代码包含生产依赖:
{ "scripts": { "build": "nest build && cp package.json dist/ && cp yarn.lock dist/ && cd dist && yarn install --production --frozen-lockfile" } }
若使用npm,将yarn命令替换为npm install --production。
5. 本地测试(依赖Docker)
确保Docker正在运行,执行以下步骤:
# 构建项目 npm run build # 用SAM本地启动API网关 sam local start-api
测试路由:
curl http://localhost:3000/hello curl http://localhost:3000/status
6. 部署到AWS
确保AWS CLI已配置有效凭证(执行aws configure完成配置),然后执行SAM部署:
sam deploy --guided
按照向导提示输入:
- 栈名称(例如
nestjs-lambda-sam-stack) - AWS区域(例如
us-east-1) - 确认部署变更等
部署完成后,控制台会输出API Gateway的访问地址,可用于测试线上的NestJS Lambda。
关键注意事项
- 确保Lambda运行时版本(例如
nodejs20.x)与本地Node.js版本一致,避免兼容性问题 - 本地测试时,SAM依赖Docker模拟Lambda环境,必须启动Docker
- 打包时仅包含生产依赖,减小Lambda包体积,提升冷启动速度
内容的提问来源于stack exchange,提问作者Aniket Lodh
相关产品推荐
相关产品推荐

