/var/lang/bin/python: No module named amazon_linux_extras

mysqlclientがAWS Lambda Pythonにインストールできないという報告があったので試してみた。

シェルを使う

$ docker run -it --rm public.ecr.aws/lambda/python:3.11-arm64 bash
09 Nov 2023 04:46:42,532 [INFO] (rapid) exec '/var/runtime/bootstrap' (cwd=/var/task, handler=)

$ docker run -it --rm public.ecr.aws/lambda/python:3.11-arm64 bash -
entrypoint requires the handler name to be the first argument

特殊なエントリーポイントが設定されているようでbashが使えない。 --entrypoint オプションで強制的に上書きする。

$ docker run -it --rm --entrypoint bash public.ecr.aws/lambda/python:3.11-arm64
bash-4.2#

/var/lang/bin/python: No module named amazon_linux_extras

Amazon Linux 2 はめちゃくちゃ古いみたいで、 /usr/bin/pythonPython 2.7 だし、 MariaDB は 5.5 だ。MariaDB(のクライアントライブラリ)が古すぎるのが報告されていたエラーの原因なので新しいバージョンを入れる方法を調べると、 Amazon Linux Extras とかいうものを使ってMariaDB 10.5を入れるのが推奨されているようだ。しかし、エラーで動かない。

bash-4.2#  yum install -y amazon-linux-extras
Loaded plugins: ovl
...
Installed:
  amazon-linux-extras.noarch 0:2.0.3-1.amzn2

Complete!

bash-4.2# amazon-linux-extras enable mariadb10.5
/var/lang/bin/python: No module named amazon_linux_extras

amazon-linux-extras を調べてみるとこうなっている。

(snip)
# Avoid encoding errors because default is ASCII.
if test "$ENVROOT"; then
    PATH=$ENVROOT:$PATH
fi
exec env PYTHONIOENCODING=UTF-8 ${PYTHON:-python} -m amazon_linux_extras "$@"

amazon-linux-extrasコマンドはPythonamazon_linux_extras モジュールを利用している。そしてPythonを起動するのにはデフォルトで python コマンドを利用している。しかし public.ecr.aws/lambda/python イメージは /var/lang/bin/python を追加して、優先してパスを通している。そのために amazon_linux_extrasモジュールが存在しないというエラーになっている。(なぜ絶対パス/usr/bin/python と書かない……こういうことするから python 環境がすぐ壊れるみたいな悪評が……)

bash-4.2# type python

python is /var/lang/bin/python

ググったら amazon_linux_extras モジュールを /var/lang/bin/python からimportできるようにパスを通すような記事を見かけたが、アプリを動かすためのPython環境を汚すのも、amazon_linux_extrasがサポートしているかどうかわからないPythonで動かすことも、よくないだろう。

上の amazon-linux-extras をみてみると、 ENVROOT 環境変数に /usr/bin を指定するか、 PYTHON 環境変数に /usr/bin/ptyhon を指定すればよさそうだ。

bash-4.2# ENVROOT=/usr/bin amazon-linux-extras
  1  httpd_modules            available    [ =1.0  =stable ]
...
† Note on end-of-support. Use 'info' subcommand.

AWS Lambda のPython用コンテナイメージに mysqlclient をインストールする

最終的に、次のようなDockerfileでmysqlclientをインストールできた。

FROM public.ecr.aws/lambda/python:3.11-arm64

RUN yum install -y amazon-linux-extras
RUN PYTHON=/usr/bin/python2 amazon-linux-extras enable mariadb10.5
RUN yum install -y gcc pkgconfig mariadb-devel
RUN pip install mysqlclient
このブログに乗せているコードは引用を除き CC0 1.0 で提供します。