AWSに構築したWordPressをCloudFrontを使ってキャッシュして高速化【CDN】

AWSに構築したWordPressをCloudFrontを使ってキャッシュして高速化【CDN】 開発
スポンサーリンク
前提としては、VPC、EC2インスタンスの作成や、ドメイン取得、ACMでのSSL証明書の作成が完了していること。
お名前.comでドメインを取得してAWSのELBを使ってSSL化(https)の対応をするACMでSSL証明書の発行までやってもらえば前提はクリアするのでよしなにどうぞ。

CloudFrontから配信することにより、WordPressサイトの高速化が可能。

AWSでWordPressを構築しているなら、SSL(https)の対応をする場合、ELB(ALB)に証明書を設定するか、CloudFrontに設定するかになることが多いが、本記事では「CloudFront」を使ってSSL(https)の対応をする。

CloudFrontだけでは賄えないくらいアクセスが増えてきたら、ELB(ALB)を挟んで CloudFront <-> ELB(ALB) <-> EC2(WordPress)とするとスケーリングもできるのでオススメ。

WordPressを高速化!CloudFrontでキャッシュする構築手順

CloudFrontを構築する

  1. CloudFrontでディストリビューションを作成。
  2. オリジン
    1. オリジナルドメインはEC2インスタンスの「パブリックDNS(IPv4)」を入力する。
    2. パブリックDNSが付与されてない場合は、パブリックDNSを付与する設定をする。※付与されている場合はこの手順は不要。
      1. VPC画面でお使いのVPCを選択してDNSホスト名、DNS解決の両方が有効になっていることを確認する。
      2. どちらかが有効になっていない場合は、有効になってないものを アクション > DNS ホスト名を編集 、 DNS 解決を編集 で有効化をチェックし変更を保存する。
    3. プロトコルは「HTTPのみ」を選択する。構成としては、ブラウザ <- https -> CF <- http -> EC2 になるが、CFからはAWS内のネットワークなのでhttpでも問題ない。
    4. その他はデフォルトのまま。
  3. デフォルトのキャッシュビヘイビア。
    1. パスパターンは「デフォルト(*)」。
    2. ビューワープロトコルポリシーはhttp -> httpsリダイレクトをするように「Redirect HTTP to HTTPS」を選択。
    3. 許可された HTTP メソッドは「GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE」を選択する。
    4. キャッシュキーとオリジンリクエストは、「Leagacy cache settings」を選択し、ヘッダー「Host, CloudFront-Forwarded-Proto」、クエリ文字列「すべて」、cookie「指定されたcookieを含める」→許可に「wordpress_logged_in*」を入力する。
      1. ヘッダーは、Origin側にアクセス先のホストを通知するのに「Host」を使い、HTTPSの判定で「CloudFront-Forwarded-Proto」を使う。
      2. クエリ文字列は、検索やコメント、ページ遷移でつかうので含めないとうまく動かない場合はある。
        1. クエリパラメータでページ遷移してる場合は、「{ドメイン}/?p=1」でアクセスしてもキャッシュされるのは「{ドメイン}/」になるので、記事ページが表示されずに、記事をクリックしてもキャッシュされている「{ドメイン}/」が返却され、トップページが表示されることになる。
        2. SiteGuadeのプラグインを使っている場合は、クエリ文字列を含めないと、ログアウトしてもログイン状態が保持される状態になる。
      3. cookieは、ユーザが記事を表示するには必要ないが、管理画面にログインしているかをcookieの「wordpress_logged_in*」をみて判定しているので、含めないと管理画面にログインできなくなる。
    5. その他はデフォルトでOK。
  4. 関数の関連付け – オプションは、デフォルトのまま。
  5. 設定
    1. 代替ドメイン名 (CNAME)はドメインを追加する。
    2. カスタム SSL 証明書はACMで作成したSSL証明書を選択する。
      1. SSL証明書が選択肢に出てこない場合は、ACMの証明書が「バージニア北部」で登録されているか確認する。
    3. その他はデフォルトのまま。
  6. 入力内容を確認して、ディストリビューションを作成。
  7. ステータスが有効になるのをまって完了。

管理画面(wp-admin)をキャッシュしないようにする

管理画面はキャッシュすると動かなくなる時があるのでキャッシュ対象外にする。

