Aje*_*shy 14 python docker aws-lambda unoconv alpine-linux
我正在编写一个 Lambda 函数,使用 unoconv 和 libreoffice 将 excel 文件转换为 PDF,为此我使用 alpine 基础图像。Dockerfile 如下。
\n# Define global args\nARG FUNCTION_DIR="/home/app/"\nARG RUNTIME_VERSION="3.9"\nARG DISTRO_VERSION="3.12"\n\n# Stage 1 - bundle base image + runtime\n# Grab a fresh copy of the image and install GCC\nFROM python:${RUNTIME_VERSION}-alpine${DISTRO_VERSION} AS python-alpine\n# Install GCC (Alpine uses musl but we compile and link dependencies with GCC)\nRUN apk add --no-cache \\\n libstdc++\n\n# Stage 2 - build function and dependencies\nFROM python-alpine AS build-image\n# Install aws-lambda-cpp build dependencies\nRUN apk add --no-cache \\\n build-base \\\n libtool \\\n autoconf \\\n automake \\\n libexecinfo-dev \\\n make \\\n cmake \\\n libcurl\n# Include global args in this stage of the build\nARG FUNCTION_DIR\nARG RUNTIME_VERSION\n# Create function directory\nRUN mkdir -p ${FUNCTION_DIR}\n# Copy handler function\nCOPY app.py ${FUNCTION_DIR}\nCOPY requirements.txt ${FUNCTION_DIR}\n# Optional \xe2\x80\x93 Install the function's dependencies\nRUN python${RUNTIME_VERSION} -m pip install -r /home/app/requirements.txt --target ${FUNCTION_DIR}\n# Install Lambda Runtime Interface Client for Python\nRUN python${RUNTIME_VERSION} -m pip install awslambdaric --target ${FUNCTION_DIR}\n\n# Stage 3 - final runtime image\n# Grab a fresh copy of the Python image\nFROM python-alpine\n# Include global arg in this stage of the build\nARG FUNCTION_DIR\n# Set working directory to function root directory\nWORKDIR ${FUNCTION_DIR}\n# Copy in the built dependencies\nCOPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}\n\n#\nARG PUID=1000\nARG PGID=1000\n#\nRUN set -xe \\\n && apk add --no-cache --purge -uU \\\n curl icu-libs unzip zlib-dev musl \\\n mesa-gl mesa-dri-swrast \\\n libreoffice libreoffice-base libreoffice-lang-uk \\\n ttf-freefont ttf-opensans ttf-ubuntu-font-family ttf-inconsolata \\\n ttf-liberation ttf-dejavu \\\n libstdc++ dbus-x11 \\\n && echo "http://dl-cdn.alpinelinux.org/alpine/edge/main" >> /etc/apk/repositories \\\n && echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories \\\n && echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories \\\n && apk add --no-cache -U \\\n ttf-font-awesome ttf-mononoki ttf-hack \\\n && rm -rf /var/cache/apk/* /tmp/*\n\nRUN pip install unoconv\n\n# (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs\nADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /usr/bin/aws-lambda-rie\nCOPY entry.sh /\nRUN chmod 755 /usr/bin/aws-lambda-rie /entry.sh\nENTRYPOINT [ "/entry.sh" ]\nCMD [ "app.handler" ]\nRun Code Online (Sandbox Code Playgroud)\nEntry.sh文件内容如下。
\n#!/bin/sh\nif [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then\n exec /usr/bin/aws-lambda-rie /usr/local/bin/python -m awslambdaric $1\nelse\n exec /usr/local/bin/python -m awslambdaric $1\nfi\nRun Code Online (Sandbox Code Playgroud)\nrequirement.txt文件内容如下。
\nunotools\nunoconv\nboto3\nRun Code Online (Sandbox Code Playgroud)\napp.py文件内容如下。
\nimport sys\nimport boto3\nimport subprocess\nimport json\n\ndef handler(event, context): \n bucketname = "somebucket"\n filename = "Sample/example.xlsx"\n outputfilename = filename.rsplit('.', 1)[0] + '.pdf'\n\n s3 = boto3.client('s3')\n\n try:\n s3.download_file(bucketname, filename, "file.xlsx")\n except Exception as e:\n return str(e)\n\n try:\n result = subprocess.run(['unoconv', '-f', 'pdf', "file.xlsx"], stdout=subprocess.PIPE)\n except Exception as e:\n return str(e)\n\n try:\n with open("file.pdf", "rb") as f:\n s3.upload_fileobj(f, bucketname, outputfilename)\n except Exception as e:\n return str(e)\n\n body = {\n "message": "Converted excel to pdf" \n }\n response = {\n "statusCode": 200,\n "event": json.dumps(event),\n "body": json.dumps(body),\n "path": "app.py"\n }\n return response\nRun Code Online (Sandbox Code Playgroud)\n我构建了这个容器并在本地运行该容器,这工作没有问题。但是,当我将映像推送到 ECR 并使用新的最新映像更新函数并运行测试时,它显示此错误。
\n{\n "errorMessage": "RequestId: SOME_ID_HERE Error: fork/exec /usr/local/bin/python awslambdaric: no such file or directory",\n "errorType": "Runtime.InvalidEntrypoint"\n}\nIMAGE Launch error: fork/exec /usr/local/bin/python awslambdaric: no such file or directory Entrypoint: [/usr/local/bin/python awslambdaric] Cmd: [app.handler] WorkingDir: [/home/app/]\nRun Code Online (Sandbox Code Playgroud)\n查看错误,我认为这与架构有关。有人可以帮助我了解导致问题的原因吗?
\nAje*_*shy 54
问题在于架构,我正在 Mac Mini M1 上构建我的映像。当我通过提供 --platform=linux/amd64 选项构建映像时,错误消失了。当然,Lambda 函数中唯一可写的文件夹是 /tmp,因此,我也必须更改它才能正常工作。
小智 23
我在 M1 Pro 上遇到了同样的问题,必须使用docker buildx进行构建来解决问题。
docker buildx build --platform linux/amd64 -f ./Dockerfile -t myDockerTag .
Run Code Online (Sandbox Code Playgroud)
小智 6
对于访问此的任何人来说,问题也可能是由于该映像是在与 AWS 指定的不同的 CPU 架构上构建的。例如,如果您在 M1 上构建了映像,则必须在 lambda 映像对话框中选择arm64选项。
| 归档时间: |
|
| 查看次数: |
15677 次 |
| 最近记录: |