如何在Docker Compose中运行本地AWS Lambda容器并解决调用报错
问题:本地AWS Lambda模拟器调用报错
Failed to reserve: AlreadyReserved 背景需求
想要搭建本地AWS Lambda服务模拟器,无需自定义客户端即可测试集成。现有仓库结构如下:
| lambda-service-emulator/ ---| app.py ---| Dockerfile | lambda-function/ ---| Dockerfile | docker-compose.yml
lambda-service-emulator/app.py(FastAPI模拟Lambda服务)
from fastapi import FastAPI, Body, Header import os import requests app = FastAPI() @app.post("/2015-03-31/functions/{function_name}/invocations") def invoke_lambda( function_name: str, payload: dict = Body({}) ): f_endpoint = os.environ['FUNCTION_ENDPOINT'] r = requests.post(f'{f_endpoint}/2015-03-31/functions/function/invocations', json=payload) try: data = r.json() except Exception: return { 'statusCode': 400 } return data
lambda-function/Dockerfile(兼容AWS Lambda的镜像)
FROM public.ecr.aws/lambda/provided as runtime # installing stuff CMD ["handler.handler"]
docker-compose.yml配置
version: '3.8' services: lambda-service: build: ./lambda-service-emulator ports: - 8081:8080 environment: FUNCTION_ENDPOINT: http://lambda-function:8080 lambda-function: volumes: - ./lambda-function:/var/task build: ./lambda-function ports: - 8082:8080
问题现象
通过Docker Compose调用Lambda时,代码能正常执行,但返回响应前出现报错:
[ERROR] (rapid) Failed to reserve: AlreadyReserved
官方Lambda镜像不适合持续运行,应每次调用后销毁容器,但不清楚如何在现有Compose结构下实现。已知按官方文档以一次性容器运行时无异常。
解决方案
核心思路
AWS Lambda官方的public.ecr.aws/lambda/provided镜像基于Rapid运行时设计,天生适配单次请求触发、执行后销毁的场景,持续运行会触发资源占用冲突。因此需要修改模拟器逻辑,每次调用时动态启动一次性Lambda容器,执行完成后立即销毁。
修改步骤
更新lambda-service-emulator/app.py
移除固定容器请求逻辑,改用Docker API动态创建并管理Lambda容器:from fastapi import FastAPI, Body import docker import json import os app = FastAPI() client = docker.from_env() @app.post("/2015-03-31/functions/{function_name}/invocations") def invoke_lambda(function_name: str, payload: dict = Body({})): # 将请求 payload 写入临时文件(模拟Lambda事件输入) with open("/tmp/event.json", "w") as f: json.dump(payload, f) # 动态启动Lambda函数容器,挂载本地代码与临时事件文件 container = client.containers.run( "lambda-function-image", # 预构建的Lambda函数镜像名 volumes={ f"{os.getcwd()}/lambda-function": {"bind": "/var/task", "mode": "ro"}, "/tmp": {"bind": "/tmp", "mode": "rw"} }, environment={ "AWS_LAMBDA_FUNCTION_NAME": function_name, "LAMBDA_EVENT_FILE": "/tmp/event.json" }, detach=True, network="lambda-emulator_default" # 关联Compose默认网络 ) # 等待容器执行完成并获取输出日志 container.wait() logs = container.logs().decode("utf-8") # 解析Lambda返回结果(Lambda函数需将输出打印到stdout) try: result = json.loads(logs) except json.JSONDecodeError: result = {"statusCode": 500, "body": logs} # 销毁容器 container.remove() return result调整docker-compose.yml
仅保留lambda-service服务,移除常驻的lambda-function服务:version: '3.8' services: lambda-service: build: ./lambda-service-emulator ports: - 8081:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock # 挂载Docker套接字,允许容器调用宿主机Docker API - /tmp:/tmp # 共享临时目录传递事件数据预构建Lambda函数镜像
启动模拟器前,先手动构建Lambda函数镜像:docker build -t lambda-function-image ./lambda-function
原理说明
- 通过挂载Docker套接字,让FastAPI服务能在容器内调用宿主机的Docker API,实现动态创建/销毁Lambda容器。
- 每次调用生成全新Lambda容器,执行完成后立即销毁,完全匹配AWS Lambda的运行模式,彻底避免Rapid运行时的资源冲突问题。
内容的提问来源于stack exchange,提问作者Mojimi
相关产品推荐
相关产品推荐

