Skip to content

you-abcdefg/serverless-image-resize-lambda-s3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lambda Image Resize

S3 に画像がアップロードされたとき、AWS Lambda が自動で画像を縮小し、JPEG のサムネイルを別の S3 バケットへ保存するサンプルです。

このリポジトリは、sharp を Lambda で動かすために Docker を使って Linux 向けの ZIP を作れるようにしてあります。ローカルが Windows や Mac でも、Lambda 用のパッケージを同じ手順で作れます。

現在確認できていること

  • Docker を使った function.zip の作成はローカルで確認済みです
  • README の Docker 手順どおりに ZIP を作成できることを確認済みです
  • AWS への実デプロイと本番動作確認は、まだ試していません
  • 実行時間は現在未計測のため、この README には具体的な性能値を書いていません

この README の読み方

この README は、初めて AWS Lambda を触る人でも順番に進められるように作っています。

おすすめの読み方は次の通りです。

  1. まず できること を読んで、何を作るかをつかむ
  2. 次に 事前準備 を確認する
  3. Docker で ZIP を作る を進める
  4. AWS コンソールで設定する を上から順に進める
  5. 最後に 動作確認トラブルシューティング を見る

スクリーンショットを入れる場合は、各セクションのすぐ下に画像を追加すると見やすくなります。

できること

  • S3 に画像をアップロードすると Lambda が自動で実行される
  • 画像を指定した横幅にリサイズできる
  • 元画像の拡張子に関係なく、出力は常に JPEG になる
  • サムネイル名は 元ファイル名-thumbnail.jpg になる

例:

  • 入力: photos/sample.png
  • 出力: photos/sample-thumbnail.jpg

全体の流れ

  1. ローカルで Lambda 用の function.zip を作る
  2. AWS コンソールで Lambda 関数を作る
  3. ZIP をアップロードする
  4. 環境変数と IAM 権限を設定する
  5. S3 のイベント通知を設定する
  6. 画像をアップロードして動作確認する

使用技術

  • Node.js 20
  • AWS Lambda
  • Amazon S3
  • Docker
  • sharp
  • AWS SDK for JavaScript v3

ファイル構成

├── index.js          # Lambda 本体
├── package.json      # 依存関係
├── package-lock.json # 依存関係の固定
├── Dockerfile        # Lambda 用 ZIP を Docker で作る設定
├── .dockerignore     # Docker ビルド時に不要なものを除外
└── README.md         # この説明書

Lambda の動き

  1. S3 に画像がアップロードされる
  2. Lambda が起動する
  3. 元画像を取得する
  4. sharp でリサイズする
  5. JPEG に変換して別バケットへ保存する

環境変数

Lambda では次の環境変数を使います。

  • OUTPUT_BUCKET
    • サムネイル保存先の S3 バケット名
    • 必須
  • RESIZE_WIDTH
    • リサイズ後の横幅
    • 省略時は 100
  • AWS_REGION
    • AWS リージョン
    • 省略時は ap-northeast-1

事前準備

用意するものは次の 2 つです。

  • Docker
  • AWS アカウント

ここはスクリーンショットを入れるなら、

  • Docker Desktop が起動している画面
  • AWS マネジメントコンソールにログインした画面

を入れると分かりやすいです。

1. Docker で ZIP を作る

1-1. プロジェクトフォルダへ移動する

このプロジェクトのフォルダでターミナルを開きます。

1-2. Docker イメージを作る

次のコマンドを実行します。

docker build -t lambda-image-resize .

ここはスクリーンショットを入れるなら、ターミナルで docker build が成功した画面を入れるとよいです。

1-3. 一時コンテナを作る

docker create --name lambda-image-resize-export lambda-image-resize

1-4. function.zip を取り出す

docker cp lambda-image-resize-export:/function.zip ./function.zip

1-5. 一時コンテナを削除する

docker rm lambda-image-resize-export

1-6. ZIP ができたか確認する

フォルダの中に function.zip があれば成功です。

