WordPress on AWS構築の備忘録

AWS上でWordPress環境を構築した時の備忘録を残しておきます。

主に利用しているマネージドサービスはCloudfront+ELB+EC2+RDS。よくあるタイプですが、CloudfrontとELBの両方を設置している記事があんまりないので、もしかしたら誰かの役に立つかもしれません。


■現在のWordPress on AWS構成図


■1.最小構成でLAMP環境をつくる

最初から↑のような構成を描いて環境を作った訳ではありません。自分一人でまともにLAMPすら構築した事がなかったので、勉強の意味も込めて一から立ち上げました。

参考ページが非常に良くまとまっていたので、何の苦もありませんでした。WordPressのようなインターネットに公開するWebサーバをAWSで立てる以上、VPCとSecurity Groupの活用は不可欠だと思います。

また、SSHログインのシェル化・SGの変動IP穴開け方法は以下のページが大変参考になりました。


■2.WordPressのインストール・初期設定、ELB・Cloudfrontの設置

私の場合、WordPressの初期設定でハマりました。Web/APサーバからmysqlコマンドでRDSに入れるのに、WPの設定画面でDB接続エラーが出たからです。

結局はOS(Redhat)のSELinuxが原因でしたが、その過程もメモしておきます。

原因切り分けのために、

  1. WPのデバッグモードを有効化 →

    wp-config.phpdefine(‘WP_DEBUG’, true);をぶちこむ

  2. DB接続のみの簡易phpの作成 → ドキュメントルート直下に置いてテスト
<?php
$link = mysql_connect('<RDSのエンドポイント名>', '<DBユーザ名>', '<パスワード>');
if (!$link) {
die('データベースにこの情報では接続できませんでした: ' . mysql_error());
}
echo 'ちゃんとデータベースに接続できるようです';
mysql_close($link);
?>

を実施しました。

WPのデバッグでは案の定、phpのmysql_connectでエラーを吐いてました。

Warning: mysqli_real_connect(): (HY000/2003): Can't connect to MySQL server on '<RDSのエンドポイント名>' (13) in /var/www/html/wordpress/wp-includes/wp-db.php on line 1531

Warning: mysql_connect(): Can't connect to MySQL server on '<RDSのエンドポイント名>' (13) in /var/www/html/wordpress/wp-includes/wp-db.php on line 1562

こんなエラーが出た上、php単体のDB接続テストもNGだった訳です。これでWP側には問題が無い事が分かりました。

Web/APサーバのコンソールからは接続できるので、AWS上のセキュリティ(SG)も問題ないと判断。じゃぁ何なんだ???となって色々調べた結果、SELinuxに行き着いた訳です。

思い切ってSELinuxをまるごと無効にする事も考えましたが、ここまで調べてそうするのも何か負けた気がするので、どのブール値がアヤシイのか調べるみると、httpd_can_network_connect_dbの仕業だったのです。httpd_can_network_connect_dbでググると色々出てきます。

setsebool -P httpd_can_network_connect_db on

私の環境(RHEL7)ではこのコマンドで1発解決でした。後のELB・Cloudfrontの設置は問題なく進みました。この時点ではまだキャッシュヒット率云々だとか、SSL化(HTTPS一本化)なんてものは考えていなかったからです。


■3.NFSサーバ、Web/APサーバ(2台目)の設置

次に考えたのが冗長化です。WordPressの冗長化を考える上で厄介なのがコンテンツの冗長化です。単純にWeb/APサーバを増やしてELBの傘下に置いても、肝心の中身を同期させないと不都合が起きるからです。

コンテンツの冗長化は大きく分けて2つの方法があると思います。rsync等でWPサーバ同士を同期させるか、共有ボリュームを立ててWPサーバのコンテンツをそこに置くか、のどちらかです。私は後者にしました。

