WordPress の前段に CloudFront を配置する ( AMIMOTO Advent Calendar 2015 12日目 )

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 ライフを!

コメントを残す

メールアドレスが公開されることはありません。