【问题标题】:Can't build zip file for AWS lambda using Linux Alpine docker无法使用 Linux Alpine docker 为 AWS lambda 构建 zip 文件
【发布时间】:2021-11-23 20:49:18
【问题描述】:

我有基于 Alpine linux 的 Dockerfile,它为 AWS Lambda 构建 lambda.zip 文件。 这是 Dockerfile:

FROM alpine:3.12

# -- Install OS packages:
RUN apk add gcc
RUN apk add --update --no-cache \
    bash \
    build-base \
    cargo \
    curl \
    docker \
    # gcc \
    git \
    g++ \
    lftp \
    libc-dev \
    libffi-dev \
    libsodium-dev \
    libxslt-dev\
    libzmq \ 
    zeromq-dev \
    make \
    musl-dev \
    ncftp \
    nodejs \
    npm \
    openssh-client \
    openssl \
    openssl-dev \
    rsync \
    su-exec \
    tar \
    wget \
    zip 
# geos \ 
# geos-dev \
# libc-dev 

WORKDIR /tmp/

RUN echo "http://mirror.leaseweb.com/alpine/edge/community" >> /etc/apk/repositories
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories
RUN apk add --virtual .build-deps \
    --repository http://dl-cdn.alpinelinux.org/alpine/edge/community \
    --repository http://dl-cdn.alpinelinux.org/alpine/edge/main \
    libc-dev geos-dev geos && \
    runDeps="$(scanelf --needed --nobanner --recursive /usr/local \
    | awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
    | xargs -r apk info --installed \
    | sort -u)" && \
    apk add --virtual .rundeps $runDeps

RUN geos-config --cflags

# -- Install python:
RUN apk add --update --no-cache python3-dev python3 \
    && python3 -m ensurepip --upgrade \
    && pip3 install --upgrade pip pipenv setuptools docker-compose awscli shapely wheel \
    && rm -r /usr/lib/python*/ensurepip  \
    && if [ ! -e /usr/bin/pip ]; then ln -s pip3 /usr/bin/pip ; fi \
    && if [[ ! -e /usr/bin/python ]]; then ln

这是适用于 docker Alpine 映像并构建 lambda.zip 的脚本,其中包含 python 文件和所有需要的依赖项,如 boto3、pip、6 等。

 
#!/bin/bash

set -x
set -e

pipenv install
rm -rf lambda.zip

VENV=$(pipenv --venv)
TEMPDIR=$(mktemp -d)

rsync -r --progress ./* ${TEMPDIR}
rsync -r --progress ${VENV}/lib/python3.8/site-packages/* ${TEMPDIR}

pushd ${TEMPDIR}
zip -r lambda.zip ./*
popd

cp ${TEMPDIR}/lambda.zip ./

cleanup() {
    rm -rf ${TEMPDIR}
}

trap cleanup EXIT

然后我将这个 lambda.zip 复制到我的本地机器,解压缩并在我的本地机器上启用 pipenv 以仅使用 lambda.zip 中的包,然后我尝试测试 Shapely 包,例如 test.py:

from shapely.geometry import Polygon
print(Polygon([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]]).minimum_clearance)

在 AWS lambda 和我的本地机器上,我在 geos_c 之后遇到了同样的错误:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    from shapely.geometry import Polygon
  File "/home/stark/code/job/lamba_python_312_stack/shapely/geometry/__init__.py", line 4, in <module>
    from .base import CAP_STYLE, JOIN_STYLE
  File "/home/stark/code/job/lamba_python_312_stack/shapely/geometry/base.py", line 19, in <module>
    from shapely.coords import CoordinateSequence
  File "/home/stark/code/job/lamba_python_312_stack/shapely/coords.py", line 8, in <module>
    from shapely.geos import lgeos
  File "/home/stark/code/job/lamba_python_312_stack/shapely/geos.py", line 87, in <module>
    _lgeos = load_dll('geos_c', fallbacks=alt_paths)
  File "/home/stark/code/job/lamba_python_312_stack/shapely/geos.py", line 60, in load_dll
    raise OSError(
OSError: Could not find lib geos_c or load any of its variants ['libgeos_c.so.1', 'libgeos_c.so'].

如果我解压缩文件,我会得到如下内容:

@user# ls

iohttp
aiohttp-3.7.4.post0.dist-info
attr
attrs-21.2.0.dist-info
boto3
boto3-1.18.38.dist-info
botocore
cron_runner.py
setuptools-58.0.4.virtualenv
shapely
Shapely-1.7.1.dist-info
...
xmltodict.py
yarl
yarl-1.6.3.dist-info

我在 Internet 上尝试了很多不同的解决方案,因此您可以在我的 Dockerfile 中看到一团糟,但它们都不起作用。

【问题讨论】:

    标签: python docker aws-lambda alpine shapely


    【解决方案1】:

    您正在 Docker 环境中安装一些静态编译的依赖项,例如 libc-devgeos-devgeos。您还必须在 Lambda 部署 zip 文件中包含这些静态依赖项。此外,要包含用于 AWS Lambda 的静态编译依赖项,您必须使用 Lambda 使用的相同操作系统,即 Amazon Linux,而不是 Alpine Linux。


    幸运的是,现在有两种选择可以让这变得更容易:

    Lambda Layers

    Lambda 层是 Lambda 依赖项,可以打包成可重用的方法,也可以与其他开发人员共享。在这种情况下,您可以简单地将 someone has already created a shapely Lambda Layer(和其他人 here)包含在您的 Lambda 函数中,而不是尝试自己打包。

    如果您仍想自己构建它,您可以查看该项目的源代码以了解它们是如何构建层的。

    Lambda Containers

    您可以创建 Docker 映像并将其部署到 Lambda,而不是创建 zip 部署。如果你走这条路,你必须在你的 Lambda 容器中实现一个特定的接口,最简单的方法是从official AWS Lambda base images 之一开始。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 1970-01-01
      • 2017-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多