使用SAM Local Invoke时无法导入app模块的问题求助
问题:SAM CLI本地测试Docker化Lambda函数时出现模块导入错误
项目信息
项目结构(执行tree -L 2输出)
. ├── Dockerfile ├── envs │ ├── dev.json │ └── prd.json ├── event.json ├── requirements.txt ├── src │ ├── app.py │ └── utils.py └── template.yml
Dockerfile内容
# Specify the base image FROM public.ecr.aws/lambda/python:3.11 AS build-stage # Install build dependencies for psutil (pyproject.toml) RUN yum install -y gcc python3-devel gcc-c++ # Set the working directory inside the container WORKDIR /app # Copy requirements.txt from the root of your project COPY requirements.txt . # Install Python dependencies without plotly to a temporary directory RUN pip3 install --no-cache-dir --upgrade pip && \ pip3 install --no-cache-dir --upgrade -r requirements.txt --target /tmp/python-deps # -------------------- Stage 2 -------------------- # Build the final stage FROM public.ecr.aws/lambda/python:3.11 AS final-stage # Remove unnecessary dependencies (optional, but recommended) RUN yum remove -y gcc python3-devel gcc-c++ && \ yum clean all # Copy the Python dependencies from the build-stage COPY --from=build-stage /tmp/python-deps /app # Copy source code COPY src /app/src # Argument to specify environment ARG ENVIRONMENT=dev ENV ENVIRONMENT=${ENVIRONMENT} # Copy the appropriate environment file based on the argument COPY envs/${ENVIRONMENT}.json /app/.env # Set the entry point for the Lambda function CMD [ "app.lambda_handler" ]
template.yml内容
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: AWS SAM template for testing Docker-based Lambda function Parameters: Environment: Type: String Description: The environment (dev or prd) Default: dev AllowedValues: [dev, prd] Globals: Function: Timeout: 180 MemorySize: 256 Resources: DockerDemo: Type: AWS::Serverless::Function Properties: CodeUri: src/ PackageType: Image ImageConfig: Command: [app.lambda_handler] Environment: Variables: ENVIRONMENT: !Ref Environment ImageUri: !Sub docker-demo:${Environment} Metadata: DockerTag: !Ref Environment DockerContext: . Dockerfile: Dockerfile DockerBuildArgs: ENVIRONMENT: !Ref Environment DockerEnvFiles: - envs/${Environment}.json
app.py内容
# Importing our utils import json import utils def lambda_handler(event : dict, context : dict) -> dict: try: env_vars = utils.load_env() utils.load_mysql(env_vars = env_vars) return { 'status' : 200, 'message' : 'Everything worked nice!' } except Exception as e: return { 'status' : 400, 'message' : f'Something went wrong: \'{e}\'' }
执行命令与错误
- 执行
sam build --use-container,构建成功。 - 执行
sam local invoke DockerDemo --event event.json,出现以下错误:
Invoking Container created from dockerdemo:dev Local image was not found. Removing rapid images for repo dockerdemo Building image.................. Using local image: dockerdemo:rapid-x86_64. START RequestId: b110d6b1-81bd-4c13-9cfe-27692c1a37b5 Version: $LATEST Traceback (most recent call last): Unable to import module 'app': No module named 'app' END RequestId: b110d6b1-81bd-4c13-9cfe-27692c1a37b5 REPORT RequestId: b110d6b1-81bd-4c13-9cfe-27692c1a37b5 Init Duration: 1.02 ms Duration: 435.02 ms Billed Duration: 436 ms Memory Size: 256 MB Max Memory Used: 256 MB {"errorMessage": "Unable to import module 'app': No module named 'app'", "errorType": "Runtime.ImportModuleError", "requestId": "b110d6b1-81bd-4c13-9cfe-27692c1a37b5", "stackTrace": []}%
环境:MacBook Pro M2(Apple Silicon芯片),无架构适配问题。
解决方案
问题根源
Lambda Python运行时默认从/var/task目录加载模块,但当前Dockerfile将代码放在/app/src目录,Python无法识别该路径下的app模块;同时template.yml中PackageType: Image与CodeUri配置存在冲突。
修复步骤
1. 调整Dockerfile,适配Lambda运行时规范
修改Dockerfile,将代码和依赖包放到Lambda默认的/var/task目录:
# Specify the base image FROM public.ecr.aws/lambda/python:3.11 AS build-stage # Install build dependencies for psutil (pyproject.toml) RUN yum install -y gcc python3-devel gcc-c++ # Set the working directory inside the container WORKDIR /app # Copy requirements.txt from the root of your project COPY requirements.txt . # Install Python dependencies without plotly to a temporary directory RUN pip3 install --no-cache-dir --upgrade pip && \ pip3 install --no-cache-dir --upgrade -r requirements.txt --target /tmp/python-deps # -------------------- Stage 2 -------------------- # Build the final stage FROM public.ecr.aws/lambda/python:3.11 AS final-stage # Remove unnecessary dependencies (optional, but recommended) RUN yum remove -y gcc python3-devel gcc-c++ && \ yum clean all # Copy Python dependencies to Lambda's default task directory COPY --from=build-stage /tmp/python-deps /var/task # Copy source code to Lambda's default task directory COPY src /var/task # Argument to specify environment ARG ENVIRONMENT=dev ENV ENVIRONMENT=${ENVIRONMENT} # Copy the appropriate environment file to task directory COPY envs/${ENVIRONMENT}.json /var/task/.env # Set the entry point for the Lambda function CMD [ "app.lambda_handler" ]
2. 修正template.yml的冲突配置
使用镜像打包时,无需指定CodeUri,简化配置:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: AWS SAM template for testing Docker-based Lambda function Parameters: Environment: Type: String Description: The environment (dev or prd) Default: dev AllowedValues: [dev, prd] Globals: Function: Timeout: 180 MemorySize: 256 Resources: DockerDemo: Type: AWS::Serverless::Function Properties: PackageType: Image Environment: Variables: ENVIRONMENT: !Ref Environment ImageUri: !Sub docker-demo:${Environment} Metadata: DockerTag: !Ref Environment DockerContext: . Dockerfile: Dockerfile DockerBuildArgs: ENVIRONMENT: !Ref Environment
3. 重新构建并测试
执行以下命令验证修复效果:
sam build --use-container sam local invoke DockerDemo --event event.json
额外说明
- Lambda Python运行时会自动将
/var/task加入Python路径,遵循此规范可避免手动配置路径的麻烦。 - 若需保留
/app目录,也可通过添加ENV PYTHONPATH=/app/src让Python找到模块,但推荐使用Lambda默认目录以减少额外配置。
内容的提问来源于stack exchange,提问作者AbdoCherry
相关产品推荐
相关产品推荐

