概要
WordPressサイトをDockerで構築します。
サーバ構成は、Webサーバ3台+ロードバランサ、データベース2台(マスター/スレーブ)で少し拡張性を持たせた形にしました。
DockerはMacBook ProにDocker Desktopをインストールしました
設定
フォルダ構成
「docker_wordpress」フォルダを作成しその下に以下のファイルとフォルダを配置しています
docker_wordpress
├── docker-compose.yml
├── loadbalancer
│ └── nginx.conf #nginx設定ファイル
├── mysql
│ ├── Dockerfile-mysql
│ ├── db # データベースデータ(永続化)
│ │ ├── master
│ │ └── slave
│ ├── log # データベースログ
│ │ └── master
│ │ └── slave
│ ├── master
│ │ ├── conf.d
│ │ │ └── mysql_master.cnf #データベース設定ファイル(マスター)
│ │ └── initdb.d
│ │ └── master.sh # データベース初期設定スクリプト(スレーブ)
│ └── slave
│ ├── conf.d
│ │ └── mysql_slave.cnf #データベース設定ファイル(スレーブ)
│ └── initdb.d
│ └── slave.sh # データベース初期設定スクリプトファイル(スレーブ)
└── web
├── Dockerfile-web
└── wordpress # wordpressファイルの格納フォルダ
docker-compose.yml
まずはdocker-compose.ymlを作成します。
データベースサーバ(MySQL)、webサーバ(apache)、ロードバランサー(nginx)を設定します
起動順番をdepends_onを使って以下に設定しています
- データベースサーバ(マスター)
- データベースサーバ(スレーブ)
- Webサーバ(apache)
- ロードバランサー(nginx)
version: "3"
services:
mysql-master: # マスターデータベース
image: mysql:5.7
restart: always
volumes:
- ./mysql/log/master:/var/log/mysql # データベースデータ(永続化)
- ./mysql/db/master:/var/lib/mysql # データベースログ
- ./mysql/master/conf.d/:/etc/mysql/conf.d # データベース設定ファイル
- ./mysql/master/initdb.d:/docker-entrypoint-initdb.d # 初期スクリプトファイル
tty: true
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: root_db_pass
MYSQL_DATABASE: wordpress_db
MYSQL_USER: wordpress_db_user
MYSQL_PASSWORD: wordpress_db_pass
build:
context: .
dockerfile: ./mysql/Dockerfile-mysql
mysql-slave: # スレーブデータベース
depends_on:
- mysql-master # マスターデータベースの処理が完了してから開始
image: mysql:5.7
restart: always
volumes:
- ./mysql/db/slave:/var/lib/mysql # データベースデータ(永続化)
- ./mysql/log/slave:/var/log/mysql # データベースログ
- ./mysql/slave/conf.d:/etc/mysql/conf.d # データベース設定ファイル
- ./mysql/slave/initdb.d/:/docker-entrypoint-initdb.d # 初期スクリプトファイル
environment:
TZ: Asia/Tokyo
MYSQL_ROOT_PASSWORD: root_db_pass
MASTER_MYSQL_HOST: mysql-master
MASTER_MYSQL_USER: wordpress_db_user
MASTER_MYSQL_PASSWORD: wordpress_db_pass
build:
context: .
dockerfile: ./mysql/Dockerfile-mysql
web: # Webサーバ
depends_on:
- mysql-slave
image: wordpress:php7.4-apache
deploy:
replicas: 3 #web 3台
resources:
limits:
cpus: "0.2" # CPU
memory: 100M # メモリ
restart_policy:
condition: on-failure
volumes: # dockerコンテナとmacフォルダを同期
- ./web/wordpress:/var/www/html #wordpressファイル
restart: always
environment:
WORDPRESS_DB_HOST: mysql:3306
WORDPRESS_DB_USER: wordpress_db_user
WORDPRESS_DB_PASSWORD: wordpress_db_pass
build:
context: .
dockerfile: ./web/Dockerfile-web
nginx_server: # ロードバランサー
depends_on:
- web # Webサーバの処理が完了してから開始
image: nginx
links:
- web
volumes:
- ./loadbalancer:/etc/nginx/conf.d #nginx設定ファイル
ports:
- "80:80"
ロードバランサー(nginx)設定
./loadbalancer/nginx.conf
負荷分散させるwebサーバのコンテナ名を登録します
upstream web {
server docker_wordpress_web_1;
server docker_wordpress_web_2;
server docker_wordpress_web_3;
}
server {
listen 80;
location / {
proxy_pass http://web;
}
}
データベース(MySQL)設定
./mysql/Dockerfile-mysql
vimをデバッグ用にインストールしておきます
FROM mysql:5.7 RUN ["apt", "update"] RUN ["apt", "install", "-y", "locales"] RUN ["locale-gen", "ja_JP.UTF-8"] RUN ["apt", "install", "-y", "vim"] ENV LANG ja_JP.UTF-8 ENV LANGUAGE ja_JP:ja
./mysql/master/conf.d/mysql_master.cnf
レプリケーションを有効にするためlog-binとserver-idを設定します
server-idはスレーブ側と被らなければOKです。
[mysqld] log-bin server-id=1 gtid-mode=ON enforce-gtid-consistency=ON general_log=ON #クエリログが有効 general_log_file=/var/log/mysql/query.log #ログファイルのパース
./mysql/slave/conf.d/mysql_slave.cnf
server-idはマスター側の被らないようにします。
読み込み専用としてread_onlyも設定しておきます。
[mysqld] server-id=2 read_only gtid-mode=ON enforce-gtid-consistency=ON general_log=ON #クエリログが有効 general_log_file=/var/log/mysql/query.log #ログファイルのパース
./mysql/master/initdb.d/master.sh
MYSQL_USER(wordpress_db_user)にレプリケーション権限を付与します。
#!/bin/sh mysql -uroot -p$MYSQL_ROOT_PASSWORD -e"GRANT REPLICATION SLAVE ON *.* TO '$MYSQL_USER'@'%';"
スクリプトに実行権限を付与します(付与しないと起動時に実行されないので忘れずに)
$ chmod a+x ./mysql/master/initdb.d/master.sh
./mysql/slave/initdb.d/slave.sh
スレーブ側でマスターデータベースサーバの設定を行いスレーブスタートします
#!/bin/sh
mysql -uroot -p$MYSQL_ROOT_PASSWORD -e" \
CHANGE MASTER TO \
MASTER_HOST = '$MASTER_MYSQL_HOST', \
MASTER_PORT = 3306, \
MASTER_USER = '$MASTER_MYSQL_USER', \
MASTER_PASSWORD = '$MASTER_MYSQL_PASSWORD', \
MASTER_AUTO_POSITION = 0; \
START SLAVE; \
"
スクリプトに実行権限を付与します(付与しないと起動時に実行されないので忘れずに)
$ chmod a+x ./mysql/slave/initdb.d/slave.sh
Webサーバ(Apache)設定
./web/Dockerfile-web
デバッグ用にvimをインストールします
FROM wordpress:php7.4-apache RUN ["apt", "update"] RUN ["apt", "install", "-y", "vim"]
WordPress設定
ダウンロード
WordPressをダウンロードして「./web/wordpress/」フォルダに入れます
./web/wordpress/wp-config.php
WordPressにデータベースやホスト情報などを設定します
/** WordPress のためのデータベース名 */
define('DB_NAME', 'wordpress_db');
/** MySQL データベースのユーザー名 */
define('DB_USER', 'wordpress_db_user');
/** MySQL データベースのパスワード */
define('DB_PASSWORD', 'wordpress_db_pass');
/** MySQL のホスト名 */
define('DB_HOST', 'mysql-master');
define('DB_HOST_RO', 'mysql-slave');
/** ドメイン設定 */
define( 'WP_HOME', 'http://localhost' );
define( 'WP_SITEURL', 'http://localhost' );
/**認証用ユニークキー
* それぞれを異なるユニーク (一意) な文字列に変更してください。
* {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org の秘密鍵サービス} で自動生成することもできます。
* ↓必ず変更してください
*/
define('AUTH_KEY', 'xl@j9?C%C0#;7n)|<( bZ75qPlME?I|+!E=b_JeC|hQc*<e=Roh&$h{cDni(7*)Y');
define('SECURE_AUTH_KEY', '~UcxG46u|-+<6g:Im}^ydPsQ3|,X]FBcf-S9*)Z2Tu`[S|Zvi,y`F!am&NGY2QC%');
define('LOGGED_IN_KEY', 'OL>v:TV8}ly<N(pY5-|-!I3z3Orw~cW.q|~Xb9,n&GK=L^_Djse5AfRQLv-;|4nv');
define('NONCE_KEY', '&Q>P!:3}z@DBo 6w 3Uv&R=NQ8;6S(OKl.:Up5-MXc+;_^-dU>}nt-K/AzdCEz<)');
define('AUTH_SALT', 'f]>5SzqN+.gd*[cea|CZ_:nR|+i3l^RI/q_hs&Dnrg*R$|1H:_b-izl,ERs*_?#g');
define('SECURE_AUTH_SALT', '<zV}MZnr* 2f2:mwAMIe*o-eF%SJ^z`$W!T.va0+!p0F=^Rxb|Ef-msDr;6yZJv!');
define('LOGGED_IN_SALT', 'T:x`Jq_PLbchkig5D._jn>7,af !gbB]`U ;pZMVYztF59R>N4WO&X$U0}^v^Q}*');
define('NONCE_SALT', '6%L]i|}N!c x;q6$ULl5_my[0^0,aUI3^7lVUD(MR)B]NAHv!Bt24wy1-hE#sV,');
起動
すべての設定が完了したのでdocker-composeで起動します
$ docker-compose up -d --build オプション -d:コンテナをバックグラウンドで起動します(同じターミナルで作業を継続できます) --build:Dockerfile変更を反映
WordPressの動作確認
初期画面

