Wordpressの画像ファイルをS3に保存する(メディア機能連携)
このblogは2015/6現在、Wordpressで書いています。
画像表示はWordpressのメディア機能を使っています。この機能を使うとWordpressが動いてるサーバ内のwp-contents/uploadsディレクトリ内に画像を保存し、その画像を記事内表示できるようになります。
今回はこの画像をサーバ内ではなく、AWS S3に保存しようという記事です。後半は移行作業の話が出てくるので少し玄人向け(SQLへの理解が必要)です。
S3へ保存する理由
多分ほとんどの場合、S3へ保存しないでも良いと思います。普通にサーバ内保存で事足ります。ただ、以下のようなケースでは必要になってくるかと思います。
- Wordpressが動くサーバを複数台で構成(+LB)していて、どれか1台にだけ画像ファイルが保存されると困るケース
- Wordpressをdocker containerとして動かし、Immutableを実現しているので、画像ファイルが消えると困るケース
S3へ保存するプラグイン
WordPressメディアへ画像をアップロードすると自動的にS3へ保存する・・・。
自前で同期するスクリプトを書いたりしても良いですが、これを実現するプラグインがあります。
他にもいくつかあるようですが、この2つのどちらかが良いと思います。
Amazon S3 and Cloudfrontは今回自分で利用して上手く行っていますし、公式上での評価が高いです。
Nephila clavataは日本人が開発しており、解説サイトもあります。最近もアップデートされました。また後述する移行の部分の話にあるように、Nephilaの方が一部の機能が使えて良いです。
今回はAmazon S3 and Cloudfront pluginを利用したので、こちらで解説します。
Amazon S3 and Cloudfront pluginの設定
実はこれについては詳しく解説されているサイトが既にあります。
AWS CloudFrontを使ってWordPressのメディアファイルだけS3に配置する
基本こちらに従えば良いです。一応、このページでも簡単に解説します。
おおまかな手順は以下の通りです。
- Plugin管理ページからAmazon Web Servicesプラグインをインストールする(以下のプラグインの前提になってます)
- Plugin管理ページからAmazon S3 Cloud Frontプラグインをインストールする
- Wordpress管理画面にAWSというリンクが表示されるので、設定ページへ飛ぶ
- AWSのAccess Key IDとSecret Access Keyを登録する(セキュリティを気にする場合はwp_configに書きましょう)
- Amazon S3 Cloud Frontの設定ページへ飛ぶ
- 画像ファイルの保存先であるバケットを選択する (自分の場合は画像はCloudFrontを通して配布する予定だったので”CloudFront or custom domain”を選択してCloudFront用に作成しておいたdomainである”resources.tech-blog.tsukaby.com”を入力しました。)
使ってみる(テスト)
この状態でメディア機能を使って画像をwordpressにアップロードすると、S3に画像が保存されるとともに、そこへのリンクが貼られるはずです。
試しにやってみるとこんな感じになります。
URLの部分に注目していただきたいのですが、通常ここはwp-contents/uploads/…となるはずですが、先ほど設定したresoruces.tech-blog.tsukaby.comになっています。自分はcustom domainを入れているのでこうなりますが、バケットを選択した人はそのバケットのURLになっていると思います。
S3の方を見てみると
このように正しく格納されていることがわかります。
当然ですが、上記のプラグインが画像ファイルをS3にputするので、プラグインで設定したAWSのIDに対してS3の参照・登録権限が無いとうまくいきません。IAM調整しましょう。
過去ファイル移行の問題
上記の設定でうまくいきます。これでWordpressを複数台で分散構築してようが、Wordpressサーバを作り直ししようが、画像まわりは問題が無くなります。
ただ、プラグインを途中から使い始めた人は過去の画像データについて考慮する必要があります。
Amazon S3 CloudFrontプラグインは過去の画像ファイルまでS3に保存してくれる、というようなことはしてくれません。過去の画像ファイルへのパスは従来通りwp-contents/uploadsへのリンクとなっています。
ですので完璧にS3へデータ移行するのであればDB上のデータを操作する必要があります。
ここでもう無理だわ、と思った人は素直にNephila clavataを使うと良いと思います。こちらは試していませんが、どうやら過去のデータにも対応しているようです。(過去データにアクセスがあった時点でwp-contents/uploadsに保存されているものの場合、自動で移行してくれる。っぽい)
Amazon S3 CloudFrontプラグインも一応過去データに対応するようですが、それはProfessionalプラン?だとか別の何かが必要なようです。
過去ファイルの移行
上記の問題があるので、ここからは手動で過去データの移行を行います。
まず、wp-contents/uploadsにあるファイルを全てS3上に移動します。
これは単にwp-contentsフォルダごとごっそりaws s3 cpするなりして移動するだけなので簡単かと思います。問題はDBの方です。
WordpressはMySQL DBにデータを保存します。いくつかテーブルがありますが、重要なのは以下です。
- wp_posts
- wp_postmeta
wp_postsはpostデータを格納するテーブルです。WordPressでは記事のテキストだけでなく、メディア機能でUploadした画像ファイルなどもpostデータ扱いです。ただし画像は画像へのリンクなどの情報が入るのであって、バイナリは別です。
wp_postmeaはpostデータのメタデータを格納するテーブルです。上記のプラグインはこのテーブルにデータを追加します。
1度上記プラグインをONにして、画像をUplaodしてみると分かりますが、meta_key = ‘amazonS3_info’というものがwp_postmetaに追加されていると思います。このレコードこそ、上記プラグインが利用するデータです。
meta_valueはこんな感じになっていると思います。
a:3:{s:6:"bucket";s:31:"resources.tech-blog.tsukaby.com";s:3:"key";s:63:"wp-content/uploads/2015/06/069a5367d28a64e4509cfc089df491bc.png";s:6:"region";s:14:"ap-northeast-1";}
後はもうお分かりかと思いますが、このようなレコードを既存の画像ファイルの分だけINSERTしてやればOKです。少々INSERT文を作るのが面倒ですが、SQLのSELECTなり、Excelなり工夫すれば出来るかと思います。ちなみに「なんかよく分からんjson形式っぽい」データで入っていると思うかと思いますが、難しいことはありません。s:63などとなっている部分は「Stringで63文字」という意味だったりa:3となっている部分は「Arrayで3個」という意味ですので、適宜INSERTするものにあわせて変えればOKです。
参考までに自分が作ったINSERT文生成SQLを載せておきます。
select CONCAT('insert into wp_postmeta(post_id, meta_key, meta_value) values(', post_id, ', \'amazonS3_info\', \'a:3:{s:6:\"bucket\";s:31:\"resources.tech-blog.tsukaby.com\";s:3:\"key\";s:', length(meta_value), ':\"wp-content/uploads/', meta_value, '\";s:6:\"region\";s:14:\"ap-northeast-1\";}\');') AS record from wp_postmeta where meta_key = '_wp_attached_file' <br>
こんな感じでINSERT文を作ってあげてから、それを実行します。
後は、過去の投稿記事内の画像へのhrefとsrcは古いURLになっていると思います。なので、それも置換して新しいS3のURLにします。参考までに自分が利用したSQLを載せておきます。
update wp_posts set post_content = replace(post_content, 'src="http://tech-blog.tsukaby.com/wp-content/uploads/', 'src="http://resources.tech-blog.tsukaby.com/wp-content/uploads/');
以上で移行作業は完了です。お疲れさまでした。
まとめ
- S3上に画像ファイルを保存するWordPressプラグイン Amazon S3 and CloudFrontプラグインを紹介しました。
- セットアップ手順と使用例を説明しました
- 過去データの問題と移行手順について説明しました
- 移行作業が難しい人にはNephila clavataをオススメします
それでは快適なWordPressライフをお過ごし下さい