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.
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.