本当はAWSのマネージドサービスEFS(Elastic File System)を使いたかったのですが東京リージョンでは未だに使えないので、渋々NFSサーバを立てて、2台のWeb/APサーバがそこをマウントするようにしました。現状、NFSサーバがSPOFです。冗長化は面倒臭すぎるのでやってません。EFSが使えるようになったら速攻で乗り換えます。

共有ボリュームとしてS3のバケットを使うというのも選択肢としてはありますが、個人的にはやろうとは思えません。どう考えても遅いからです。S3は耐障害性に掛けてはピカイチですが、こういったLinuxサーバの共有ディレクトリとして使うのは違う気がします。WPコンテンツへのアクセスの度にS3に行く(恐らくプロトコルがhttpに変換・再変換される処理が挟まる)のは非常に効率が悪いと思います。

AWS上でNFSサーバを立てるにあたり、以下のページが参考になりました。

NFSサーバを構築する段階で、Apacheの設定も固まってきたので参考までに貼っておきます。

<VirtualHost *:80>
 ServerAdmin <管理者メールアドレス>
 DocumentRoot /var/www/html/wordpress
 ServerName <独自ドメイン名>
 ErrorLog /var/log/httpd/wordpress-error-log
 CustomLog /var/log/httpd/wordpress-acces-log common
</VirtualHost>
<Directory "/var/www/html/wordpress">
 AllowOverride All
 EnableSendfile Off
 EnableMMAP Off
 Options -Indexes
</Directory>
<FilesMatch "\.(jpe?g|gif|png|css|js|ico)$">
 Header set Cache-Control s-maxage=172800,max-age=604800
</FilesMatch>

それと、NFSサーバが属するSecutity GroupでNFSv4のTCP 2049番を適切に開けておく事、NFSクライアントからマウントする前にWordPressのバックアップは必ず取っておきましょう。普通は誰でも取ると思いますが。

細かいですがSELinuxを有効化している場合、以下のコマンドもおまじないとして打っておいた方が良いと思います。apacheの領域でNFSディレクトリを使うなら。

setsebool -P httpd_use_nfs on

Web/APサーバの複製はAWS上で構築していれば楽勝です。AMIイメージから立ち上げれば一瞬です。AWS様様です。わざわざ2台目を一から構築する必要は全くありません。


■4.独自ドメインの取得、Route53との関連付け

ドメイン取得もAWSで出来るので、英語もバリバリOKな方は全部Route53で賄えます。私の場合はドメイン取得のみ先行してお名前.comで済ませてしまった(.tokyoが安かった)ので、少し面倒事が増えましたが、以下のページが参考になったので楽勝でした。非常に丁寧で助かりました。


■5.WordPressのSSL化

★5−1.Cloudfront、ELBのSSL化

上記の構成図にもある通りEC2はSSL化しておりません。ELBまでで事足りるからです。CloudfrontとELBのSSL化は以下のページが参考になりました。

尚、AWSのACM(Amazon Certificate Manager)で無料SSL証明書を発行して貰う場合、独自ドメイン宛に送られるメールを見て承認URLにアクセスしなければなりません。そのメールをSES、Route53、S3のバケットを使って受け取れる方法があったので、参考にして利用させて頂きました。

恐らく、ELBの設定は何も考えずにできると思いますが、CloudfrontとWordPressの設定は少し厄介だと思います。具体的な設定な話は後にして、ここでは参考にしたページを張っておきます。また、CloudfrontとWordPressのどちらから手を付けるのかにもよりますが、WPの管理画面にアクセスできなくなる場合に備えて、DBに入ってサイト・ホームURLを変更する方法を学んでおいて損は無いはずです。

更には、CloudfrontのようなCDNキャッシングの挙動を学ぶ上での基礎事項として、クッキーとセッションの基礎も知っておきたいです。


★5−2.WordPressのSSL化

外部プラグインは一切使っておりません。やった事は以下の2つです。

  1. DBに記録されているサイト・ホームURLをSQL(UPDATE)でhttpsに書き換える
    (WP管理画面にアクセスできるならそちらからでもOK)
  2. wp-config.phpに以下の文言を書き足す
