As dependências python para um aplicativo AWS lambda excederam o limite de 250 MB para AWS Lambdas. Uma dessas dependências é o rasterio que depende do gdal. Estou tentando construir uma imagem docker para contornar o limite de 250 MB e implantar nosso código em um AWS Lambda (usando serverless.com).
Abordagem 1: pip install rasterio
Atualmente tenho um Dockerfile
com:
FROM public.ecr.aws/lambda/python:3.10
RUN pip install rasterio # Fails with error (see below)
WARNING:root:Failed to get options via gdal-config: [Errno 2] No such file or directory: 'gdal-config'
ERROR: A GDAL API version must be specified. Provide a path to gdal-config using a GDAL_CONFIG environment variable or use a GDAL_VERSION environment variable.
Abordagem 2: yum install gdal-devel
tl; dr: "Nenhum pacote gdal-devel disponível."
Abordagem 3: construir gdal
tl; dr: muitas dependências. Nervoso, essas dependências terão dependências que também precisam ser construídas.
Abordagem 4: yum install epel-release e depois gdal-devel
- Precisa de fortran:
yum -y install libgfortran
funcionou, mas instalou libgfortran.so.4 yum -y install gdal-devel
ainda com erro, por exemplo "Erro: Pacote: openblas-openmp-0.3.3-2.el7.aarch64 (epel) Requer: libgfortran.so.3 (GFORTRAN_1.0) (64 bits)"- Não tenho certeza se o problema é ter a versão 4 em vez da versão 3 do libgfortran, mas não consegui instalar facilmente
libgfortran.so.3
.
Abordagem 5: use aws/sam/build-python
contêiner
aws/sam/build-python
contêinerdependências python são instaladas sem problemas( nenhum rasterio é instalado sem erros, mas o lambda falha quando é executado na AWS com o erro "Nenhum módulo chamado 'rasterio._version'" ) ao usar osserverless.com
requisitos de python sem servidor, ou seja, executandoserverless deploy
com o seguinte sem servidor. arquivo yml:
service: aws-python-docker-demo
frameworkVersion: "3"
plugins:
- serverless-python-requirements
custom:
pythonRequirements:
usePipenv: true
layer: true
provider:
name: aws
runtime: python3.10
deploymentBucket:
blockPublicAccess: true
functions:
hello:
handler: src/main.lambda_handler
layers:
- !Ref PythonRequirementsLambdaLayer
este
serverless-python-requirements
plugin parece usar um contêiner dockerpublic.ecr.aws/sam/build-python3.10
para instalar as dependências do python e compactá-las para o lambda- (que falha porque as dependências e o código do lambda são >= limite de tamanho de 250 MB)
Plano:entenda comoserverless-python-requirements
:instala dependências python dentropublic.ecr.aws/sam/build-python3.10
do contêinerzips dependências python (que serão> 250 MB)
copie esse zip na imagem docker para o AWS lambda....?
Não tenho certeza se esta é uma boa abordagem, tenho certeza de que existem soluções melhores. Qualquer conselho é bem-vindo.
** Atualização ** em relação à nova abordagem (nº 6) e em resposta à gentil resposta de @Rob.
Abordagem 6: tente usar uma imagem antiga do docker gdal/lambda
O trabalho em andamento está aqui usando https://hub.docker.com/r/remotepixel/amazonlinux-gdal/ . Próxima etapa: faça isso funcionar e, em seguida, itere a partir daí para:
- atualizar gdal
- use o contêiner lambda mais recente
- use python 3.10 (conforme necessário para nossa aplicação)
Atualmente planejando responder/atualizar a resposta a esta pergunta do StackOverflow: https://stackoverflow.com/questions/36772111/how-can-i-install-a-recent-version-of-gdal-on-amazon-linux #comentar135429542_44907360
Atualmente errando com:
{
"errorType": "Runtime.InvalidEntrypoint",
"errorMessage": "RequestId: 2cda4291-3b02-4079-8d59-f1ab111f8dab Error: exec: \"main.lambda_handler\": executable file not found in $PATH"
}
Resposta à possível resposta de Rob
Quando executo isso, ocorre um erro com o seguinte:
cat Dockerfile2
FROM public.ecr.aws/lambda/python:3.10
RUN pip install rasterio
docker --version
Docker version 24.0.6, build ed223bc
macOS 12.7.2
docker build -t testing-run-api-dependencies-2 -f ./Dockerfile2 . --progress=plain --no-cache
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s
#2 [internal] load build definition from Dockerfile2
#2 transferring dockerfile: 101B done
#2 DONE 0.0s
#3 [internal] load metadata for public.ecr.aws/lambda/python:3.10
#3 DONE 1.1s
#4 [1/2] FROM public.ecr.aws/lambda/python:3.10@sha256:f95780930513037d252b6b6165720381a1014096c3be9f2eac620776c8f0d167
#4 CACHED
#5 [2/2] RUN pip install rasterio
#5 1.173 Collecting rasterio
#5 1.229 Downloading rasterio-1.3.9.tar.gz (411 kB)
#5 1.309 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 411.7/411.7 kB 5.5 MB/s eta 0:00:00
#5 1.406 Installing build dependencies: started
#5 8.663 Installing build dependencies: finished with status 'done'
#5 8.666 Getting requirements to build wheel: started
#5 8.934 Getting requirements to build wheel: finished with status 'error'
#5 8.939 error: subprocess-exited-with-error
#5 8.939
#5 8.939 × Getting requirements to build wheel did not run successfully.
#5 8.939 │ exit code: 1
#5 8.939 ╰─> [3 lines of output]
#5 8.939 <string>:22: DeprecationWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html
#5 8.939 WARNING:root:Failed to get options via gdal-config: [Errno 2] No such file or directory: 'gdal-config'
#5 8.939 ERROR: A GDAL API version must be specified. Provide a path to gdal-config using a GDAL_CONFIG environment variable or use a GDAL_VERSION environment variable.
#5 8.939 [end of output]
#5 8.939
#5 8.939 note: This error originates from a subprocess, and is likely not a problem with pip.
#5 8.942 error: subprocess-exited-with-error
#5 8.942
#5 8.942 × Getting requirements to build wheel did not run successfully.
#5 8.942 │ exit code: 1
#5 8.942 ╰─> See above for output.
#5 8.942
#5 8.942 note: This error originates from a subprocess, and is likely not a problem with pip.
#5 8.947
#5 8.947 [notice] A new release of pip is available: 23.0.1 -> 24.0
#5 8.947 [notice] To update, run: pip install --upgrade pip
#5 ERROR: process "/bin/sh -c pip install rasterio" did not complete successfully: exit code: 1
------
> [2/2] RUN pip install rasterio:
8.942 error: subprocess-exited-with-error
8.942
8.942 × Getting requirements to build wheel did not run successfully.
8.942 │ exit code: 1
8.942 ╰─> See above for output.
8.942
8.942 note: This error originates from a subprocess, and is likely not a problem with pip.
8.947
8.947 [notice] A new release of pip is available: 23.0.1 -> 24.0
8.947 [notice] To update, run: pip install --upgrade pip
------
Dockerfile2:2
--------------------
1 | FROM public.ecr.aws/lambda/python:3.10
2 | >>> RUN pip install rasterio
--------------------
ERROR: failed to solve: process "/bin/sh -c pip install rasterio" did not complete successfully: exit code: 1
Talvez eu esteja entendendo mal, mas talvez isso seja algo específico para sua máquina de construção/versão do Docker. Quando tento sua abordagem 1 acima literalmente para construir o contêiner localmente, ela é bem-sucedida:
Agora, em teoria, as compilações do docker não deveriam ter nenhuma dependência na máquina local, uma compilação do docker que funciona em um lugar deveria funcionar em outro, mas talvez você tenha uma dependência obsoleta em cache? Talvez tente
docker build
em uma máquina diferente se você tiver acesso a outro ambiente oudocker system prune -a
(caro, limpa todas as imagens em cache não utilizadas) e reconstrua.