FastlyでWordPressのコンテンツをキャッシュさせてみる

Fastlyの学習のために、WordPressを使ってコンテンツ配信を行ってみます。
また[FastlyのWordPressプラグイン](https://ja.wordpress.org/plugins/fastly/)の設定方法も記述します。

## 前提
WordPressは以下のような構成にしています。

* WordPress on EC2
* WebサーバーとしてNginx
* DBはRDS(MySQL)

## WordPressの構築
今回はこれがメインではないので割愛します！
上記のような構成をいい感じに構築してください。

構築できたら、適当に記事などを投稿するとFastlyの効果がわかりやすいです。
自分の環境では、ChromeのDeveloper Toolで計測した感じだと以下のようなページ内容に仕上がりました。

![98155991f23a11099cc59379ba7cb817.png](https://qiita-image-store.s3.amazonaws.com/0/152303/0ad62463-ac91-2d4b-fc7f-15446f0c469d.png)


ページサイズ|レンダリング完了時間
---|---
1.2MB|718ms

## Fastlyの設定
Fastlyにログインすると、下記のような画面が現れるので必要項目を埋めていきます。
![ba849c5f94c34480e71662e3468b9b82.png](https://qiita-image-store.s3.amazonaws.com/0/152303/7dadb780-f547-3d0f-9f13-bd16beef5613.png)

Name|Description
---|---
Name|サービスの名前
Domain|閲覧したいドメイン。${好きな名前}.global.ssl.fastly.netで共有ドメインが使え、httpsが使える
Address|Originのアドレス
Enable TLS?|OriginでTLSを使うかどうか。今回は使わず行く

ここまで入力したらCREATEボタンを押して、先に進みます。
下記画面のClone Activeボタンを押します。
![550217067766ebabef3ee029390ba1ec.png](https://qiita-image-store.s3.amazonaws.com/0/152303/0355c5c4-95b6-471c-2d82-a0304db60337.png)

さて、設定画面です。ここで設定したい内容は以下の項目になります。

* コンテンツ圧縮
* 管理画面のキャッシュ無効化
* 管理画面のIP制限

### コンテンツ圧縮
Content -> Gzipsにいきます。
Setup Gzipを押し、適当な名前をつけCREATEをすると、コンテンツのGzip圧縮が有効になります。
どのContent Typeを圧縮有効にするかもこの画面で設定可能ですが、とりあえずデフォルトで行きます。

### 管理画面のキャッシュ無効化
管理画面はキャッシュしたくないので、キャッシュさせないようにします。
Settings -> Cache settingsにいきます。
Create your first cache settingを押しましょう。

![801025c3c03158163a32a5d236dc8f2b.png](https://qiita-image-store.s3.amazonaws.com/0/152303/5949ca54-36e3-720f-672f-de5ca6e4229c.png)

Name|設定内容
---|---
Name|no cache admin
TTL|0
Action|Pass(do not cache)
Stale TTS|0

Attache a conditionをクリック
キャプチャ撮り忘れたので入力項目だけ。

Name|設定内容
---|---
Name|isadmin
Apply if...| req.url ~ "^/wp-admin" &#124;&#124; req.url.ext ~ "(php)$

ここまでできたらCREATEしましょう。

### 管理画面のIP制限
管理画面は誰にも入ってほしくないので、IP制限をしたいものです。
もちろんFastlyでもそれはできます。

Custom VCLに行きます。
ただし、このCustom VCLは**Fastlyのサポートチームに連絡して使えるようにしてもらわないといけません。**
<https://docs.fastly.com/guides/vcl/uploading-custom-vcl>

サポートチームにメールする必要がありますが、日本語でも問題ありません。
対応はめちゃくちゃ早いです。さすがFastly！

さて、使えるようになったらUpload Your First VCL Fileをクリック。
名前は適当につけてもらって、実際のVCLの内容はこんな感じです。

```
acl myhome {
   "localhost";
   "自宅のIPアドレス"/32;
}

sub vcl_recv {
#FASTLY recv
  if (req.url ~ "^/wp-admin" && client.ip !~ myhome) {
    error 403 "Forbidden";
  }

  if (req.request != "HEAD" && req.request != "GET" && req.request != "FASTLYPURGE") {
    return(pass);
  }

  return(lookup);
}

sub vcl_fetch {
#FASTLY fetch

  if ((beresp.status == 500 || beresp.status == 503) && req.restarts < 1 && (req.request == "GET" || req.request == "HEAD")) {
    restart;
  }

  if (req.restarts > 0) {
    set beresp.http.Fastly-Restarts = req.restarts;
  }

  if (beresp.http.Set-Cookie) {
    set req.http.Fastly-Cachetype = "SETCOOKIE";
    return(pass);
  }

  if (beresp.http.Cache-Control ~ "private") {
    set req.http.Fastly-Cachetype = "PRIVATE";
    return(pass);
  }

  if (beresp.status == 500 || beresp.status == 503) {
    set req.http.Fastly-Cachetype = "ERROR";
    set beresp.ttl = 1s;
    set beresp.grace = 5s;
    return(deliver);
  }

  if (beresp.http.Expires || beresp.http.Surrogate-Control ~ "max-age" || beresp.http.Cache-Control ~ "(s-maxage|max-age)") {
    # keep the ttl here
  } else {
    # apply the default ttl
    set beresp.ttl = 3600s;
  }

  return(deliver);
}

sub vcl_hit {
#FASTLY hit

  if (!obj.cacheable) {
    return(pass);
  }
  return(deliver);
}

sub vcl_miss {
#FASTLY miss
  return(fetch);
}

sub vcl_deliver {
#FASTLY deliver
  return(deliver);
}

sub vcl_error {
#FASTLY error
}

sub vcl_pass {
#FASTLY pass
}

sub vcl_log {
#FASTLY log
}
```

VCLの書き方は、Custom VCL有効にするときにサポートチームから教えてもらえるのでそれ通りやりましょう！

### Activate
ここまでできたら、設定を反映します。上部にある「ACTIVATE」を押しましょう。

他のCDNサービスですと、こういう設定反映には時間がかかります。
アカマイだと早くて15分、CloudFrontだと体感ですが10分～20分はかかるでしょうが、
Fastlyはすぐに反映されます。
ちょっと設定ミスったときのリカバリーがすぐ出来るのがFastlyのいいところですね。

これでFastlyの設定は完了です。

## WordPressの設定
以下のドメインでFastlyが有効になったサイトが見れるはずです。
>https://hoge.global.ssl.fastly.net

しかしWordPressのサイトは見れないはずです。
WordPressの管理画面で設定してあるドメインと、上記ドメインに差異があるため元のドメインにリダイレクトされるはずです。
ということで、WordPressのサイトをFastlyの共有ドメインで見れるように設定していきます。

### Nginxの設定
Nginxのvhost設定で、Fastlyの共有ドメインを受けられるようにしておきます。

```
server_name hoge.global.ssl.fastly.net;
```

### wp-config.phpの設定
WordPressの設定ファイルである「wp-config.php」を修正します。
以下の設定をwp-config.phpに入れます。

```php
define('WP_HOME','https://hoge.global.ssl.fastly.net');
define('WP_SITEURL','https://hoge.global.ssl.fastly.net');

$_SERVER['HTTPS'] = 'on';
$_ENV['HTTPS'] = 'on';
```

ここまで設定を行ったら、またFastlyの共有ドメインにアクセスしてみましょう。
これでようやくFastly経由でWordPressサイトが見れるようになったはずです。

## FastlyのWordPressプラグインを設定する
記事投稿したときなど、記事一覧画面のキャッシュが消えてくれないと困ります。
その問題を解決するために、[FastlyのWordPressプラグイン](https://ja.wordpress.org/plugins/fastly/)を導入します。

その前にWordPressからFastlyのAPIを呼び出す必要があるので、APIキーを発行します。
Fastlyの管理画面からAccount -> Personal API Tokensへ行きます。
そしてCreate Token。下記のように入力してください。

![94ff0b0e05709169d0869b85670df1b8.png](https://qiita-image-store.s3.amazonaws.com/0/152303/35b38a20-8d13-1fdb-1bca-98571e589a17.png)


で、ここで発行されるAPIキーをメモります。
またサービスIDというものが必要になりますが、それはFastlyのダッシュボードに行けば記載されてます。

APIキーとサービスIDをメモったら、WordPressのFastly管理画面に行きます。
FastlyプラグインをWordPressの管理画面で有効化するのを忘れずに。

下記画面にAPIキーとサービスIDを貼り付けて保存しましょう。

![0b313548689280c9a11d81d2618f778f.png](https://qiita-image-store.s3.amazonaws.com/0/152303/547defec-4bc7-6d68-0fbe-f7ba134b2510.png)

保存したら、「TEST CONNECTION」を押して疎通確認してください。
「Connection Successful on service \*fastly test\*」と表示されたら疎通おｋです！

続いてFastlyの管理画面以外でも、WordPressの管理画面でもPurge出来るような設定を行います。
下記画面のように「Allow Full Cache Purges」をYesにしてください。
![c604e81e936de5d1fd574d9aa0229fb2.png](https://qiita-image-store.s3.amazonaws.com/0/152303/79597548-b1e1-c9cf-45fe-ba5910c45f71.png)

これで保存すると、下記のPurgeボタンが使えるようになります。
![9fb8d1f6ef23792523998af11811080b.png](https://qiita-image-store.s3.amazonaws.com/0/152303/369aee51-2cd4-7858-9fb6-511b186f8769.png)

ここまで出来たら、プラグインの設定も終わりです。
動作確認をしていきます。

### 動作確認
WordPressの管理画面からはログアウトしておきます。

次にhttpのrequest headerに「Fastly-Debug: 1」をつけるようにします。
これはChromeの拡張機能などを使用してつけてください。

これをつけ、サイトのトップページにアクセスするとResponse Headerに下記のような項目が現れます。

```
Surrogate-Control:max-age=86400, stale-while-revalidate=86400, stale-if-error=86400
Surrogate-Key:p-12 p-10 p-8 p-1 tm-home
```

Surrogate-KeyはキャッシュのIDのようなもので、このIDがページに振られていれば
FastlyのWordPressのプラグインは正常に機能しています。

このSurrogate-Keyを指定してキャッシュのパージを行うことも可能です。
実際このFastlyのWordPressプラグインでも、記事投稿時に自身の記事のSurrogate-KeyとトップページのSurrogate-Keyを指定して削除しています。
これにより、いちいち手動でキャッシュをパージしなくてもプラグインがよしなにキャッシュをパージしてくれます。

ではその動きを確認します。
適当に新しい記事を投稿してみましょう。キャッシュが有効になっているにもかかわらずトップページに新しい記事が表示されるはずです。
このキャッシュパージの早さ(約150ms)がFastlyの特徴の一つです。

## 最後に
これでFastlyでWordPressのコンテンツをキャッシュさせることが出来ました。
速さはどれくらい変わったんでしょ？

Before:

ページサイズ|レンダリング完了時間
---|---
1.2MB|718ms

After:

ページサイズ|レンダリング完了時間
---|---
70.4KB|352ms

コンテンツ圧縮もしてるためページサイズも減少、レンダリングも早くなりました！

Fastlyはパージと設定反映が非常に高速です。
頻繁に更新を行うサイトとの相性がとてもいいので、ブログサイトにも適用しやすいのでおすすめです。

## 参考資料

* [WordPressにFastlyのPlugin(Purgely)をインストール](https://qiita.com/AtsushiFukuda/items/a168e08c19a5cd413760)