Webサーバが2台構成(オートスケールではない)の環境でWordPressを使おうとしたら、なかなか厄介だったので作業内容をメモ。
AWSのマルチAZ環境を前提とした調査だが、複数台構成の環境全般に言える。
基本方針
WordPressは複数台サーバを前提とした設計になっていない(WordPressがローカルファイルを書き換える)ので、マルチAZ環境には向いていない。
どうしても複数台サーバにしたければ、一案としてrsyncでファイル同期する方法がある。
データベースは通常通り、RDSを使える。
ただし単純に「web1をweb2に同期」としても、WordPressがweb2サーバのファイルを書き換える可能性がある。
(後述するが、「rsyncで双方向同期+ロードバランサーでスティッキーセッション」で対応できる。)
また、gitでファイルを管理していてもWordPressがファイルを書き換えるため、この対策も必要となる。
(後述するが、「専用のテーマのみgit管理対象」で対応できる。)
具体的な構築内容
サーバ構成
Webサーバはweb1とweb2の二台構成とする。アクセスはELBで割り振るものとする。
データベースにはRDSを使うものとする。(EC2にMySQLをインストールしてデータベースサーバを構築する場合も、作業の流れは同じ。)
以下の手順では、メディア置き場としてS3は使っていない。(メディアはWebサーバに保存し、rsyncで同期する。)
公開ディレクトリ
一例として /var/www/html
とする。(/var/www/vhosts/wordpress/html
など他の場所の場合も、作業の流れは同じ。)
同期設定
rsyncで /var/www
を双方向同期する。同期ユーザは一例としてrsyncとする。(専用に作成する。)
意図しないファイルの削除&復元を避けるため、/etc/lsyncd.conf
のsyncブロックで以下の指定を行う。
delete = "running",
init = false,
WordPress設置場所のディレクトリに以下の指定を行い、この中で作成されたファイル&ディレクトリの所有グループをapacheにする。
chown apache. /var/www
chmod 0777 /var/www
chmod g+s /var/www
セッション切れを防ぐため、ELBでスティッキーセッションを有効にする。
「Aサーバでメディアをアップロードしたが、直後にBサーバにアクセスしたのでメディアが表示されない(同期が完了していない)。」もこれで防げる。
更新方法
ファイルアップロードユーザは一例としてweb-userとする。(専用に作成する。)
アップロードはweb1サーバからweb-userで行う。(web2サーバから行っても問題ないはずだが、統一しておくと無難。)
これでファイル&ディレクトリの所有者&所有グループは
- アップロードした ... web-user / apache
- WordPressが作成した ... apache / apache
- 同期された ... rsync / apache
となる。すべて同じグループになるので、グループに対して読み書きの権限を与えれば、各ファイルの読み書きができる。
gitを使う場合
デプロイの仕組みを作る場合、web1サーバからapacheユーザでデプロイする。rsyncで同期されるので、web2サーバでのデプロイは不要。
ただしWordPress自体が自身のプログラムを書き換えるため、最低限のファイルのみgitで管理する。
.gitignore
で以下の指定を行い、wordpress
ディレクトリをgit管理対象外にして、専用のテーマのみgit管理対象とする。
(テーマ以外にも管理対象を追加したければ、都度追加する。)
/wordpress/*
!/wordpress/wp-content
/wordpress/wp-content/*
!/wordpress/wp-content/themes
/wordpress/wp-content/themes/*
!/wordpress/wp-content/themes/mysite
オートスケールに対応させるなら
双方向同期では対応できないので、素直にAWS公式の解説通りにすると良さそう。(未検証。)
外部 Amazon RDS データベースを備えた高可用性の WordPress ウェブサイトを Elastic Beanstalk にデプロイする - AWS Elastic Beanstalk