ブラウザでhttp://localhostと入力し、WordPressの初期画面が表示されれば成功
そのまま初期設定を行います
サイトトップ画面

再度、ブラウザでhttp://localhost/と入力してサイトトップが表示されることを確認します
ダッシュボード画面

また、ブラウザでhttp://localhost/wp-admin/と入力し、ログイン後にダッシュボードも表示されることも確認します
コンテナ起動確認
dockerコンテナの確認を行います。
nginx、webサーバ3個、データベースサーバ2個のSTATUSが「UP」になっていることを確認します
$ docker ps -sa --format "table {{.Image}}\t{{.Names}}\t{{.Status}}"
IMAGE NAMES STATUS
nginx docker_wordpress_nginx_server_1 Up About an hour
wordpress:php7.4-apache docker_wordpress_web_2 Up About an hour
wordpress:php7.4-apache docker_wordpress_web_1 Up About an hour
wordpress:php7.4-apache docker_wordpress_web_3 Up About an hour
mysql:5.7 docker_wordpress_mysql-slave_1 Up About an hour
mysql:5.7 docker_wordpress_mysql-master_1 Up About an hour
データベースのレプリケーション確認
マスターデータベースとスレーブデータベースの状態を確認します
FileとPositionが設定されていることを確認します
マスターデータベース
$ docker exec -it docker_wordpress_mysql-master_1 bash root@5596c918f946:/# root@5596c918f946:/# mysql -u root -proot_db_pass mysql> show master status;

