如何将简易Node.js Express应用通过Docker容器打包并部署到AWS Lambda?
如何将简易Node.js Express应用通过Docker容器打包并部署到AWS Lambda?
嘿,我来一步步带你把这个简易的Express应用打包成Docker镜像,再部署到AWS Lambda上——先确认下你的应用代码没问题,就是你贴的这段,我先整理好:
import express from 'express'; const app = express(); const PORT = 3712; // Middleware to parse JSON bodies app.use(express.json()); // Logger middleware app.use((req, res, next) => { console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`); next(); }); // Routes app.get('/test', (req, res) => { console.log(`${new Date().toISOString()} - Request received for /test`); res.json({ test: 'success' }); }); app.get('/hello', (req, res) => { console.log(`${new Date().toISOString()} - Request received for /hello`); res.send('hi'); }); app.post('/sendkey', (req, res) => { console.log(`${new Date().toISOString()} - Request received for /sendkey`); const { key } = req.body; res.json({ key, accepted: true }); }); // 本地运行时才启动HTTP服务器,适配Lambda环境 if (process.env.NODE_ENV !== 'production' || process.env.LAMBDA_LOCAL) { app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`); }); } export default app; // 导出应用实例给Lambda handler使用
下面开始正式操作:
第一步:准备Docker打包配置
首先得给应用配置Docker相关文件,不然没法打包镜像。
1.1 写Dockerfile
在项目根目录新建个Dockerfile,内容如下(我用AWS官方的Lambda Node.js镜像,自带Runtime Interface Emulator,省得自己折腾):
# 使用AWS官方的Node.js Lambda基础镜像,版本选和你应用匹配的,这里用18 FROM public.ecr.aws/lambda/nodejs:18 # Lambda的默认工作目录,直接用这个就行 WORKDIR ${LAMBDA_TASK_ROOT} # 先复制package文件,这样依赖安装层可以缓存,加快后续构建速度 COPY package*.json ./ # 安装应用依赖,包括适配Lambda的aws-serverless-express RUN npm install && npm install aws-serverless-express # 复制所有应用代码到容器里 COPY . . # 指定Lambda的入口handler:文件名.导出的函数名 CMD ["lambda-handler.handler"]
1.2 创建.dockerignore
同样在根目录建这个文件,避免把node_modules、日志这些没用的东西打包进去:
node_modules npm-debug.log .git .gitignore .env
1.3 写Lambda的入口handler
新建lambda-handler.js文件,把Express应用转换成Lambda能识别的handler格式:
import awsServerlessExpress from 'aws-serverless-express'; import app from './index.js'; // 导入咱们的Express应用实例 // 创建Lambda兼容的服务器 const server = awsServerlessExpress.createServer(app); // Lambda的handler函数,接收事件和上下文参数 export const handler = (event, context) => { console.log(`Received event: ${JSON.stringify(event)}`); awsServerlessExpress.proxy(server, event, context); };
第二步:本地构建并测试Docker镜像
先在本地把镜像建起来,测试下能不能正常跑:
# 构建镜像,命名为express-lambda-app docker build -t express-lambda-app . # 本地运行容器,映射端口3712,同时设置环境变量模拟本地运行 docker run -p 3712:3712 -e LAMBDA_LOCAL=true express-lambda-app
然后用curl或者浏览器访问http://localhost:3712/test,能返回{"test":"success"}就说明没问题。
第三步:把镜像推送到Amazon ECR
Lambda只能从ECR拉取容器镜像,所以得先把咱们的镜像传到ECR上:
- 打开AWS控制台,搜ECR,进入后点“创建仓库”,给仓库起个名(比如
express-lambda-app),然后创建。 - 进入刚创建的仓库,点“查看推送命令”,照着上面的命令在本地终端执行就行,大概是这几步(替换你的AWS账号ID和区域):
# 登录ECR aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com # 给镜像打标签,对应ECR仓库地址 docker tag express-lambda-app:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/express-lambda-app:latest # 推送镜像到ECR docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/express-lambda-app:latest
第四步:创建Lambda函数并部署镜像
现在去Lambda控制台搞事情:
- 点“创建函数”,选择“容器镜像”选项。
- 函数名随便起,然后点“浏览图像”,找到刚才推到ECR的那个镜像,选中它。
- 执行角色选“创建新角色”,用默认的基本权限就行(能写CloudWatch日志就行)。
- 点“创建函数”,等个几分钟,Lambda就会把镜像拉下来准备好。
测试Lambda函数
创建完后,点“测试”标签,选“API Gateway AWS Proxy”模板,修改path为/test,httpMethod为GET,然后点“测试”,如果看到返回结果里有{"test":"success"},就说明部署成功了!
第五步(可选):配置API Gateway让接口能通过HTTP访问
如果想让别人用HTTP URL访问你的接口,就得整个API Gateway触发器:
- 在Lambda函数的“配置”标签里,点“触发器”→“添加触发器”,选“API Gateway”。
- 选择“创建新API”,类型选“HTTP API”,安全选项选“开放”(如果需要认证可以后续配置)。
- 创建完后,你会得到一个类似
https://abc123.execute-api.us-east-1.amazonaws.com/test的URL,直接访问就能调用你的Express接口了。
备注:内容来源于stack exchange,提问作者user732456




