AMIMOTO Advent Calendar の12日目です。
アイキャッチ画像は Cloudcraft で作ってみました。カコイイ!
WordPress の前段に CloudFront を置きたいことってありますよね。
そんな時、以下の様な問題に直面するかと思われます。
- ログイン時はプレビュー画面とか、即座に変わるようにキャッシュさせたくない
- Nginx のログファイルに CloudFront の IP アドレスではなく、アクセスしてきた PC の IP アドレスを記録したい
- モバイル版とPC版でテーマを切り替えたいんだけど…
- publish したときにちゃんと反映されるようにキャッシュ消したい
今日は、これらのお悩みを解決しちゃおうかなって感じです。
ログイン時はプレビュー画面とか、即座に変わるようにキャッシュさせたくない
CloudFront ではアクセス URL によってキャッシュ方法を変えたり、オリジンサーバを変えたりを Behavior ってところで設定することができます。
なので、以下の戦略で Behavior を設定してあげましょう。
- *.php へのアクセスは、ほぼノーキャッシュで
- /wp-admin/* は管理画面なので、こちらへのアクセスもほぼノーキャッシュで
- /wp-content/uploads/* 以下には、メディアファイルしかないはずだからキャッシュをきつく
- /wp-includes/*, /wp-content/* にも基本的には css, js, イメージファイルしか公開してないはずなのでキャッシュをきつく
- 他の URL へのアクセスについては、ログイン時と非ログイン時を Cookie で判断してキャッシュ
これを、AWS コンソールからポチポチと手で設定しても良いんですが、説明するのがめんどくさいし、手順書くのも億劫なので、aws-cli で cloudfront create-distribution しちゃうワンライナー作っておきました。
WordPress はサブディレクトリではなくルートにインストールされている前提です。
$ export origin_url='{ORIGIN URL HERE}'; export domain='{DOMAIN NAME HERE}'; aws cloudfront create-distribution --cli-input-json "$(curl -l -s https://raw.githubusercontent.com/amimoto-ami/create-cf-dist-settings/master/source_dist_setting.sh | sh)"
{ORIGIN URL HERE} にはオリジンサーバのドメインを書いてください。
IP アドレスで設定することが出来ないのでサーバ名を書く必要があります、EC2 1台だけの構成だとしても ELB 配下にしておけばよいでしょう。
{DOMAIN NAME HERE} には、公開 URL を書いてください。
なお、aws-cli では、デフォルトで aws cloudfront コマンドが使えないので ~/.aws/config の先頭に以下を追加しておいてから実行する必要があります。
[preview] cloudfront=true
上記のワンライナーで作った dogmap.jp の CloudFront 版は以下の URL からアクセスできます。
d2fe6jih9itgzn.cloudfront.net
あとは、僕が作った以下のプラグインを入れておくとプレビューリンクに post_date とかのクエリストリングが追加されるので、幸せになります。
https://gist.github.com/wokamoto/ecfd3a7ea9ef80ea1628
Nginx のログファイルに CloudFront の IP アドレスではなく、アクセスしてきた PC の IP アドレスを記録したい
Nginx の Real IP module を利用することで可能です。
これを設定すると特定の IP アドレスからのリクエストを X-Forwarded-For ヘッダの内容を元に変更してくれます。
参考URL: How to get the client IP when using CloudFront and nginx – Jayway
AMIMOTO で設定するなら、/etc/nginx/conf.d/00_real_ip.conf として以下のファイルを作成した後で service nginx restart して設定を反映してあげてください。
# Look for client IP in the X-Forwarded-For header real_ip_header X-Forwarded-For; # Ignore trusted IPs real_ip_recursive on; # VPC set_real_ip_from 172.31.0.0/16; # CloudFront set_real_ip_from 54.182.0.0/16; set_real_ip_from 54.192.0.0/16; set_real_ip_from 54.230.0.0/16; set_real_ip_from 54.239.128.0/18; set_real_ip_from 54.239.192.0/19; set_real_ip_from 54.240.128.0/18; set_real_ip_from 204.246.164.0/22; set_real_ip_from 204.246.168.0/22; set_real_ip_from 204.246.174.0/23; set_real_ip_from 204.246.176.0/20; set_real_ip_from 205.251.192.0/19; set_real_ip_from 205.251.249.0/24; set_real_ip_from 205.251.250.0/23; set_real_ip_from 205.251.252.0/23; set_real_ip_from 205.251.254.0/24; set_real_ip_from 216.137.32.0/19; # self set_real_ip_from 127.0.0.1/32;
なお set_real_ip_from 172.31.0.0/16; ってのは、EC2 や ELB が属している VPC の「VPC CIDR」で置き換えてください。
これで set_real_ip_from で指定した IP アドレスからのアクセスがあった場合は、nginx の設定ファイル内で使用している $remote_addr
と $binary_remote_addr
変数を HTTP ヘッダ X-Forwarded-For を元によしなに置換してくれます。
モバイル版とPC版でテーマを切り替えたいんだけど…
User-Agent ごとにキャッシュを作るように CloudFront で設定すれば良いんですが、そんなことしたらほぼノーキャッシュになってしまいます。
最初の手順で作った CloudFront ではオリジンサーバに対して、以下の HTTP ヘッダを送ってくれます。
- CloudFront-Forwarded-Proto
- CloudFront-Is-Desktop-Viewer
- CloudFront-Is-Mobile-Viewer
- CloudFront-Is-Tablet-Viewer
- Host
勘が良い人ならわかると思いますが、PC、スマートフォン、タブレットの User-Agent を CloudFront が判断して、それぞれ PC からのアクセスなら CloudFront-Is-Desktop-Viewer が true に、スマートフォンからのアクセスなら CloudFront-Is-Mobile-Viewer が true に、タブレットからのアクセスなら CloudFront-Is-Tablet-Viewer が true になります。
AMIMOTO では、PC・モバイルのテーマ切り替えには Nginx Mobile Theme プラグインを推奨しています。
参考URL: Nginx Mobile Theme – Nginxリバースプロキシ下で動作するモバイル用のテーマ切り替えプラグイン
この Nginx Mobile Theme プラグインで User-Agent ではなく、CloudFront-Is-Mobile-Viewer を使って切り替えるようにするには Nginx の設定ファイルを以下のように設定してください。
set $mobile ''; include /etc/nginx/mobile-detect; if ( $http_cloudfront_is_mobile_viewer = 'true' ) { set $mobile '@smartphone'; }
※ CloudFront-Is-Mobile-Viewer ヘッダの内容は nginx 内の $http_cloudfront_is_mobile_viewer 変数で確認できます。
publish したときにちゃんと反映されるようにキャッシュ消したい
これは、digitalcube からプラグイン出しましたので、それ使うのが簡単です。
使い方は、そのうち作者が解説してくれるでしょう。
C3 Cloudfront Clear Cache
それでは、良い CloudFront ライフを!