WordPress メディアファイルをオブジェクトストレージに格納するプラグイン (WP-Stateless)

feature-image

アップロードした画像をオブジェクトストレージへ格納するためのプラグインの紹介です。この記事での検証環境は以下の通りです。

  • Google Cloud Platform が提供するオブジェクトストレージ(Cloud Storage)に格納する
  • WordPress 5.8 環境で動作テスト

オブジェクトストレージとは

オブジェクトストレージはデータを「オブジェクト」という単位で扱う記憶装置です。ディレクトリ構造で管理するファイルストレージとは異なり、データサイズやデータ数の保存制限がないため、大容量データの保存に適しています。

・・・というように書き始めると長くなってしまいますので外部サイトの説明記事にリンクします。

補足すると、大容量データの保存にも適しているという意味で、小容量データの保存でも全く問題はありません。

Google が提供する Cloud Storage や、Amazon Web Service が提供する Amazon S3 (Amazon Simple Storage Service) などが有名です。

何がしたいのか

このような構成を作りたいわけです。

まだこの構成だけだと本領発揮ではないのですが、とはいえこれだけでも以下のメリットがあります。

  • WordPress 本体を運営しているサイトとは別に、ストレージに特化したサイトから画像データを配信できる。つまり、プログラムによる動的アプリケーション(WordPress)の負担と、画像配信に関するサーバーの負担を分離できる。
  • 画像データが外部に保存されるのでデータの紛失対策としてとても強力。一般的にオブジェクトストレージは、何世代かの世代記録ができることも多い(世代バックアップ)。
更なる発展型

サイト閲覧者向けにはオブジェクトストレージを直接参照させるのではなく、Cloud Flare などの CDN を挟むことで配信の高速化や、GCP の転送費用の低減を狙えたりします。

この記事では、Cloud Storage を使うケースで説明します。

WordPress で Cloud Storage を使うための選択肢

Google Cloud Storage (GCS) 関連で人気そうなプラグインを 3 種類見繕いました。そのなかで今回は WP-Stateless プラグインと WP Offload Media Lite プラグインを実際に動かしてみます。

Google Cloud Storage (GCS) 事前準備

  • Google Cloud Storage (GCS) に任意の名前のバケットを作成しておく
  • バケットに対して全公開するための参照権限を設定しておく
  • WordPress から Google Cloud Storage (GCS) に画像を格納するためのアカウント(サービスアカウント)を作成したうえで書き込み権限を設定しておく

この記事で求めるプラグイン要件

WebP フォーマット画像を自動生成するための EWWW Image Optimizer プラグインとの相性を重要視しています。

この記事で紹介する WP-Stateless とあわせて、WordPress での画像管理をより便利にするために以下のプラグインをセットで導入していますので参考にしてください。

  • The Paste
  • EWW
  • FileBird Lite

WP-Statelss と WP Offload Media Lite の比較

2022/01/17 時点の情報より、以下の通り整理できます。どちらのプラグインもメンテナンスは程よく行われており、将来的な懸念も今の所はなさそうな印象です。と言いつつ WP-Staeless は若干停滞気味かもしれません。

結論としては、 WordPress 5.8 で正常に動作しています。ただしバケットの作成で手間取りましたので後述します。

WP-Stateless – Google Cloud Storage WP Offload Media Lite for Amazon S3, DigitalOcean Spaces, and Google Cloud Storage
バージョン 3.1.1 2.5.5
最終更新日 8 ヶ月前 6 ヶ月前
有効インストール数 6,000+ 50,000+
WordPress バージョン 5.0 またはそれ以降 4.9 またはそれ以降
検証済み最新バージョン 5.6.7 5.8.3
PHP バージョン 5.6 またはそれ以降 5.5 またはそれ以降
言語 英語 英語 または 韓国語
対応プラットフォーム GCS (Google Cloud Storage) S3 (Amazon S3), GCS (Google Cloud Storage), and DigitalOcean Spaces (S3 互換ストレージ)
ソースコード https://github.com/udx/wp-stateless https://github.com/deliciousbrains/wp-amazon-s3-and-cloudfront

WP Offload Media Lite はフリーミアム提供ですので、高度な機能を使おうとすると有償になります。ただし格納する用途に限定すれば無料版でも問題なさそうでした。

PRO Upgrade with Email Support and More Features

  • Upload existing Media Library to Amazon S3, DigitalOcean Spaces or Google Cloud Storage
  • Control offloaded files from the Media Library
  • Assets Pull addon – Serve your CSS, JS and fonts via CloudFront or another CDN

