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

如何配置Python3.9容器镜像以实现AWS Lambda多层目录处理程序?

解决Lambda Docker部署的模块导入问题

问题背景

应用目录结构:

.
├── Dockerfile
└── app
    └── src
        └── main.py
        └── custom.py

原Dockerfile内容:

FROM public.ecr.aws/lambda/python:3.9

WORKDIR /app

COPY /app /app

RUN yum -y install gcc libmariadb-dev default-libmysqlclient-dev python-devel mysql-devel
RUN /var/lang/bin/python3.9 -m pip install --upgrade pip
RUN pip install -U poetry
RUN poetry export --only main --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt -t .

ENV PYTHONPATH="$PYTHONPATH:${LAMBDA_TASK_ROOT}"
WORKDIR ${LAMBDA_TASK_ROOT}/src
ENTRYPOINT ["/lambda-entrypoint.sh"]
CMD ["main.lambda_handler"]

触发Lambda时出现错误:

{
  "errorMessage": "Unable to import module 'main': No module named 'main'",
  "errorType": "Runtime.ImportModuleError",
  "requestId": "...",
  "stackTrace": []
}

main.py中的导入语句:

from typing import Any
from src.custom import Function

def lambda_handler(event: dict[str, Any], context: Any):
    # Function相关逻辑

错误原因

  1. 模块路径不匹配:原Dockerfile将app目录复制到/app,但Lambda默认从${LAMBDA_TASK_ROOT}(即/var/task)加载模块,导致无法找到main模块。
  2. PYTHONPATH配置不当:未将包含src目录的路径添加到Python的模块搜索路径,同时工作目录设置为${LAMBDA_TASK_ROOT}/src,进一步加剧了路径混乱。
  3. 内部模块导入路径错误:main.py中使用from src.custom import Function,但在原配置下src模块不在Python的搜索路径中。

解决方案

提供两种可行的修改方案,可根据是否允许修改代码选择:

方案一:调整目录结构与代码导入(无需复杂PYTHONPATH配置)

修改Dockerfile,将src下的内容直接复制到Lambda任务根目录,并调整代码导入为相对路径:

修改后的Dockerfile

FROM public.ecr.aws/lambda/python:3.9

# 将app/src下的所有文件复制到Lambda任务根目录(/var/task)
COPY app/src/ ${LAMBDA_TASK_ROOT}/
# 复制poetry配置文件到任务根目录(确保能导出依赖)
COPY app/pyproject.toml app/poetry.lock ${LAMBDA_TASK_ROOT}/

WORKDIR ${LAMBDA_TASK_ROOT}

# 安装系统依赖并清理缓存
RUN yum -y install gcc libmariadb-dev default-libmysqlclient-dev python-devel mysql-devel && yum clean all

# 升级pip并安装poetry
RUN /var/lang/bin/python3.9 -m pip install --upgrade pip
RUN pip install -U poetry

# 导出requirements并安装依赖到当前目录
RUN poetry export --only main --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt -t .

# 明确PYTHONPATH包含任务根目录(默认已包含,显式设置更稳妥)
ENV PYTHONPATH="${PYTHONPATH}:${LAMBDA_TASK_ROOT}"

ENTRYPOINT ["/lambda-entrypoint.sh"]
# 直接指定main模块中的lambda_handler函数
CMD ["main.lambda_handler"]

修改main.py的导入语句

将绝对导入改为相对导入(因为custom.py与main.py在同一目录):

from typing import Any
# 相对导入同目录下的custom模块
from .custom import Function

def lambda_handler(event: dict[str, Any], context: Any):
    # 业务逻辑
    return {"statusCode": 200, "body": "Success"}

方案二:保留原目录结构(无需修改代码)

通过调整PYTHONPATH和CMD模块路径,让Python能识别原目录结构中的src模块:

修改后的Dockerfile

FROM public.ecr.aws/lambda/python:3.9

# 将整个app目录复制到Lambda任务根目录下
COPY app/ ${LAMBDA_TASK_ROOT}/app
# 复制poetry配置文件到任务根目录
COPY app/pyproject.toml app/poetry.lock ${LAMBDA_TASK_ROOT}/

WORKDIR ${LAMBDA_TASK_ROOT}

# 安装系统依赖并清理缓存
RUN yum -y install gcc libmariadb-dev default-libmysqlclient-dev python-devel mysql-devel && yum clean all

# 升级pip并安装poetry
RUN /var/lang/bin/python3.9 -m pip install --upgrade pip
RUN pip install -U poetry

# 导出requirements并安装依赖到当前目录
RUN poetry export --only main --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt -t .

# 将app目录添加到PYTHONPATH,让Python能找到src模块
ENV PYTHONPATH="${PYTHONPATH}:${LAMBDA_TASK_ROOT}/app"

ENTRYPOINT ["/lambda-entrypoint.sh"]
# 指定src.main模块中的lambda_handler函数(src是顶级模块)
CMD ["src.main.lambda_handler"]

此方案下,main.py中的from src.custom import Function无需修改,因为src已被Python识别为顶级模块。


内容的提问来源于stack exchange,提问作者weekwith.me

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 01:55:35