Lambda LayerをDockerを使用して作成してみる

# はじめに
AWS Lambdaで外部ライブラリを使いたいとき、「Lambda Layer」を活用すると便利です。
Windows環境ではLambdaの実行環境（Amazon Linux）と異なるため、そのままでは動かないことがあります。

そこで、Dockerを使って本番と同じLinux環境を再現し、任意のPythonライブラリをLayer化する方法をまとめました。
# 前提知識
### Layerとは
AWS Lambda Layerは、Lambda関数のコードとは別に、共通で使用するライブラリやコードを切り出して管理する仕組みのこと。
複数の関数で同じライブラリを使う場合などに便利です。

【Layerを使用しない方法】
Lambda関数ではライブラリやモジュールを含めたZIPファイルをアップロードします。
![Lambda_Layers-without layers.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091380/79b81168-e0f2-4441-a86b-a64c2b193b70.png)
しかし、この形式だと以下のような問題がある
- 複数のLambda関数で同じライブラリを使うと、**ZIPが重くなる**
- アップデートのたびに**関数ごとにZIPを作り直す必要がある**
- 複数関数間で**ライブラリのバージョンがズレやすい**

【Layerを使った方法】
Layerを使うと、ライブラリなどを別のZIPファイルとしてまとめて管理できます。
関数側では、それを参照するだけでOKです。
![Lambda_Layers-with layers.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091380/f3da60ca-0204-491f-bf73-e5a792e07e05.png)
このようにすることで、
- 同じライブラリを複数の関数で使い回せる
- ライブラリを一括でアップデートできる
- 各関数のZIPが軽量化される

といったメリットがあります。
### なぜDockerを使うのか
AWS LambdaでPythonなどの依存パッケージを含むLambda Layerを作成する際には、本番の**Lambda実行環境（Amazon Linuxベース）と完全に一致した環境でビルドを行う必要**があります。

特に以下の理由から、ローカル環境（WindowsやmacOS）で直接パッケージを作成すると、Lambda上で正常に動作しないことがあります。
- OS依存のバイナリが含まれるライブラリが存在する（例：numpy, pandas, scipy など）
- pip install時にビルドされるC/C++拡張モジュールが、LambdaのAmazon Linuxと互換性のない形式になる
- WindowsやmacOSでは利用できるglibcや依存ツールのバージョンがLambdaと異なる

このため、ローカルで作成したLayerがLambda上で「ImportError」や「Segmentation Fault」などを引き起こす可能性が高い。

そこで Docker を使うことで、Lambdaと同一のAmazon Linuxベースの環境を再現し、その中でPythonライブラリをインストールすることができます。
これにより、Lambda本番環境でそのまま動作する、互換性のあるLayerを安全かつ確実に作成できます。
# 目標
- Dockerで AWS Lambda と同じ Linux 環境 を作る
- 任意のPythonライブラリをインストール
- Lambda Layer用の ZIP を作成する
# 手順
### 作業フォルダを作成する
このフォルダがDockerビルドの作業ディレクトリになります。
```bash
mkdir lambda_layer
cd lambda_layer
```
### Dockerfileを作成する
LambdaでLayerとして認識されるには、ZIPの中身が `python/lib/python3.x/site-packages/` という正確なパス構造になっている必要があります。
ここではその構造をあらかじめ作成しておき、後から `pip install` でそこにライブラリを直接インストールする形を取ります。
```Dockerfile
# ベースイメージ
FROM amazonlinux:2023

# Python 3.12 + 必要なツールをインストール
RUN dnf install -y python3.12 python3.12-pip zip

# 作業ディレクトリ
WORKDIR /build

# Layer構造用フォルダ作成
RUN mkdir -p python/lib/python3.12/site-packages
```
##### ポイント
- Lambda本番環境と同じイメージを使用する（例：`public.ecr.aws/lambda/python:3.12`）
- `/build/python/lib/python3.12/site-packages/` に配置する
### Dockerイメージをビルドする
このコマンドで、先ほど作成した Dockerfile を元に Docker イメージをビルドし、lambda-layer-build という名前を付けます。
```bash
docker build -t lambda-layer-build .
```
→ `lambda-layer-build` という名前のDockerイメージが作成される
### コンテナ内に入ってlangfuseをインストール
#### コンテナを起動する
このコマンドでコンテナを起動し、ホスト側の作業ディレクトリ（lambda_layer/）を /build にマウントします。
```bash
docker run -it --rm -v ${PWD}:/build lambda-layer-build /bin/bash
```
#### コンテナ内でインストールしたいライブラリを指定して実行
必要なライブラリ（例：requests）を -t オプションで直接 Layer のフォルダにインストールします。この形式にすることで、そのまま ZIP 化してLayerとしてアップロード可能になります。
```bash
cd /build
pip3.12 install <ライブラリ名> -t python/lib/python3.12/site-packages
```
例：
```bash
pip3.12 install requests -t python/lib/python3.12/site-packages
```
### Layer用ZIPを作成する
Layerは python フォルダ以下の構成でなければならないため、ZIP化する際には必ず python/ をルートにして圧縮します。
```bash
zip -r lambda_layer_langfuse.zip python
```
→ /build/lambda_layer_langfuse.zip が作成される
### コンテナを終了してローカルを確認する
コンテナを終了させる
```bash
exit
```
ローカルのファイルを確認する
```bash
dir # または ls
```
→ `lambda_layer_langfuse.zip` ができている
### AWSコンソールからLayerを作成
1. Lambda → 「レイヤー」 → 「レイヤーの作成」
![スクリーンショット 2025-06-02 110304.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091380/7d800a16-2da7-4d89-9f45-061d8776e0c0.png)
2. 必要項目を入力して作成
	- アップロード：lambda_layer.zip
	- ランタイム：Python 3.12

![スクリーンショット 2025-06-02 110940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4091380/d12caa5c-e21a-405d-a6e2-12bea3400f5b.png)
3. 　作成後、Lambda関数にレイヤーを追加して利用
# まとめ
Lambda LayerをWindows環境で作成するには、DockerによるLinux環境の再現が最も安定した方法です。
この手順を使えば、requests や boto3、numpy など任意のライブラリをLayer化できます。

Pythonのバージョンを変更したい場合は、Dockerfileのパスやコマンドも適宜調整してください。