Cloud Run で画像リサイズ API を作る
2023年は「Cloud Run を触って覚える」をテーマとした ひとりアドベントカレンダー を開催しており、Cloud Run のさまざまな機能や Cloud Run でよく使う構成などをご紹介しています。
22日目は Cloud Run で画像リサイズ API を作ってみたので、その手順を解説します。
Cloud Run の概要は「gihyo.jp」で解説していますので、こちらもぜひご覧ください。
画像リサイズ
今回は Cloud Run で画像をリサイズするシンプルな API を作ってみました。画像のリサイズもできる CDN サービスを使うことが多くなってきていますが、「最小限の構成で画像のリサイズだけしたい」といったようなユースケースに使えるアーキテクチャだと思います。
アーキテクチャ
Cloud Storage バケットに格納しているファイルを、クエリパラメータで自由にリサイズできる API を Cloud Run で構築します。Cloud Storage バケットは Cloud Storage FUSE を使ってマウントし、sharp を使ってリサイズを実施します。Cloud Run の前にアプリケーション ロードバランサを挟み、Cloud CDN を有効化してキャッシュできるようにします。
手順
Cloud Storage バケットを作成する
まずは Cloud Storage バケットを作成します。
作業は Cloud Shell 上で行いますので、まずは Cloud Shell を開きます。
Cloud Shell の起動
次のコマンドで Cloud Storage バケットを作成します。BUCKET_NAME
は適宜修正してください。
gcloud storage buckets create gs://<BUCKET_NAME> \
--location asia-northeast1
適当な画像ファイルを数点アップロードしておきます。Cloud Shell に画像をアップロードするには、オプションメニューから [アップロード] を選びます。
アップロード
[フォルダ] をクリックし images
フォルダを選びます。
フォルダの指定
Cloud Shell へのアップロードが完了したら、次のコマンドで画像ファイルをアップロードします。
gcloud storage cp images/* gs://<BUCKET_NAME>/
Cloud Run サービスを作成する
次に Cloud Run サービスを作成します。
サンプルコードを GitHub からクローンします。
git clone git@github.com:suwa-yuki/run-resize-image-sample.git
cd run-resize-image-sample
main.js
のコードは次の通りです。file
と size
をクエリパラメータに取り、指定したファイル名の画像を指定したサイズが長辺となる画像にリサイズします。
const express = require("express")
const sharp = require("sharp")
const mntDir = process.env.MNT_DIR
const app = express()
app.get("/", async (req, res) => {
const { file, size } = req.query
const original = await sharp(`${mntDir}/${file}.jpg`)
const resized = await original.resize(parseInt(size))
const data = await resized.toBuffer()
res.type('jpeg')
res.send(data)
});
app.listen(3000, () => {
console.log("Server started on port 3000")
})
サービス アカウントを作成します。Cloud Storage バケットのオブジェクトの読み取り権限を付与します。
gcloud iam service-accounts create fs-identity
gcloud projects add-iam-policy-binding <PROJECT_ID> \
--member "serviceAccount:fs-identity@<PROJECT_ID>.iam.gserviceaccount.com" \
--role "roles/storage.objectAdmin"
次のコマンドでデプロイします。
gcloud alpha run deploy resizer \
--region asia-northeast1 \
--source . \
--port 3000 \
--execution-environment gen2 \
--service-account fs-identity \
--allow-unauthenticated \
--add-volume=name=gcs,type=cloud-storage,bucket=<BUCKET_NAME> \
--add-volume-mount=volume=gcs,mount-path=/mnt/gcs \
--update-env-vars MNT_DIR=/mnt/gcs
Cloud Storage バケットのマウントは --add-volume
と --add-volume-mount
オプションで設定することができます。マウント先は /mnt/gcs
にしており、このパスを環境変数 MNT_DIR
に設定しています。sharp からは、このパス配下のファイルをオリジナル画像ファイルとしてアクセスしにいきます。
アクセスしてみる
それでは使ってみたいと思います。クエリパラメータとして file
と size
を受け取るようにしているので、それぞれ指定した URL を作り、ブラウザからアクセスしてみます。
hat
という名前のファイルを長辺 300
で取得する場合は、次のような URL になります。
https://<CLOUDRUN_URL>?file=hat&size=300
画像リサイズ API の実行結果
好きなサイズで取得できます。
画像リサイズ API の実行結果 (サイズ変更)
CDN を追加する
一度リサイズした画像は再度 Cloud Run を経由してリサイズし直す必要はないため、CDN キャッシュを組み合わせると良いです。Google Cloud ではグローバル外部アプリケーション ロードバランサの設定で Cloud CDN を有効化できます。Cloud Run サービスとグローバル外部アプリケーション ロードバランサを接続するには Cloud Run Integration (プレビュー) を使用すると、少ないステップでかんたんにカスタムドメインも含めて設定できます。設定方法は次のブログで紹介しているので参考にしてください。
作成後、ロードバランサのコンソールから編集します。バックエンド サービスの設定で Cloud CDN の設定が行えます。
Cloud CDN の設定
各設定の意味は次のドキュメントを参考にしてください。
まとめ
パラメータをカスタマイズすれば、ここからさらに機能を持たせることができます。sharp はリサイズだけではなく、切り抜き、回転、合成、エフェクト、色調補正など様々な機能があります。要件に合わせてカスタマイズしながら使ってみてください。
Discussion