ここはスクリーンショットを入れるなら、エクスプローラーで function.zip が見えている画面を入れると伝わりやすいです。

2. AWS コンソールで Lambda 関数を作る

2-1. Lambda を開く

  1. AWS マネジメントコンソールにログインします。
  2. 上部の検索ボックスで Lambda と検索します。
  3. Lambda をクリックします。

ここはスクリーンショットを入れるなら、AWS コンソールの検索欄で Lambda を検索している画面が向いています。

2-2. 関数を作成する

  1. 関数を作成 を押します。
  2. 一から作成 を選びます。
  3. 次のように設定します。
  • 関数名: 好きな名前
    • 例: lambda-image-resize
  • ランタイム: Node.js 20.x
  • アーキテクチャ: x86_64
  1. デフォルトの実行ロールの変更 を開きます。
  2. はじめてなら新しいロールを作る設定のままで構いません。
  3. 関数を作成 を押します。

ここはスクリーンショットを入れるなら、関数を作成 画面全体が見える画像がよいです。

3. ZIP をアップロードする

3-1. コードタブを開く

作成した Lambda 関数の画面で コード タブを開きます。

3-2. ZIP をアップロードする

  1. アップロード元 を押します。
  2. zip ファイル を選びます。
  3. ローカルで作成した function.zip を選択します。
  4. 必要なら Deploy を押します。

ここはスクリーンショットを入れるなら、アップロード元 を押したメニューと ZIP アップロード画面が分かりやすいです。

4. Lambda の設定を行う

4-1. ハンドラーを確認する

  1. 設定 タブを開きます。
  2. ランタイム設定 を開きます。
  3. 編集 を押します。
  4. ハンドラーが index.handler になっていることを確認します。

違っていたら index.handler に直して保存します。

4-2. 環境変数を設定する

  1. 設定 タブの 環境変数 を開きます。
  2. 編集 を押します。
  3. 環境変数を追加 を押します。
  4. 次のように設定します。
  • キー: OUTPUT_BUCKET
    • 値: 出力用 S3 バケット名
  • キー: RESIZE_WIDTH
    • 値: 100

必要なら次も設定します。

  • キー: AWS_REGION
    • 値: ap-northeast-1
  1. 保存 を押します。

ここはスクリーンショットを入れるなら、環境変数 画面が最適です。

5. IAM ロールに権限を付ける

5-1. 実行ロールを開く

  1. Lambda の 設定 タブを開きます。
  2. アクセス権限 を開きます。
  3. 実行ロール に表示されているロール名をクリックします。

