メモ > サーバ > サービス: AWS > マルチAZ環境でWordPress
■マルチAZ環境でWordPress
※Webサーバが2台構成(オートスケールではない)の環境でWordPressを使おうとしたら、なかなか厄介だったので作業内容をメモ
AWSのマルチAZ環境を前提とした調査だが、複数台構成の環境全般に言える
■下調べの内容
アマゾン ウェブ サービスで WordPress ウェブサイトを構築する
http://docs.aws.amazon.com/ja_jp/getting-started/latest/wordpress/hosting-wordpress-on-aws.html
AWSでWordPressを使おうと試してみたが、管理画面側ではメディアはS3ではなくローカルファイルが参照される。
管理画面側ではロードバランサを経由せずにアクセス…とすれば使えるが、可用性が下がるのでそのような運用は避けたい。
また、WordPressが何かとローカルのファイルを更新しようとするので、スケーリング環境だとファイルの同期が厄介。
ステップ 5: アプリケーションバージョンを更新する
http://docs.aws.amazon.com/ja_jp/getting-started/latest/wordpress/update-application-version.html
AWS公式の解説通りに構築すると、WordPressやプラグインのバージョンアップが面倒すぎて耐えられる自信は無い。
(複数台構成のWebサーバを一時的に1台にし、WordPressの管理画面でアップデートを実行し、
サーバからファイルをダウンロードして、それを新しいバージョンのアプリとして登録しなおす)
…だったが、上の詳細解説ページは無くなって、簡易な解説に差し替えられている
以下は転送先のページ
外部 Amazon RDS データベースを備えた高可用性の WordPress ウェブサイトを Elastic Beanstalk にデプロイする - AWS Elastic Beanstalk
http://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/php-hawordpress-tutorial.html
以下は解説が差し替えられる前のメモ
■基本方針
WordPressは複数台サーバを前提とした設計になっていない(WordPressがローカルファイルを書き換える)ので、マルチAZ環境には向いていない。
どうしても複数台サーバにしたければ、一案としてrsyncでファイル同期する方法がある。
データベースは通常通り、RDSを使える。
ただし単純に「web1をweb2に同期」としても、WordPressがweb2サーバのファイルを書き換える可能性がある。
(「rsyncで双方向同期+ロードバランサーでスティッキーセッション」で対応する。)
また、gitでファイルを管理していてもWordPressがファイルを書き換えるため、この対策も必要となる。
(「専用のテーマのみgit管理対象」で対応する。)
[ようやく見つけたかもしれない]WordpressサイトをGit管理する方法[メモ]
http://qiita.com/goosys/items/5c66cb912986afcd86f3
wordpressサイトをgitで管理する際のgitignore
http://eturlt.net/blog/20130520/gitignoreforwordpress/
■具体的な構築内容
サーバ構成
Webサーバはweb1とweb2の二台構成とする。アクセスはELBで割り振るものとする
データベースにはRDSを使うものとする
(EC2にMySQLをインストールしてデータベースサーバを構築する場合も、作業の流れは同じ)
公開ディレクトリ
一例として /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で管理する
Git管理の詳細は Git.txt を参照
■所有者と権限を保持して同期(未検証)
# visudo -f /etc/sudoers.d/users
追加後、下記コマンドで追加されているか確認できる
Cmnd_Alias RSYNCCOMMANDS = /usr/bin/rsync
rsync ALL=PASSWD: ALL, NOPASSWD: RSYNCCOMMANDS
# su - rsync -s /bin/bash … rsyncユーザへ切り替え
# cat /etc/sudoers.d/users … usersファイルの所有者はrootの為、権限エラー
# sudo cat /etc/sudoers.d/users … sudoに追加されていても、許可されたコマンドではないためパスワードが要求される
# sudo rsync --version … sudoに追加されており、且つ許可されたコマンドなのでパスワードが要求されず実行
rsyncの設定を以下のようにすると、ファイルの所有者と権限を保持して同期できる
設定後、rsyncを再起動する
# vi /etc/lsyncd.conf
SFTPでアップロードするファイルのumaskを設定する場合、以下のようにする
設定後、sshdを再起動する
rsync = {
owner = true, … 追加
group = true, … 追加
rsync_path = "sudo /usr/bin/rsync", … 追加
archive = true,
compress = false,
rsh = "ssh -p 10022"
}
# vi /etc/ssh/sshd_config
■オートスケールに対応させるなら
双方向同期では対応できないので、素直にAWS公式の解説通りにするといいかも(未検証)
■メモ
展開済みのWordPressの全ファイルをFTP経由でアップロードすると非常に時間がかかる
圧縮ファイルのままアップロードし、SSHで unzip wordpress-4.7.2-ja.zip として展開すると早い
ただしファイルの所有者に注意。FTPでアップロードしたときと同じ所有者になるように一括変更しておく
#Subsystem sftp /usr/libexec/openssh/sftp-server
Subsystem sftp internal-sftp -u 002
# chown -R apache wordpress … 所有者をapacheに変更(再帰的)
# find wordpress -type d -print | xargs chmod 775 … ディレクトリの権限を775に変更(再帰的)
# find wordpress -type f -print | xargs chmod 664 … ファイルの権限を664に変更(再帰的)
以下はハマりどころなのでメモしておく
【決定版】WordPressの引っ越し!サーバー移行・移転手順 | FASTCODING BLOG
https://fastcoding.jp/blog/all/system/moving-wordpress/
searchreplacedb2 を使った、データベースの移行について紹介されている
SSL対応後のWordpress管理画面で発生した無限リダイレクトループの修正方法 - Qiita
https://qiita.com/hirror/items/bb96e236c3ffc41e890e
リダイレクトループが発生したら、wp-config.php に $_SERVER['HTTPS'] = 'on'; を書けば、何とかなるかも