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で取得したものを設定します。キャッシュの設定は通常のページと管理画面と分けるので、デフォルトだけ以下のように設定し、後で追加で設定します。
デフォルトのキャッシュ設定
- Viewer Protocol Policy
SSLを使用する場合は、Redirect HTTP to HTTPSを選択します。 - Allowed HTTP Methods
GET, HEAD - Cache and origin request settings
Use legacy cache settings - Cache Based on Selected Request Headers
WhiteList - Whitelist Headers
CloudFront-Forwarded-Proto, Hostが最低限必要です。 - Object Caching
nginx-proxyの設定を使用するので、Use Origin Cache Headers - Forward Cookies
comment_author_*, wordpress_logged_in_*, wordpress_test_cookie*, wp-settings-* - Query String Forwarding and Caching
Forward all, cached based on all
/wp-admin/*, *.php, /wp-json/* のキャッシュ設定
admin画面がキャッシュされないよう/wp-admin/*, *.php, /wp-json/* 用のbehaviorをそれぞれ作成します。下記項目以外はデフォルトと一緒です。
- Allowed HTTP Methods
GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE - Whitelist Headers
CloudFront-Forwarded-Proto, Host
/wp-json/*にはX-WP-Nonceも必要です。(無いとブロックエディタ等が使えなくなります。) - Object Caching
Custom
Minimum TTL/Maximum TTL/Default TTL全て0にします。 - Forward Cookies
All
Route53の設定を変更
最後にRoute53の設定を変更して、CloundFrontのドメインを設定すれば完了です。サブドメインの場合は普通にCNAMEレコードで設定すれば良いですが、トップドメインの場合はCNAMEが使えないので、Aレコードを使用し、エイリアスにすることで、CloundFrontが選べるようになります。