Why Upgrade to WP Offload Media? - Delicious Brains Inc

「WordPress へアップロードする既存のメディアをまとめて Cloud Storage にアップロードし直したい場合」については有償版機能になってしまうようなので、その点で困る人もいそうですね。無償と有償の機能差の詳細は上記のリンク先を参照してください。

なお WP-Stateless では同等機能が利用できます。

  • 既存のファイルをアップロードする行為
  • URL をリプレイスする行為
要件 with WP-Stateless with WP Offload Media Lite
GCS アップロード できる できる
WebP での保管 EWWW と連携により可能 EWWW との連携により可能
独自ドメイン URL の割当 可能 可能
独自ドメイン URL の HTTPS 化 可能 可能
(以下オプション) ——— ———
設定画面のシンプルさ 若干わかりづらい(相対的に) シンプル
アップロードパス指定 任意 任意。変数は Year/Month 形式固定
同一ファイル名の競合回避 ランダム文字列をファイル名に付与 タイムスタンプをディレクトリに付与
WebP を GCS へ保管後にサーバーファイル削除 不可(Ephemeral では正常動作しない) 不可(WP-Stateless での Ephemeral 相当動作はあるが正常動作しない)

ここまでを見ると、(今回求めているシンプルな使い方においては)極めてどちらが優位ということはなさそうです。

EWWW Image Optimizer プラグインへの対応

アップロード画像を WebP 変換したかったため、EWWW Image Optimizer プラグインとの組み合わせ動作は欠かせないものでした。結論としては、WP-Stateless プラグイン および WP Offload Media Lite プラグインいずれにおいても EWWW Image Optimizer プラグインが期待通りに動いてくれました。

そんな中、WP-Statelss は EWWW Image Optimizer をオフィシャルでサポートしている点も捨てがたいです。この図のように、WP-Stateless が EWWW Image Optimizer の有効化を検知すると警告を出して、「互換性を有効化するか」という問いかけをしてくれます。

互換性の考慮が必要なのか?

そこまで複雑なことをしているわけではなさそうですが、正式に互換性を考慮する対象として認識されているのは安心感がありますね。参考にリンクを掲載します。

WP-Stateless の EWWW Image Optimizer 互換考慮処理(ソースコード) https://github.com/udx/wp-stateless/blob/664739e48d26987f94123f76cdd50ea293005783/lib/classes/compatibility/ewww.php

WP-Stateless のセットアップ

手動セットアップ手順 https://wp-stateless.github.io/docs/manual-setup/

  • Google Cloud Platform を使えるようにします(まだの人)
  • Google Cloud Project を作成します
  • Cloud Storage で バケット を作成します
  • Google Cloud で サービスアカウント(Service Account)を作成します
  • WP-Stateless プラグインを設定します

プラグインを有効化すると「メディア」欄に設定が表示されます。この画像は既にセットアップ済みですが、まだセットアップしていない場合は自動セットアップに関する項目も出てきます。これは、インターネットに接続されている環境の場合には OAuth を使って(?)自動的に Clous Storage との連携をセットアップできるようです。私は開発環境(localhost)で試してからの本番サイト構築だったため、手順を流用する都合で手動セットアップを採用しただけです。自動の方が手っ取り早いと思います。

Cloud Storage の設定

設定の要約

  • Cloud Storage のバケットを任意の名前で作成しておく
  • Cloud Storage バケットに一般公開の権限設定をしておく。 allUsers に対しては ストレージのレガシーオブジェクト読み取り 権限の設定がお勧め
  • サービスアカウント wp-stateless に対しては、 Storage オブジェクト管理者Storage レガシーバケット読み取り の 2 種類の権限設定をしておくのがお勧め

Cloud Storage は権限設定などややこしい点があるので、すべてを説明すると話が WP-Stateless の本題から逸れてしまうことため別の記事にまとめました。

WP-Stateless プラグインを利用するための Cloud Storage (GCS) 権限設定
WP-Stateless プラグインを利用するための Cloud Storage (GCS) 権限設定
https://fand.jp/wordpress/cloud-storage-settings-for-using-wp-stateless/
WP-Stateless プラグインを利用するための Cloud Storage 設定で気をつける点を説明します。その他のアプリケーションにも応用可能な基礎知識です。

WP-Stateless の動作確認

結果的には何とか動きましたが、いくつかの動作不良を経て苦労しました。そのトラブルシュートは記事の末尾に記載しています。

