You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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容器,执行完成后立即销毁。

修改步骤

  1. 更新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
    
  2. 调整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  # 共享临时目录传递事件数据
    
  3. 预构建Lambda函数镜像
    启动模拟器前,先手动构建Lambda函数镜像:

    docker build -t lambda-function-image ./lambda-function
    

原理说明

  • 通过挂载Docker套接字,让FastAPI服务能在容器内调用宿主机的Docker API,实现动态创建/销毁Lambda容器。
  • 每次调用生成全新Lambda容器,执行完成后立即销毁,完全匹配AWS Lambda的运行模式,彻底避免Rapid运行时的资源冲突问题。

内容的提问来源于stack exchange,提问作者Mojimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:31