どこにでもいる30代SEの学習ブログ

主にプログラミング関連の学習内容。読んだ本の感想や株式投資についても書いてます。

【AWS】LambdaでPillowを使う方法(Lambda Layer)

AWS LambdaでPillowを使おうと思ったら次のエラーが表示されました。

[ERROR] Runtime.ImportModuleError: Unable to import module 'lambda_function': No module named 'PIL'
Traceback (most recent call last):

Lambdaのデフォルト環境にはPillowが入っていないので、インストールする必要がありました。今回は「Lambda Layer」を使った方法を紹介します。

方法を調べるにあたり下記記事を大変参考にさせていただき、とても助かりました。ありがとうございます。

michimani.net

qiita.com

[1] 必要な環境

Amazon Linuxを用意する必要があります。Amazon Linux上でPillowをローカルにインストールしzip圧縮してLayerに追加します。

用意する環境は、Lambda関数のPythonバージョンによって異なります。Python3.8を使いたい場合はAmazon Linux2Python3.7以下ならAmazon Linuxになります。

Building Lambda functions with Python - AWS Lambda

Amazon LinuxでDockerイメージが用意されています。Dockerを使えば、Amazon LinuxのEC2をわざわざ用意せずに済みます。ここでは、Dockerを用いた方法を紹介していきます。

ただし、Amazon Linux2を使用する場合、 Dockerは使えません。イメージが用意されていないので、Amazon Linux2のEC2を構築して、Dokcerコンテナで行ったのと同様のことを行います。

[2] Dockerインストール

$ sudo yum -y install docker

Dockerを起動し、自動起動の有効化も行います。

$ sudo systemctl start docker
$ sudo systemctl enable docker

Amazon ECS における Docker の基本 - Amazon Elastic Container Service

[2] docker-composeインストール

docker-composeもインストールします。

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.29.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

docker-compose --versionで実行できることを確認します。

$ docker-compose --version
docker-compose version 1.29.0, build 07737305

Install Docker Compose | Docker Documentation

[3] Amazon Linuxコンテナの起動確認

Amazon Linuxのコンテナを取得します。

$ docker pull amazonlinux

docker imagesAmazon Linuxのコンテナが取得できたことを確認します。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
amazonlinux         latest              e2c0b9bec08e        12 days ago         163MB

Amazon Linuxコンテナを試しに起動してみます。

$ docker run -it amazonlinux
bash-4.2# exit

起動が確認できたら削除します。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                          PORTS               NAMES
8b36a23fb991        amazonlinux         "/bin/bash"         About a minute ago   Exited (0) About a minute ago
$ docker rm 8b36a23fb991
8b36a23fb991

[4] パッケージ作成

いよいよPillowを含むパッケージの作成に取り掛かります。

[4-1] Dockerfileの用意

「Dockerfile」と「docker-compose.yml」を用意します。

  • Dockerfile
FROM amazonlinux:latest

RUN yum install -y python3 zip
RUN mkdir /home/deploy
  • docker-compose.yml
version: '2'
services:
  app:
    build: .
    volumes:
      - './deploy:/home/deploy'
    command: >
      bash -c "pip3 install -r /home/deploy/requirements.txt -t /home/deploy/python &&
      cd /home/deploy &&
      /usr/bin/zip -r PIL.zip python"

Lambda Layersに追加する場合、pythonディレクトリの下にパッケージをインストールする必要があります。詳細は以下の記事を参考にさせていただきました。

qiita.com

[4-2] ディレクトリの準備

$ mkdir deploy
$ mkdir deploy/python

「requirements.txt」を準備しdeployディレクトリ下に置きます。「requirements.txt」にはインストールするパッケージ名を記載します。今回はPillowのみです。

  • requirements.txt
Pillow

treeコマンドで確認すると次のようなディレクトリ構成です。

$ tree
├── Dockerfile
├── deploy
│   ├── python
│   └── requirements.txt
└── docker-compose.yml

[4-3] パッケージ作成

準備ができたら下記コマンドを実行します。

docker-compose up --build

lsで確認すると無事にzipファイルが作成されていました。

$ ls deploy/
PIL.zip  python  requirements.txt

[5] Lambda Layerに追加

作成したzipをLambda Layerに追加していきます。

[5-1] レイヤーの作成

f:id:predora005:20210413232416p:plain

「.zipファイルをアップロード」で先ほど作成したzipをアップロードします。ランタイムは「Python 3.7」を選択します。

f:id:predora005:20210413232420p:plain

Lambda関数自体のランタイムも「Python 3.7」にし揃える必要があります。ランタイムを「Python3.8」にする場合は前述の通り、zipファイルをAmazon Linux2で作成します。

[5-2] レイヤーの追加

作成したレイヤーをLambda関数に追加します。

f:id:predora005:20210413233354p:plain

f:id:predora005:20210413232442p:plain

「カスタムレイヤー」を選択し、先程作成したレイヤーを選択します。バージョンは「1」しか無い状態なので「1」を選びます。

f:id:predora005:20210413232446p:plain

レイヤーが追加できたので、再度テストを実行します。

f:id:predora005:20210413232506p:plain

今度はエラーが出ずに関数が実行されます。

f:id:predora005:20210413232511p:plain

終わりに

調べるのにだいぶ時間を要しましたが、冒頭で紹介した記事のおかげでどうにかなりました。この方法は今回紹介したPillowだけでなく、他のパッケージを追加する際にも使用できます。やり方さえ分かれば時間はそれほどかからないので、気軽にパッケージの追加が行えそうです。

[備考1] Amazon LinuxでDockerを使用する場合

Amazon LinuxでDockerを使用する場合は、ec2-userをdockerグループに追加します。追加後にログアウト・再ログインが必要です。

$ sudo usermod -a -G docker ec2-user

dockerグループへの追加を忘れると、以下のエラーが表示されます。

$ docker pull amazonlinux
Using default tag: latest
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/create?fromImage=amazonlinux&tag=latest: dial unix /var/run/docker.sock: connect: permission denied

[備考2] Python3.8を使いたい場合

Amazon Linux2のEC2を構築して、Dokcerコンテナで行ったのと同様のことを行います。

まずは、python3.8をインストールします。

$ sudo amazon-linux-extras install python3.8

次にpythonディレクトリを作成し、Pillowをインストールします。

$ mkdir python
$ pip3.8 install Pillow -t python

pythonディレクトリにインストールしたPillowをzip化します。

$ zip -r PIL.zip python

レイヤー追加以降の手順は、Amazon Linuxの場合と同様です。

出典