You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将简易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上:

  1. 打开AWS控制台,搜ECR,进入后点“创建仓库”,给仓库起个名(比如express-lambda-app),然后创建。
  2. 进入刚创建的仓库,点“查看推送命令”,照着上面的命令在本地终端执行就行,大概是这几步(替换你的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控制台搞事情:

  1. 点“创建函数”,选择“容器镜像”选项。
  2. 函数名随便起,然后点“浏览图像”,找到刚才推到ECR的那个镜像,选中它。
  3. 执行角色选“创建新角色”,用默认的基本权限就行(能写CloudWatch日志就行)。
  4. 点“创建函数”,等个几分钟,Lambda就会把镜像拉下来准备好。

测试Lambda函数

创建完后,点“测试”标签,选“API Gateway AWS Proxy”模板,修改path/testhttpMethodGET,然后点“测试”,如果看到返回结果里有{"test":"success"},就说明部署成功了!

第五步(可选):配置API Gateway让接口能通过HTTP访问

如果想让别人用HTTP URL访问你的接口,就得整个API Gateway触发器:

  1. 在Lambda函数的“配置”标签里,点“触发器”→“添加触发器”,选“API Gateway”。
  2. 选择“创建新API”,类型选“HTTP API”,安全选项选“开放”(如果需要认证可以后续配置)。
  3. 创建完后,你会得到一个类似https://abc123.execute-api.us-east-1.amazonaws.com/test的URL,直接访问就能调用你的Express接口了。

备注:内容来源于stack exchange,提问作者user732456

火山引擎 最新活动