スレーブデータベース
スレーブ側の動作状況を確認します
「Master_Log_File」と「Read_Master_Log_Pos」がマスター側と一致して、Slave_IO_RunningとSlave_SQL_Runningが両方ともYesになっていれば正常にレプリケーションされています
$ docker exec -it docker_wordpress_mysql-slave_1 bash
root@5596c918f946:/# root@5596c918f946:/# mysql -u root -proot_db_pass
mysql> show slave status¥G
Master_Host: mysql-master ← マスターデータベースのホスト
Master_User: wordpress_db_user ← マスターデータベースのユーザ
Master_Port: 3306
Master_Log_File: 5596c918f946-bin.000001 ← マスターのFileと一致
Read_Master_Log_Pos: 154 ← マスターのPosisonと一致
Slave_IO_Running: Yes ← Yesになっていること
Slave_SQL_Running: Yes ← Yesになっていること
WordPressのデータベースレプリケーション設定
初期状態のWordPressはデータベースサーバを一つしか指定できません。(wp-config.phpで設定)
そのため、いまの状態はデータベースはレプリケーションされてますがクエリはすべてマスターデータベースで処理されています。
今回はプラグイン「HyperDB」を使ってWordPressのレプリケーション設定をします。
HyperDB設定
WordPressのダッシュボード(プラグイン)からHyperDBをインストール&有効化

プラグイン画面で「HyperDB」と検索

HyperDBをインストール

HyperDBを有効化
./web/wordpress/db-config.php設定
インストールが終わったらPHP側を修正します。
db-config.phpをwp-config.phpと同じ階層に配置します。
インストールが終わったらPHP側を修正します。
db-config.phpをwp-config.phpと同じ階層に配置します。
<?php
// Master ( read and write )
$wpdb->add_database(array(
'host' => DB_HOST, // マスターデータベースのホスト
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 1, // 1は書き込み有効
'read' => 1, // 1は読み込み有効
));
// Slave ( read only )
$wpdb->add_database(array(
'host' => DB_HOST_RO, // スレーブデータベースのホスト
'user' => DB_USER,
'password' => DB_PASSWORD,
'name' => DB_NAME,
'write' => 0, // 0は書き込み無効
'read' => 1, // 1は読み込み有効
));
db.phpファイルコピー
したhyperdbに含まれるdb.phpをwp-content配下にコピーします
インストールしたhyperdbに含まれるdb.phpをwp-content配下にコピーします
$ cp ./web/wordpress/wp-content/plugins/hyperdb/db.php ./web/wordpress/wp-content/
レプリケーションの動作確認
マスターのクエリログ
サイトにアクセスし更新系、データ取得系の両方が処理されていることを確認します
$ tail -100f ./mysql/log/master/query.log
更新系、データ取得系の両方が処理されます
スレーブのクエリログ
データ取得系のみが処理されていることを確認します
$ tail -100f ./mysql/log/slave/query.log
データ取得系のみ処理されます

コメント