CloudFrontでドメインルートをS3にして、サブディレクトリをWordPressにした場合の注意点と解決策
CloudFrontでドメインルートをS3にして、サブディレクトリをWordPressにした場合の注意点と解決策
ハロウィンは家にこもってゆるゆりを見ていました森永です。
今回はタイトルをどうしようかすごく迷いましたが、困っている方がいらっしゃると思うのでド直球なタイトルにしてみました。
問題の構成
今回の問題の前提は以下の通りです。
- CDNにCloudFrontを使用してリバースプロキシとしている
- ドメインルート
example.com
はS3に向ける example.com/blog/*
はWordPressを構築したEC2に向ける(ELBを挟んだ場合も同様)- WordPress側で
blog
というスラッグを作成している
- WordPress側で
CloudFrontの設定はこんな感じです。
S3とEC2(もしくはELB)をOrigin登録して、Behaviorで振り分けます。
想定としては、コーポレートブログをS3に置いていて、後になってブログを開設したくなったのでWordPressを使おう!といったものが考えられます。
結構ありそうな状況ですよね。
問題点
見る側からすると問題はありません。(もし何かあればコメントで教えて下さい。)
記事を編集する側がある操作をした際に大きな問題が発生します。
それは、未公開の記事をプレビューしたい時です。
こいつの原因は明確です。プレビューのURLにサブディレクトリが含まれないからです。
example.comの例で行くと、WordPressの公開記事はhttp://example.com/blog/hogehoge
といったURLとなります。
これだとCloudFrontでちゃんとWordPress側に振り分けられます。
ところが、未公開記事をプレビューするとhttp://example.com/?p=番号&preview=true
というURLになってしまいます。
/blog
どこ行った!!
こいつの厄介なところは、ドメインルートのあとにすぐクエリストリングが来ている点です。
CloudFrontではクエリストリングによるBehavior設定は出来ないので、preview=true
などで振り分けられないのです。
解決策
サブディレクトリではなくサブドメインにしましょう!!!!
と言いたいのですが、そうも行かないこともありますよね。。。
出来るのであればサブドメイン形式blog.example.com
をオススメします。
気を取り直して、サブディレクトリ形式での解決方法。
プレビューのURLが問題になっているので、プレビューのURLを書き換えちゃいましょう!
簡単に言うなと思われるかもしれませんが、WordPressにはfunction.php
というファイルがあり、そこにコードを書けばWordPressの機能をHookできるのです。
こいつを使う方針で行きます。
(.htaccessでRewriteする手も考えたのですが、最初にS3に見に行ってしまうのでそもそものURLを変えないと無理でした…)
以下のコードをwp-content/themes/function.php
に追記します。
/*プレビューのURL修正*/ function my_update_post_link($link) { $post_type_rewrite = get_post_type_object(get_post_type())->rewrite; $link = preg_replace('/\?/', $post_type_rewrite['slug'].'/?', $link); return $link; } add_filter('preview_post_link', 'my_update_post_link'); function my_post_updated_messages($messages){ $post_type_rewrite = get_post_type_object(get_post_type())->rewrite; $messages['post'][8] = preg_replace('/\?/', $post_type_rewrite['slug'].'/?', $messages['post'][8]); $messages['post'][9] = preg_replace('/\?/', $post_type_rewrite['slug'].'/?', $messages['post'][9]); $messages['post'][10] = preg_replace('/\?/', $post_type_rewrite['slug'].'/?', $messages['post'][10]); return $messages; } add_filter('post_updated_messages', 'my_post_updated_messages');
上記でやっていることを簡単に言うと、プレビューのURLの?
をスラッグ/?
に書き換えているだけです。
今回はblog
というスラッグを作成しているので、?
はblog/?
に書き換えられて見事CloudFrontで振り分けできるURLとなるわけです。
最後に
結構前にやったときに起きた問題だったんですが、最近になって同僚に質問されたので備忘としてまとめてみました。
こういうTips結構重要なんですよね…(再現しても次やった時忘れている問題)
他に今回の構成で問題になるところがあればコメント頂けると幸いです。