CloudFrontをWordPress用にセットアップ

CloudFrontを使用すれば、キャッシュも効くのでEC2のリソースを消費は最低限でWordPressを運用できます。さらにSSLも更新を気にせず無料で使用できます。

nginx-proxyの設定

nginx-proxyでExpiresヘッダを指定し、キャッシュの有効期間をコンテンツごとに指定します。CloudFrontでも設定することはできますが、条件ごとにルールを作成しないといけないため、nginxで指定した方が簡単です。
またCloudFrontでSSLを使用する場合は、CloudFrontとEC2間はHTTPでの通信になるので、適当な設定をしないと一部コンテンツがHTTPで配信されたり、リダイレクトループが起きてしまう可能性があります。

キャッシュの設定はCloudFrontを使用し始めた後でも良いですが、SSLを使用する場合の設定はCloudFront使用前に変更する必要があります。

Expiresヘッダの指定

/etc/nginx/conf.dに以下の内容のファイルを追加します。
数値やファイル名はお好みで。text/htmlを1秒キャッシュさせることで最大各ページ1秒に一回しかアクセスがこなくなるので、貧弱なインスタンスでも問題なく大量のアクセスを捌けるようになります。

map $sent_http_content_type $expires {
    default  off;
    text/html 1s;
    text/css 7d;  
    test/javascript 7d;
    ~image/ 7d;
}

expires $expires;

SSL用の設定の追加

フロントエンドのサーバーへのプロトコルは通常X-Forwarded-Protoを参照すれば取得できます。X-Forwarded-Protoがhttpsの場合、WordPressやapacheでHTTPS=onを設定すれば良いのですが、dockerのWordPressはデフォルトでこの設定が入っています。
ただしCloudFrontへのプロトコルはなぜかX-Forwarded-Protoではなく、Cloudfront-Forwarded-Protoに入っているので、これをX-Forwarded-Protoに変換する必要があります。

proxy用のヘッダは/etc/nginx/proxy.confに記述します。11行目以降が、CloudFront用の設定ですが、このファイルがあると、デフォルトの設定がなくなるので、10行目までも必要になります。

# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
map $http_cloudfront_forwarded_proto $proto{
    default $proxy_x_forwarded_proto;
    ~.+ $http_cloudfront_forwarded_proto;
}
proxy_set_header X-Forwarded-Proto $proto;

docker-compose.ymlの変更

設定をコンテナに反映するため、前述のファイルをbind mountします。

services:
   nginx:
      container_name: nginx_proxy
      image: jwilder/nginx-proxy:alpine
      ports:
        - 80:80
        - 443:443
      volumes:
        - /var/run/docker.sock:/tmp/docker.sock:ro
        # - ../lego/lego/certificates:/etc/nginx/certs
        - ./nginx/proxy.conf:/etc/nginx/proxy.conf
        - ./nginx/conf.d/expire.conf:/etc/nginx/conf.d/expire.conf
      restart: always
      logging:
        options:
          max-size: 5m
          max-file: "10"

ドメインのネームサーバーをRoute53に変更

Route53でホストゾーンを作成し、Aレコード(トップドメインの場合)、もしくはCNAMEレコード(サブドメインの場合)をec2へ割り当てます。レジストラの設定でネームサーバーをRoute53に変更すると、そのドメインでAWSへとアクセスできるようになります。
ドメインの変更が反映されるのは最大3日程度とかなり時間もかかって、その間テストもうまくできなくなります。
またこの時点でSSL化はできていないので、すでにSSL化しているサイトはlegoなどでフリーの証明書を取って一時的にそれを使用したりする必要があるかと思います。

ACMで証明書を取得する

AWS Certificate Manager(ACM)で証明書を取得します。ACMの証明書をCloudFrontで使用する場合には米国東部 (バージニア北部)リージョンで証明書を取得する必要があります。Route53がネームサーバーになっている場合は、ドメイン検証のためのステップが簡単になります。
DNS を使って AWS Certificate Manager の検証を簡単に 

CloudFrontの設定

OriginをEC2のDomain、SSL CertificateをCustomにして、ACMで取得したものを設定します。キャッシュの設定は通常のページと管理画面と分けるので、デフォルトだけ以下のように設定し、後で追加で設定します。

デフォルトのキャッシュ設定

/wp-admin/*, *.php, /wp-json/* のキャッシュ設定

admin画面がキャッシュされないよう/wp-admin/*, *.php, /wp-json/* 用のbehaviorをそれぞれ作成します。下記項目以外はデフォルトと一緒です。

Route53の設定を変更

最後にRoute53の設定を変更して、CloundFrontのドメインを設定すれば完了です。サブドメインの場合は普通にCNAMEレコードで設定すれば良いですが、トップドメインの場合はCNAMEが使えないので、Aレコードを使用し、エイリアスにすることで、CloundFrontが選べるようになります。

モバイルバージョンを終了