Serverless Framework は主に JavaScript のランタイムで使われることが多いと思いますが、最近 Python ランタイムの Lambda 関数を作成する必要があり、 serverless-python-requirements というライブラリを使って Python のコードをデプロイしています。このライブラリで custom.pythonRequirements.dockerizePip: true
というオプションを有効化すると、 requirements.txt
の依存関係を Linux のコンテナでクロスビルドしてくれるため便利です。
クロスビルド時にあるエラーに遭遇したのでそのメモを記載します。
前提条件#
再現方法#
MacOS 環境において、serverless.yml に provider.runtime
としてランタイムの種類を記載せず、関数レベルで指定している場合、デプロイ実行時に以下のエラーが発生します。
serverless.yml#
service: <あなたのサービス名>
frameworkVersion: '3'
plugins:
- serverless-python-requirements
provider:
name: aws
region: ap-northeast-1
logRetentionInDays: 7
stage: dev
# runtime: python3.11 # ランタイムをスタックレベルで指定せず、
custom:
pythonRequirements:
dockerizePip: true
functions:
main_py:
runtime: python3.11 # ランタイムを関数レベルで指定する
handler: handler_py.main
main_js:
runtime: nodejs20.x # なお、なぜ関数レベルで指定したかというと、このように複数の種類のランタイムを混在させたかったから
handler: handler_js.main
出力#
$ sls deploy
Deploying <あなたのサービス名> to stage dev (ap-northeast-1)
✖ Stack <あなたのサービス名>-dev failed to deploy (3s)
Environment: darwin, node 18.19.0, framework 3.38.0 (local), plugin 7.2.3, SDK 4.5.1
Credentials: Local, environment variables
Docs: docs.serverless.com
Support: forum.serverless.com
Bugs: github.com/serverless/serverless/issues
Error:
Running "docker run --rm -v /Users/kamataryo/Library/Caches/serverless-python-requirements/caccb90f1757a760e21907a698ded42825c79604157da6614640dbccdcbb4dc1_x86_64_slspyc:/var/task:z -v /Users/kamataryo/Library/Caches/serverless-python-requirements/downloadCacheslspyc:/var/useDownloadCache:z -u 0 public.ecr.aws/sam/build-undefined:latest-x86_64 python -m pip install -t /var/task/ -r /var/task/requirements.txt --cache-dir /var/useDownloadCache" failed with: "Unable to find image 'public.ecr.aws/sam/build-undefined:latest-x86_64' locally
docker: Error response from daemon: repository public.ecr.aws/sam/build-undefined not found: name unknown: The repository with name 'build-undefined' does not exist in the registry with id 'sam'.
See 'docker run --help'."
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
エラーの概要#
public.ecr.aws/sam/build-undefined:latest-x86_64
のイメージを取得しようとして存在していなかったためエラーとなっているようです。
試しに provider.runtime
を存在しないはずの適当な値 konnnichiha
に変えると、エラーメッセージが以下に変化しました。
Error:
Running "docker run --rm -v /Users/kamataryo/Library/Caches/serverless-python-requirements/01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b_x86_64_slspyc:/var/task:z -v /Users/kamataryo/Library/Caches/serverless-python-requirements/downloadCacheslspyc:/var/useDownloadCache:z -u 0 public.ecr.aws/sam/build-konnnichiha:latest-x86_64 python -m pip install -t /var/task/ -r /var/task/requirements.txt --cache-dir /var/useDownloadCache" failed with: "Unable to find image 'public.ecr.aws/sam/build-konnnichiha:latest-x86_64' locally
docker: Error response from daemon: repository public.ecr.aws/sam/build-konnnichiha not found: name unknown: The repository with name 'build-konnnichiha' does not exist in the registry with id 'sam'.
解決方法#
provider.runtime
を明示的に指定します。
service: <あなたのサービス名>
frameworkVersion: '3'
plugins:
- serverless-python-requirements
provider:
name: aws
region: ap-northeast-1
logRetentionInDays: 7
stage: dev
runtime: python3.11 # ランタイムをスタックレベルでも指定しておく
custom:
pythonRequirements:
dockerizePip: true
functions:
main_py:
runtime: python3.11
handler: handler_py.main
main_js:
runtime: nodejs20.x
handler: handler_js.main
今回、利用する Python のランタイムの種類が1つだけだったので問題ありませんでした。 複数の種類の Python ランタイムを利用して requirements.txt の依存関係をクロスビルドしたい場合、serverless-python-requirements を利用するのは難しいと思われます。