はじめに

docker-lambda + sharp で画像変換する AWS Lambda Function 作ったのでそのメモ。

TL;DR

目次

  1. はじめに
  2. TL;DR
  3. 環境・条件
  4. 詳細
    1. 作業メモ
    2. 解説・変更点など
      1. async/await
      2. webp 対応
      3. ACL, Cache-Control
  5. まとめ
  6. 参考文献

環境・条件

1
2
3
4
5
6
7
8
9
10
$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.5
BuildVersion: 18F132

$ docker --version
Docker version 19.03.1, build 74b1e89

$ npm v sharp
sharp@0.23.0

詳細

リポジトリ: 17number/aws-lambda-resize-s3-image-sharp

作業メモ

npm init で初期化。

1
$ npm init

npm-add-dependenciessharp を追加。

1
$ npm-add-dependencies sharp

Dockerfile を作成。

1
2
3
4
5
6
7
FROM lambci/lambda:build-nodejs10.x
ENV LANG C.UTF-8
ENV AWS_DEFAULT_REGION ap-northeast-1

ADD . .

CMD npm install && zip -r9 deploy_package.zip .

index.js を作成。

1
2
3
4
5
// dependencies
const AWS = require('aws-sdk');
const sharp = require('sharp');

// 略、GitHub 参照

ビルド。

1
$ docker build -t aws-lambda-nodejs10.x-image-optimizer .

デプロイファイルを作成。

1
$ docker run --rm -v "$PWD":/var/task aws-lambda-nodejs10.x-image-optimizer:latest

aws lambda create-function で Lambda function を作成。

1
2
3
4
5
6
7
8
$ aws lambda create-function \
--function-name resizeImage \
--zip-file fileb://deploy_package.zip \
--handler index.handler \
--runtime nodejs10.x \
--timeout 10 \
--memory-size 1024 \
--role arn:aws:iam::123456789012:role/hoge-fuga-role

aws lambda add-permission で権限を設定。

1
2
3
4
5
6
$ aws lambda add-permission --function-name resizeImage \
--principal s3.amazonaws.com \
--statement-id resizeImage \
--action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::your-source-bucket \
--source-account 123456789012

S3 コンソール で、Lambda Function に通知するためのイベントを設定。

解説・変更点など

async/await

なるべくネストを減らすために async/await を使うようにした。

aws-sdkS3 は(たぶん他クラスも)、promise() メソッドがあるので、

1
s3.getObject(params, (err, data) => { /* some process */ });

↑のようなコードを、↓のように変更した。

1
let image = await s3.getObject(params).promise();

webp 対応

sharp を使うと webp にも変換ができる。

webp とは、以下のような画像形式。

sharp を使った変換方法はこれだけ。

1
2
const sharp = require("sharp");
sharp("hoge.png").webp().toFile("hoge.webp");

webp について詳しく知りたい方は 【画像軽量化】Webpにそろそろ対応したほうが良さそうなので現時点で最適方法の考察 - ウェブ企画ラボ などの記事をどうぞ。

ACL, Cache-Control

S3.putObject は、パラメータで ACL (アクセスコントロール)、CacheControl が設定できる。

公開用の画像ファイルで、一度作ったら基本的に変わらない想定なので、それぞれ "public-read", "max-age=31536000" (=1年) とした。(もっと短い方が良いかも)

1
2
3
4
5
6
7
8
9
10
s3.putObject(
{
Bucket: dstBucket,
Key: dstKey,
Body: resized,
ContentType: contentType,
ACL: "public-read",
CacheControl: "max-age=31536000"
}
);

なお、AWS Lambda Function を実行するロールの権限が不足していると、ACL の部分でエラーになる(なった)ので注意。対象 Bucket の操作権限を付与すれば解決するはず。

まとめ

参考文献

関連記事