キャッシュ対象外にする方法

  1. ビヘイビアを作成
  2. パスパターンにキャッシュ対象外にしたいパス「/wp-admin/*」を入力。
  3. オリジンとオリジングループは、ec2インスタンスのオリジンを選択。
  4. ビューワープロトコルポリシーは「Redirect HTTP to HTTPS」を選択。
  5. 許可された HTTP メソッドは「GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE」
  6. キャッシュキーとオリジンリクエストは「Legacy cache settings」をチェックし、ヘッダー「すべて」、クエリ文字列「すべて」、cookie「すべて」、オブジェクトキャッシュ > Customizeをチェックし、最小/最大/デフォルト TTLを「0」に設定。
  7. その他はデフォルトのまま。
  8. 入力内容を確認して、ビヘイビアを作成。

動的コンテンツである「*.php」もキャッシュ対象外としたほうがいいので、上記手順でビヘイビアを追加で作成する。

ビヘイビアの優先順位が追加作成されたものがデフォルトの上に設定されていればOK。

ドメインの接続先をCloudFrontに変更する

  1. Route53でドメインAレコードのトラフィックのルーディング先を、CloudFrontに変更する。
  2. Aレコードを選択してレコードを修正で、エイリアスをONにし、トラフィックのルーティング先をCloudFrontに設定するして保存。
  3. 環境変数のHTTPSをonにするために、wp-config.phpに処理を追加する。CloudFrontでリクエストヘッダーに追加した「CloudFront-Forwarded-Proto」を見てHTTPSにするかの判定処理を入れる。※CloudFrontは「HTTP_X_FORWARDED_PROTO」ヘッダーを削除するので、追加した「HTTP_CLOUDFRONT_FORWARDED_PROTO」を使う。
    if (isset( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] === 'https') {
      $_SERVER['HTTPS'] ='on';
    }
    
  4. WordPressアドレス、サイトアドレスをhttpsに変更する。管理画面にログインできれば管理画面から変更でOKだが、ログインできなければ、wp_optionsの「siteurl」「home」の値を変更。

CloudFrontのキャッシュがヒットしてるかの確認方法

キャッシュされているかの確認は、デバッグモードなりでレスポンスヘッダーの「x-cache」を見る。

ステータスとしては

  • キャッシュがヒットしたとき:Hit from cloudfront
  • キャッシュがヒットしてないとき:Miss from cloudfront

となる。

トップ記事一覧、CSSで確認すると、初回アクセス時は「Miss from cloudfront」となっているが

再度サイトを更新すると、「Hit from cloudfront」となっていることが確認できる。

CloudFrontのキャッシュを削除する方法

  1. CloudFrontのキャッシュ削除は、対象のデストリビューションを選択し、キャッシュ削除タブから「キャッシュ削除を作成」。
  2. ルート直下から全てのキャッシュを削除する場合は、「/*」とし、キャッシュ削除を作成。特定のパスをしていすることもできる。
  3. ステータスが完了済みになればOK。

CloudFrontからのリクエストのみEC2で受け付けるようにする

EC2のパブリックDNSやパブリックIPアドレスでアクセスすると、http通信としてWordPress画面が表示されてしまい、CloudFrontを挟むことでレイテンシーの削減や、(DDoS) 攻撃の対策をしているのにこのままではよろしくない。

Amazon CloudFrontデベロッパーガイドの、リクエストにカスタムHTTPヘッダーを追加するための CloudFront 設定を参考に、カスタムヘッダーをCloudFrontに付与して、EC2(Apache)側でヘッダーを見て、リクエストを受け付けるか否かの判定処理を追加し、CloudFrontからのリクエストのみ受け付けるようにする。

CloudFrontにカスタムヘッダーを追加してApacheで判定をする

    1. httpd.confのルートディレクトリアクセス時の設定(デフォルトだとDirectory”/var/www/html/”)に、カスタムヘッダーが設定されているリクエストのみ受け付けるように処理を追加する。
      # Further relax access to the default document root:
      <Directory "/var/www/html/">
          Options Indexes FollowSymLinks
          Require all granted
      
          # ここから追加
          # CloudFrontからのみアクセスできるようにする。
          SetEnvIf {カスタムヘッダー名} "{値(ランダムな英数字)}" CustomVal
          # 例:SetEnvIf X-Custom-Header "jfowpF850wDFEdefe" CustomVal
          Order deny,allow
          Deny from all
          Allow from env=CustomVal
          # ここまで
      
      </Directory>
      
    2. Apacheを再起動。
      sudo service httpd restart
    3. この状態で「ドメイン」、「パブリックIP」にアクセスすると下記のようになる。
      1. ドメインアクセス:「Forbidden」画面
      2. パブリックIPアクセス:「Forbidden」画面
      3. Test Pageが表示される場合は、Apacheバージョンが表示されてしまいセキュリティー的によろしくないので、AWSでWordPress構築をしたらやるべきセキュリティ対策【Apache】を参考に、Test Pageが表示されないように設定しておくとよい。
    4. CloudFrontの設定をする。オリジンを選択し、編集画面を表示する。
    5. カスタムヘッダーを追加で、httpd.confに設定した、カスタムヘッダー名と値(ランダムな英数字)を設定して変更を保存
    6. サイトを更新して「ドメイン」、「パブリックIP」にアクセスすると下記のようになればOK。
      1. ドメインアクセス:正常にWordPressで構築したサイトが表示
      2. パブリックIPアクセス:「Forbidden」画面

ハマりポイント!ホームページを固定ページにしたら301リダイレクトループ

よくある設定だと思いますが、ルートドメインにアクセスしたら「HOME」用の固定ページを表示する。

この設定に変えた瞬間に、記事ページにはアクセスできるが、ホームページにアクセスすると301リダイレクトループが発生。


エラーメッセージ:「ERR_TO_MANY_REDIRECTS」

301リダイレクトループの解決方法

解決方法としては、CloudFrontのリクエストヘッダーに「Host」を追加する。
※上記の手順通り設定してもらえば問題ないが、リダイレクトループになってしまったら今一度リクエストヘッダーの設定を確認してみてほしい。

WordPressはホスト名(SiteURL)を自身で管理しているので、クライアントからHTTPS接続だよーと通知してあげる必要がある。

なのでHostが通知されないと、ひたすらリダイレクトループになります。

クラシックエディターのビジュアルモードが表示されない

WordPress はUser-Agentヘッダを判別して、ビジュアルエディターを起動している。
CloudFrontはオリジンに転送するリクエストを削減するため、HTTP リクエストヘッダーから一部のヘッダーを削除あるいは更新する。

なので、管理画面(wp-admin)をキャッシュしないようにするのヘッダーで「すべて」を設定すれば解消する。

スポンサーリンク

コメント

タイトルとURLをコピーしました