/**
 * SSL
 */

define('FORCE_SSL_ADMIN', true);
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
 $_SERVER['HTTPS'] = 'on';
 $_ENV['HTTPS'] = 'on';
 } elseif (isset( $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO']) && $_SERVER['HTTP_CLOUDFRONT_FORWARDED_PROTO'] == 'https') {
 $_SERVER['HTTPS'] = 'on';
 $_ENV['HTTPS'] = 'on';
 }

込み入ったことをしておりますが、私の環境の場合、HTTPSに一本化している(Cloudfrontでリダイレクトを掛けている)ので、ifの分岐は必要無く、単純に

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

とやってしまっても良いかと思います。後々CloudfrontやELBを抜いたりする場合に備えて、この記述を残しておいてもまぁ良いかなと思うのでそのままにしてあります。


★5−3.Cloudfrontの詳細設定

※以下の内容はあくまで私の環境の場合です。特にBehaviorの設定は、WordPressのテーマやレスポンシブの実装方法にもよるので、一概にこうとは言えません。

▼General設定

Alternate Domain Names(CNAMEs)には、取得した独自ドメイン名を入れます。SSL証明書はACM(北ヴァージニア)で発行したものを指定します。

また、Cloudfrontの設定が済んだ後には必ず、Route53で該当ドメインのAliasにCloudfrontのエンドポイントを指定するのを忘れずに。

 

▼Origin設定

Origin Domain Nameは作成済みのELBを指定します。空白内をクリックするだけで出てきてくれるので非常に便利です。HTTPSに一本化する場合は、Origin Protocol PolicyをHTTPS Onlyにしましょう。

 

▼Behaviors設定(概要)

先人の例に習っておりますが、ここで重要なのは

  • HTTPは全てHTTPSにリダイレクトさせる
  • /wp-admin配下と、wordpress配下のphpはキャッシュさせない
  • それ以外は適切にキャッシュさせる

ことです。以降、代表として/wp-admin/*とDefaultのBehaviorを詳しく見ていきます。

 

▼Behavior(/wp-admin*)の詳細

Headerは飛ばすものを適切に選ばないと色々な問題が発生します。Cookieも下手に弄って肝心なものを止めてしまうと、プレビューが使えなくなったり、カスタマイズのプレビューが見れなくなったり、ログインループにハマったりします。案外危険です。先人の例に習いつつ、設定はこれで今のところ大丈夫です。

 

▼Behavior(Default)の詳細

Defaultは所謂普通のページ(ブログの記事)のキャッシュをどうするのかを設定する箇所になります。飛ばすHeaderを更に少なくしたのと、Originへ飛ばすCookieをWordPressで使用するものだけに絞る事が大事です。

飛ばすCookieを下手にAllにするとキャッシュヒット率が全然あがりません。CDNを利用するメリットが無くなってしまいます。そこら辺の事情や仕組みは上述した参考ページに詳しいので割愛しますが、Codexを読む限りこの設定でも問題ありません。


■6.セキュリティ

WordPressに対する最低限のセキュリティとして、ログイン画面にBasic認証は掛けておくべきだと思います。プラグインでも自分で設定しても大丈夫です。私は自分で設定しました。


■7.これからについて

個人的な興味関心と勉強のためにここまで構築しましたが、個人のブログにしては豪華過ぎる構成だと思います。以下の参考ページにもある通り、Static Pressに移行する方が安全で経済的だと私も思います。しばらくは今の構成で行こうと思いますが、遠くない将来には移行したいです。お金さえ気にしなければ、CloudWatch LogsやAWS CLIをフル活用して運用の自動化まで踏み込んでも面白そうなのですが…

上乃木 燕二
クラシック音楽のブログを運営しています。後期ロマン派〜新ウィーン楽派がメイン。交響曲ネタが多目。オペラ・室内楽を扱うべく奮闘中。元トロンボーン奏者。チェロやりたい。マーラーとテンシュテットが心の師匠。