一通りの設定が完了したあと、メディアライブラリから通常の操作でアップロードすると Cloud Storage にもデータが格納されました。また、メディアライブラリから削除をすると同じく Cloud Storage からもデータ削除されます。完璧です。

メディアライブラリの画像一覧にて、特定の画像に対して複数サイズのリンク一覧が表示されます。URL を見て読み取れる通り、Cloud Storage のリンクになっています。

WP-Stateless の動作モード概要

設定画面の画像

無効化(Disabled)を除き 4 種類あります。

モード 挙動の説明 きめ細かい ACL
Backup 挙動そのものは通常の WordPress そのままで、単純にバックアップ用としてのみ使うものと想定(実際に試してはいません) 必要(想定)
CDN サーバー内にファイルを作成するのとあわせて、GCS へも転送する。サーバー内のファイルは削除されない。メディア管理画面での画像の扱いは CDN の URL になる。 必要
Ephemeral アップロード直後はサーバー内にファイルが作成されるが、直後に GCS へ転送するのですぐに消される。アップロード失敗の可能性が相対的には減ると思われる。 必要
Stateless サーバー内にファイルを作ることなく GCS へ直接保存するストリーム形式 不要

まとめ

WordPress のメディアライブラリにアップロードした画像を Google のオブジェクトストレージ(Cloud Storage)に格納するためのプラグインについて検証しました。

WP Offload Media Lite プラグインも実用的だとは思いますが、無償で使える範囲が WP-Stateless の方が広いため、当面はこちらでよいかと思いました。

今後 S3 などの別のストレージを利用する予定がある場合は、複数のクラウドストレージに対応している WP Offload Media Lite も捨てがたいと思います。

セットアップ時のトラブル

WP-Stateless を正常に動かすにあたっていくつか苦労したので記録します。

(1)そもそもちゃんと動かない

一番最初にハマった点です。画像アップロードしても Cloud Storage の方には一向に反映されません。いろいろ切り分けしたのですが、結果的には localhost 意外の名前を与えることで解決しました。

  • 動かなかった時: http://localhost:8000 でテスト中
  • 動いた時: http://dev.example.com:8000 でテスト中

結果論なので正確な事実ではないかもしれませんが、変化点がここでした。GitHub の Issue にも http://localhost だとうまく動かないんだが?的な記載が目についたので試した結果です。

確か、このようなメッセージだったはず。

WP-Stateless has the following notice:
Cloud not connect to Google Storage bucket. Please, be sure that bucket with name “バケット名” exists.

(2)Stateless モードでのみ動くがその他は全滅

Cloud Storage バケットの作成方法に問題があります。

今回やりたいことは、CDN モードでの動作でした。Cloud Storage にアップロードするだけの目的であれば Stateless モードでも問題ないのですが、EWWW Image Optimizer で WebP 変換したものをアップロードしようとすると CDN モードでなければならない成約があります。

で、CDN モードが何をやっても動かない。エラーログを探しても見当たらない(探し方が悪い?)。

いよいよ WP-Stateless プラグインを諦めて WP Offload Media Lite プラグインに乗り換え始めたところ、またもや失敗してしまいました。しかし WP-Stateless との違いは、なにやら怪しいエラーログを発見。

[Tue Jan 18 12:39:58.186463 2022] [php7:notice] [pid 32] [client 172.20.0.1:56204] AS3CF: Error offloading /var/www/html/wp-content/uploads/2022/01/2022-testImg.png to provider: {\n "error": {\n "code": 400,\n "message": "Cannot insert legacy ACL for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access",\n "errors": [\n {\n "message": "Cannot insert legacy ACL for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access",\n "domain": "global",\n "reason": "invalid"\n }\n ]\n }\n}\n, referer: http://dev.fand.jp:8000/wp-admin/upload.php

整形してみます。

{
  "error": {
    "code": 400,
    "message": "Cannot insert legacy ACL for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access",
    "errors": [
      {
        "message": "Cannot insert legacy ACL for an object when uniform bucket-level access is enabled. Read more at https://cloud.google.com/storage/docs/uniform-bucket-level-access",
        "domain": "global",
        "reason": "invalid"
      }
    ]
  }
}

結論、バケット作成時に「きめ細かい管理」というアクセス制御モードで作成する必要がありました。

「きめ細かい管理」とは何ぞや

画像引用 https://cloud.google.com/storage/docs/access-control?hl=ja

「均一」アクセスの方を推奨されていたので全く疑っていなかったのですが、WP-Stateless と WP Offload Media Lite いずれにおいても「きめ細かい管理」が必要でした。