pythondockeraws-lambdaaws-lambda-containers

Why can't I run `from algorithm import foo` in `lambda_function.py` inside a docker container for AWS lambda function?


I'm following this tutorial to build a Docker image for an AWS lambda function that runs python 3.11.

When I run python lambda_function.py locally, it can successfully run from algorithm import foo as data_processor inside lambda_function.py at line 1.

But when I package the program into a Docker image and run it, it generates an error saying Unable to import module 'lambda_function': No module named 'algorithm'.

This is how I test the docker image in my local machine.

# start a docker container
docker run --platform linux/amd64 -p 9000:8080 my-image:latest

# Open another terminal. Then trigger the lambda function
curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'

Here's my folder structure

.
├── Dockerfile
├── algorithm
│   ├── __init__.py
│   └── foo.py
├── lambda_function.py
└── requirements.txt

And here's my Dockerfile

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

# Copy requirements.txt
COPY requirements.txt ${LAMBDA_TASK_ROOT}

RUN pip install --upgrade pip

# Install the specified packages
RUN pip install -r requirements.txt

# Copy function code
COPY lambda_function.py ${LAMBDA_TASK_ROOT}
COPY algorithm/ ${LAMBDA_TASK_ROOT}

# Set the CMD to your lambda_handler (could also be done as a parameter override outside of the Dockerfile)
CMD [ "lambda_function.lambda_handler" ]

I've checked that ${LAMBDA_TASK_ROOT} is equal to /var/task. And that sys.path contains '/var/task'.

Why can't I run from algorithm import foo as data_processor in lambda_function.py inside a docker container?

I've checked this similar question, but the answer there doesn't help.


Solution

  • By adding print("Directory listing:", os.listdir('/var/task')) before from algorithm import foo as data_processor, I found that COPY algorithm/ ${LAMBDA_TASK_ROOT} actually copies all files under algorithm/ to ${LAMBDA_TASK_ROOT}.

    I mean I can see __init__.py and foo.py under ${LAMBDA_TASK_ROOT}.

    So in order to correctly copy the folder to ${LAMBDA_TASK_ROOT}, I should write COPY algorithm ${LAMBDA_TASK_ROOT}/algorithm instead of COPY algorithm/ ${LAMBDA_TASK_ROOT} inside Dockerfile.