如何从使用Docker部署的AWS Lambda Python处理程序运行终端命令?

huangapple go评论106阅读模式
英文:

How to run terminal commands from AWS Lambda Python handler deployed using Docker?

问题

以下是 ChatGPT 建议的更改部分:

  1. # 创建运行时目录
  2. RUN mkdir -p /var/runtime
  3. # 创建一个 shell 脚本来运行 Lambda 函数
  4. RUN echo -e '#!/bin/sh\n/usr/local/bin/python -m awslambdaric $*' > /var/runtime/bootstrap
  5. RUN chmod 755 /var/runtime/bootstrap
  6. ENTRYPOINT ["/var/runtime/bootstrap"]
  7. 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

  1. # Define function directory
  2. ARG FUNCTION_DIR="/function"
  3. FROM python:buster as build-image
  4. # Install aws-lambda-cpp build dependencies
  5. RUN apt-get update && \
  6. apt-get install -y \
  7. g++ \
  8. make \
  9. cmake \
  10. unzip \
  11. libcurl4-openssl-dev \
  12. praat
  13. # Include global arg in this stage of the build
  14. ARG FUNCTION_DIR
  15. # Create function directory
  16. RUN mkdir -p ${FUNCTION_DIR}
  17. # Copy function code
  18. COPY app/* ${FUNCTION_DIR}
  19. # Install the runtime interface client
  20. RUN pip install \
  21. --target ${FUNCTION_DIR} \
  22. awslambdaric
  23. RUN pip install \
  24. --target ${FUNCTION_DIR} \
  25. boto3
  26. # Multi-stage build: grab a fresh copy of the base image
  27. FROM arm64v8/python:buster
  28. # Include global arg in this stage of the build
  29. ARG FUNCTION_DIR
  30. RUN apt-get update
  31. RUN apt-get -y install praat
  32. # Set working directory to function root directory
  33. WORKDIR ${FUNCTION_DIR}
  34. # Copy in the build image dependencies
  35. COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
  36. ENTRYPOINT [ "/usr/local/bin/python", "-m", "awslambdaric" ]
  37. CMD [ "app.handler" ]

The command I need to run is inside a function handler(event, context) in app/app.py file:

  1. # Get file name without extension
  2. file_name = os.path.splitext(s3_key)[0]
  3. # Download the file from S3 to /tmp/
  4. file_path = os.path.join(TEMPORARY_FOLDER, os.path.basename(s3_key))
  5. s3.download_file(s3_bucket, s3_key, file_path)
  6. # Copy the praat script, because it creates temporary files and otherwise may not run outside /tmp/
  7. shutil.copy("analyse_csg_files_server.praat", os.path.join(TEMPORARY_FOLDER, "analyse_csg_files_server.praat"))
  8. # Change the current working directory to /tmp/
  9. os.chdir(TEMPORARY_FOLDER)
  10. # Run the command
  11. cmd = f'praat --run analyse_csg_files_server.praat \"{file_name}\"'
  12. res = subprocess.call(cmd)
  13. print(res)

ChatGPT suggested following change:

  1. # Create the runtime directory
  2. RUN mkdir -p /var/runtime
  3. # Create a shell script to run the Lambda function
  4. RUN echo -e '#!/bin/sh\n/usr/local/bin/python -m awslambdaric $*' > /var/runtime/bootstrap
  5. RUN chmod 755 /var/runtime/bootstrap
  6. ENTRYPOINT [ "/var/runtime/bootstrap" ]
  7. 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
Runtime.InvalidEntrypoint
at AWS.

How can I achieve this functionality?

答案1

得分: 1

参考文档可以在这里找到,如果您还没有看到它:
https://docs.aws.amazon.com/lambda/latest/dg/python-image.html

您可以尝试创建一个名为 entry.sh 的脚本,如下所示:

  1. #!/bin/sh
  2. if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
  3. exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
  4. else
  5. exec /usr/local/bin/python -m awslambdaric $1
  6. fi

Dockerfile 中,您可以这样做:

  1. # (可选)添加 Lambda Runtime Interface Emulator 并在 ENTRYPOINT 中使用脚本以便在本地更简单地运行
  2. ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
  3. COPY entry.sh /
  4. RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
  5. ENTRYPOINT [ "/entry.sh" ]
  6. 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:

  1. #!/bin/sh
  2. if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
  3. exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1
  4. else
  5. exec /usr/local/bin/python -m awslambdaric $1
  6. fi

Within the Dockerfile you could do this:

  1. # (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs
  2. ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie
  3. COPY entry.sh /
  4. RUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh
  5. ENTRYPOINT [ "/entry.sh" ]
  6. CMD [ "app.handler" ]

Hope this helps!

huangapple
  • 本文由 发表于 2023年5月29日 18:11:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356441.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定