5-2. S3 権限を追加する

  1. IAM のロール画面で 許可を追加 を押します。
  2. インラインポリシーを作成 を選ぶか、ポリシー追加画面へ進みます。
  3. JSON タブを開きます。
  4. 次のポリシーを貼り付けます。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::<入力バケット名>/*",
        "arn:aws:s3:::<出力バケット名>/*"
      ]
    }
  ]
}
  1. <入力バケット名><出力バケット名> を自分のバケット名に書き換えます。
  2. 保存してロールに追加します。

ここはスクリーンショットを入れるなら、IAM の JSON タブ画面が分かりやすいです。

6. S3 のイベント通知を設定する

6-1. 入力用バケットを開く

  1. AWS コンソールで S3 を開きます。
  2. 入力用バケットをクリックします。

6-2. イベント通知を作成する

  1. プロパティ タブを開きます。
  2. 下へスクロールして イベント通知 を探します。
  3. イベント通知を作成 を押します。
  4. 次のように設定します。
  • イベント通知名: 好きな名前
    • 例: resize-trigger
  • イベントタイプ: オブジェクトの作成 (すべて)
  • プレフィックス: 必要なら設定
    • 例: photos/
  • サフィックス: 必要なら設定
    • 例: .png
  • 送信先: Lambda 関数
  • Lambda 関数: 作成した関数名
  1. 保存します。

ここはスクリーンショットを入れるなら、S3 の イベント通知を作成 画面が向いています。

7. 動作確認をする

この章は、AWS にデプロイしたあとに行う想定の確認手順です。

7-1. 入力用バケットに画像を入れる

  1. S3 の入力用バケットを開きます。
  2. アップロード を押します。
  3. sample.png などの画像を 1 枚選びます。
  4. アップロード を押します。

7-2. 出力用バケットを見る

数秒待ってから、出力用バケットを開きます。

-thumbnail.jpg のファイルが作成されていれば成功です。

例:

  • 入力: photos/sample.png
  • 出力: photos/sample-thumbnail.jpg

ここはスクリーンショットを入れるなら、入力バケットと出力バケットの比較が分かる画面が使いやすいです。

7-3. CloudWatch Logs を確認する

  1. Lambda 関数画面に戻ります。
  2. モニタリング タブを開きます。
  3. CloudWatch Logs を表示 を押します。
  4. 最新のログストリームを開きます。

次のようなログがあれば成功です。

Successfully resized image: sample-thumbnail.jpg

ここはスクリーンショットを入れるなら、CloudWatch Logs の成功ログ画面を入れるのがおすすめです。

8. うまくいかないときの見直しポイント

8-1. Lambda 側で見る場所

  • 設定ランタイム設定
    • ハンドラーが index.handler か確認する
  • 設定環境変数
    • OUTPUT_BUCKETRESIZE_WIDTH が正しいか確認する
  • 設定アクセス権限
    • IAM ロールに S3 権限があるか確認する
  • モニタリング
    • 実行エラーが出ていないか確認する

8-2. S3 側で見る場所

  • プロパティイベント通知
    • Lambda が設定されているか確認する
  • 入力用バケット
    • 本当に画像をアップロードしているか確認する
  • 出力用バケット
    • -thumbnail.jpg が作られているか確認する

8-3. よくある失敗パターン

  • 出力バケット名のスペルミス
  • IAM 権限不足
  • S3 イベント通知の設定漏れ
  • 画像ではないファイルをアップロードしている
  • RESIZE_WIDTH に文字列や 0 を入れている

9. うまくいったと判断できる状態

  • これは AWS にデプロイして確認できた場合のゴールです
  • 入力用バケットに画像を置く
  • Lambda が自動で実行される
  • 出力用バケットに -thumbnail.jpg 付きファイルが作成される
  • CloudWatch Logs に成功ログが残る

index.js のポイント

  • 入力バケット名は S3 イベントから取得
  • 出力バケット名は OUTPUT_BUCKET から取得
  • リサイズ幅は RESIZE_WIDTH から取得
  • 元画像の拡張子に関係なく、出力は JPEG
  • photo.sample.png のようなファイル名でも photo.sample-thumbnail.jpg になるようにしています

.dockerignore について

Docker ビルドに不要なものを除外しています。

  • node_modules
  • function.zip
  • .git
  • .gitignore
  • README.md
  • npm-debug.log

これにより、Docker に送るファイルを減らし、ビルドを少し分かりやすくできます。

よくあるつまずき

sharp が Lambda で動かない

Windows や Mac でそのまま npm install した node_modules を ZIP に入れると、Lambda の Linux 環境で動かないことがあります。

そのため、このリポジトリでは Docker を使って Linux 向けの ZIP を作ります。

OUTPUT_BUCKET environment variable is required. と出る

Lambda の環境変数に OUTPUT_BUCKET が設定されていません。保存先バケット名を設定してください。

RESIZE_WIDTH must be a positive integer. と出る

RESIZE_WIDTH100300 のような正の整数を設定してください。

今後の改善案

  • 複数サイズのサムネイル生成
  • WebP など他形式への対応
  • CloudFront 連携
  • テストコード追加
  • CI/CD 対応

参考

Open tabs:

  • README.md: 20260321_Lambda/lambda-image-resize/README.md

My request for Codex:

README.md内容が実態とあっているか確認 AWSのデプロイは 試していない 実行時間も現在の実態にあわせる。

About

Reproducible serverless image resizing with AWS Lambda, S3, and sharp using Docker.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors