英文:
How to run terminal commands from AWS Lambda Python handler deployed using Docker?
问题
以下是 ChatGPT 建议的更改部分:
# 创建运行时目录
RUN mkdir -p /var/runtime
# 创建一个 shell 脚本来运行 Lambda 函数
RUN echo -e '#!/bin/sh\n/usr/local/bin/python -m awslambdaric $*' > /var/runtime/bootstrap
RUN chmod 755 /var/runtime/bootstrap
ENTRYPOINT ["/var/runtime/bootstrap"]
CMD ["app.handler"]
请尝试使用上述更改,然后构建和运行您的 Docker 容器。这些更改应该有助于解决 AWS Lambda 找不到正确入口点的问题。希望这能帮助您实现所需的功能。如果您仍然遇到问题,请提供更多详细信息以便进一步帮助。
英文:
I have an AWS Lambda docker image, where I install package named "praat" and want to call it from Python using subprocess. It fails probably due to the ENTRYPOINT, as when I changed it, I was able to run docker exec --workdir / aws-praat praat --help
after creating a Docker container. But I couldn't figure out how to still have the AWS Lambda entry point.
The following is my Dockerfile
# Define function directory
ARG FUNCTION_DIR="/function"
FROM python:buster as build-image
# Install aws-lambda-cpp build dependencies
RUN apt-get update && \
apt-get install -y \
g++ \
make \
cmake \
unzip \
libcurl4-openssl-dev \
praat
# Include global arg in this stage of the build
ARG FUNCTION_DIR
# Create function directory
RUN mkdir -p ${FUNCTION_DIR}
# Copy function code
COPY app/* ${FUNCTION_DIR}
# Install the runtime interface client
RUN pip install \
--target ${FUNCTION_DIR} \
awslambdaric
RUN pip install \
--target ${FUNCTION_DIR} \
boto3
# Multi-stage build: grab a fresh copy of the base image
FROM arm64v8/python:buster
# Include global arg in this stage of the build
ARG FUNCTION_DIR
RUN apt-get update
RUN apt-get -y install praat
# Set working directory to function root directory
WORKDIR ${FUNCTION_DIR}
# Copy in the build image dependencies
COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
CMD [ "app.handler" ]
The command I need to run is inside a function handler(event, context) in app/app.py file:
# Get file name without extension
file_name = os.path.splitext(s3_key)[0]
# Download the file from S3 to /tmp/
file_path = os.path.join(TEMPORARY_FOLDER, os.path.basename(s3_key))
s3.download_file(s3_bucket, s3_key, file_path)
# Copy the praat script, because it creates temporary files and otherwise may not run outside /tmp/
shutil.copy("analyse_csg_files_server.praat", os.path.join(TEMPORARY_FOLDER, "analyse_csg_files_server.praat"))
# Change the current working directory to /tmp/
os.chdir(TEMPORARY_FOLDER)
# Run the command
cmd = f'praat --run analyse_csg_files_server.praat \"{file_name}\"'
res = subprocess.call(cmd)
print(res)
ChatGPT suggested following change:
# Create the runtime directory
RUN mkdir -p /var/runtime
# Create a shell script to run the Lambda function
RUN echo -e '#!/bin/sh\n/usr/local/bin/python -m awslambdaric $*' > /var/runtime/bootstrap
RUN chmod 755 /var/runtime/bootstrap
ENTRYPOINT [ "/var/runtime/bootstrap" ]
CMD [ "app.handler" ]
I played around with it a bit, but could not get it to start and was getting an error RequestId: 190c1fa1-f5a5-44de-b7ed-4075769eb307 Error: fork/exec /var/runtime/bootstrap: exec format error
at AWS.
Runtime.InvalidEntrypoint
How can I achieve this functionality?
答案1
得分: 1
参考文档可以在这里找到,如果您还没有看到它:
https://docs.aws.amazon.com/lambda/latest/dg/python-image.html
您可以尝试创建一个名为 entry.sh
的脚本,如下所示:
#!/bin/sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
else
exec /usr/local/bin/python -m awslambdaric $1
fi
在 Dockerfile
中,您可以这样做:
# (可选)添加 Lambda Runtime Interface Emulator 并在 ENTRYPOINT 中使用脚本以便在本地更简单地运行
ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
COPY entry.sh /
RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
ENTRYPOINT [ "/entry.sh" ]
CMD [ "app.handler" ]
希望这能帮助您!
英文:
References to documentation can be found here if you haven't already seen it:
https://docs.aws.amazon.com/lambda/latest/dg/python-image.html
You can attempt to create an entry.sh
script looks like this:
#!/bin/sh
if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
else
exec /usr/local/bin/python -m awslambdaric $1
fi
Within the Dockerfile
you could do this:
# (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs
ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
COPY entry.sh /
RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
ENTRYPOINT [ "/entry.sh" ]
CMD [ "app.handler" ]
Hope this helps!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论