WordPressを運用しているインスタンスの状態は日々変化をしていくものですが、WordPress自体のバージョンアップは管理画面のU/Iから比較的容易に行ってしまうことができます。
しかし、母艦であるLinuxベースのパッケージに手を入れない限りそれらは日に日に古くなっていきます。
それらを個別アップデートすることである程度の対応を続けることは出来ますが、ソリューションを使っている場合にはパッケージアップデートには限界があるようです。
あくまでも独立インスタンス運用でのケースにはなりますので、共有サーバーなどでのWordPress運用には当てはまらない箇所が多々あることをご了承ください。
BitnamiソリューションをGCPで運用
当サイトはGCPにより、独立インスタンスで Bitnamiソリューションを用いて構成しています。
こちらのソリューションではPHPアップデートが容易に行えない感じであることから、2年以上前のソリューションのインスタンスから新インスタンスへの移行をすることにいたしました。
ソースコードからビルドをして丁寧に環境設定を行えば、おそらく対応可能であるとは思われるのですが、母艦OSを含む膨大な関連ライブラリについても整合性を取る必要があることから、骨折り損のくたびれ儲けとなる可能性が高そうなため、この道を進むことを断念し、インスタンスを丸ごと構成し直す道を進むことにしました。住宅で言えば、住み替え、引っ越しみたいなものでしょうか。
過去にはこの様な事を繰り返し、Webサーバーをアップデートするのにとてつもない時間をかけて 対応するようなケースも経験していますが、日々進化しているライブラリ等を含め、私にとっては対応コストが積み上がってしまうという経験を踏まえると、GCPでのソリューションを適切に利用することのメリットはそれなりに有るわけです。
裏を返すと、ソリューションに信頼がある事が前提で、細かいことは調査をしないと分からないという点が盲点となりますね。同じソリューションでも日進月歩で構成が変わっている事があり、今回の Bitnamiソリューション についても例外ではありません。
GCPの利用を開始してからというもの、各ソリューションへの信頼は有るため最新のソリューションをインスタンスの入れ替えにより利用する、母艦の移行を行う、ということを今回の記事にしています。
日々噛み締めていますか?WordPressを含めた無償ライブラリ、GitHubの公開ソースは先人たちの並々ならぬ苦労の末に出来上がっている人類共通資産であることを。大切に利用いたしましょう。
移行前の状態
さて、実際のところWordPressインスタンスの移行をするとなると、今回のケースではインスタンスの作成し直し、データのリストアなどなどを行うわけですが、程度にもよりますが運用中の画像ファイルなどの移行にはそれなりの計画もって対応する必要があります。
今回、一つの切っ掛けとなった、WordPress管理画面内の「PHPの更新を推奨」表示。
ざっとした環境構成は下記の状態です。
旧 | 新 | |
WordPress | 6.0.3 | 6.0.3 |
debian_version | 9.13 | 11.5 |
php -v | 7.3.17 | 8.1.11 |
mysql -V | 8.0.18 | MariaDB 10.6.10 |
ソースコードからビルドするなどもう勘弁して欲しい、という方向けの立派なソリューションが Bitnamiソリューション です。
言うなれば、我々の肩代わりをしていただいている素敵なソリューションであるということも言えるわけです。ソリューションは無償ですが、GCPとの連携によりインスタンス費用等が発生してくる事を考えると、とてもうまい連携技であるとも言えます。
また、AWSの方にも同様なソリューションが有るようですが未検証です。AWSもしかり、GCP同様に母艦であるLinuxベースのパッケージ郡が日に日に古くなることは変わらないと思います。同じ様なスタイルでWordPressインスタンス移行は行えるはずです。
ここでは下記の定義で解説をします。
- 旧インスタンス:稼働中また移行前のインスタンス
- 新インスタンス:新規に立ち上げたインスタンス
旧、新、ともに Bitnamiソリューション にてインスタンスが立ち上がっている状態を前提といたします。
MySQL
旧インスタンスから、データベース上にあるWordPressのデータを吸い上げます。
root ユーザーにてmysql コマンドでログインします。
# mysql -u root -p
既存のデータベースを照会すると、下記の様な状態になっていました。
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| bitnami_wordpress |
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
一旦抜けます。
mysql> quit
Bye
mysqdump コマンドにより、bitnami_wordpress データベースよりデータをダンプします。
mysqldump -u root -p bitnami_wordpress > k.works.sql
ダンプしたファイル内容の一部。
-- MySQL dump 10.13 Distrib 8.0.18, for linux-glibc2.12 (x86_64)
--
-- Host: localhost Database: bitnami_wordpress
-- ------------------------------------------------------
-- Server version 8.0.18
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `wp_actionscheduler_actions`
--
DROP TABLE IF EXISTS `wp_actionscheduler_actions`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `wp_actionscheduler_actions` (
`action_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`hook` varchar(191) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL,
`scheduled_date_gmt` datetime DEFAULT '0000-00-00 00:00:00',
`scheduled_date_local` datetime DEFAULT '0000-00-00 00:00:00',
`args` varchar(191) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
`schedule` longtext COLLATE utf8mb4_unicode_520_ci,
`group_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`attempts` int(11) NOT NULL DEFAULT '0',
`last_attempt_gmt` datetime DEFAULT '0000-00-00 00:00:00',
`last_attempt_local` datetime DEFAULT '0000-00-00 00:00:00',
`claim_id` bigint(20) unsigned NOT NULL DEFAULT '0',
`extended_args` varchar(8000) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL,
PRIMARY KEY (`action_id`),
KEY `hook` (`hook`),
KEY `status` (`status`),
KEY `scheduled_date_gmt` (`scheduled_date_gmt`),
KEY `args` (`args`),
KEY `group_id` (`group_id`),
KEY `last_attempt_gmt` (`last_attempt_gmt`),
KEY `claim_id` (`claim_id`),
KEY `claim_id_status_scheduled_date_gmt` (`claim_id`,`status`,`scheduled_date_gmt`)
) ENGINE=InnoDB AUTO_INCREMENT=1535 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `wp_actionscheduler_actions`
--
これらは、新インスタンスへリストアを行う際にそのまま食わせるデータとなります。
MariaDB
MySQL から MariaDB となっていますが、根本的には同じです。歴史を解説していきますと長くなるため割愛します。
ここでは、新インスタンス側のデータベースのテーブルを初期化(DROP)します。
まずは、既存のデータベースを確認してみます。
mysql -u root -p
test というデータベースが増えている様子でした。(tableを確認したところ何も無かったため、消し忘れたのでしょうか。。。)
MariaDB [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| bitnami_wordpress |
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
6 rows in set (0.002 sec)
対象のデーベースへ接続します。
use bitnami_wordpress;
DROP TABLE 対象のSQL句を生成します。
SELECT CONCAT( 'DROP TABLE ', GROUP_CONCAT( CONCAT('`',table_name,'`') ),';' ) AS statement FROM information_schema.tables WHERE table_schema = 'bitnami_wordpress' AND table_name LIKE '%';
この結果は環境により異なる可能性があります。
DROP TABLE `wp_commentmeta`,`wp_comments`,`wp_links`,`wp_options`,`wp_postmeta`,`wp_posts`,`wp_term_relationships`,`wp_term_taxonomy`,`wp_termmeta`,`wp_terms`,`wp_usermeta`,`wp_users`;
生成されたSQL句を実行して、新インスタンスの bitnami_wordpress データベース内のテーブルを全てDropします。
ここでのDropは「新インスタンス」でデータが何もないテーブルを削除することです。 誤って「旧インスタンス」側でDropしないように注意しましょう。 |
確認のため、下記を実行します。(結果は0であるはずです)
show tables;
mysql コマンドによる接続を抜けて、シェルに戻ります。
mysql> exit
インスタンス間のデータ移行
私は、Transmit(macOSアプリ)を用いて、ダンプファイルをバックアップの意味も含めてローカルへ転送し、新インスタンス側へコピーしました。
以降に解説する画像ファイルなどの複数のリソースはこの方法では少々きついことから、rsync による接続で対応をしています。
新インスタンス MariaDBへのリストア
mysql コマンドにより、ダンプファイルを元にリストアを実施します。
mysql -u root -p bitnami_wordpress < k.works.sql
新インスタンスでの rsync の環境設定とコピー実施
rsync がない場合はインストールします。
apt-get install rsync
インスタンス間のデータコピーをスムーズに行うために、ssh 接続用の キーを生成します。
bitnami ユーザーでログインし、/home/bitnami へ移動。
ssh-keygen -b 1024
一時的なキーのため、ビット数はなんでもOKです。
生成された /home/bitnami/.ssh/id_rsa.pub の公開キーを、旧インスタンス側の /home/bitnami/.ssh/authorized_keys の中へ設定します。
# bitnami
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC5jJ/jSpRi5tw9HugkS9pa ..........
# Added by Google
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQChUegVTnuwhldc5c3Ew0g .........
# Added by Google という行がある場合にはGCP側が生成しているため、そのまま残します。
新インスタンスから旧インスタンスへのSSH接続が行えるかを bitnami ユーザーで検証します。
ssh bitnami@[旧インスタンスの内部IPアドレス]
ここでは、新インスタンス → 旧インスタンスの内部IPアドレス を用いて接続しています。
同一VPCネットワーク内に有ることを前提としています。もしそうでない場合は外部IP等でも接続できますが、転送データによっては下りのトラフィック料金がそれなりに発生しますので注意が必要です。
接続が行えればOKです。
sudo su で rsync を実行。ファイルの権限も継承します。
# rsync -avz -e "ssh -i /home/bitnami/.ssh/id_rsa" bitnami@[旧インスタンスの内部IPアドレス]:apps/wordpress .
rsync のオプションにて「-e」または「- -rsh」を指定して、SSH接続をします。
sshの接続先に 内部IPを指定し、旧インスタンスの bitnami/apps/wordpress ディレクトリを取得し、新インスタンスの /home/bitnami/ に保存します。
コピー先を「.」 としていますが、/home/bitnami で実施しています。
この流れで、旧インスタンスにある、wordpressファイル群が 新インスタンスへコピーされます。
ファイルの状態によりますが、画像ファイルが多い場合などはそれなりに時間がかかります。
新インスタンス側でのWordPressリソースの設定
2022年10月初旬時点の Bitnamiソリューション では、旧インスタンス側の構成と比べるとそれなりに変更がありました。
新インスタンス側の構成を確認すると、下記の状態でシンボリックリンクが設定されていました。
/opt/bitnami/wordpress
lrwxrwxrwx 1 root root 29 Oct 17 21:04 wp-content -> /bitnami/wordpress/wp-content
要するに、ディレクトリ実態は下記に切り出されている状態となっています。
/bitnami/wordpress/wp-content
おそらくですが、今回のケースのように移行がしやすいように、環境が整備されていると見て取れます。
確認をしてみると下記の状態でした。
# ls -la
total 24
drwxrwxr-x 4 daemon root 4096 Oct 19 12:18 .
drwxr-xr-x 6 root root 4096 Oct 17 21:04 ..
-rw-r----- 1 bitnami daemon 4436 Oct 19 12:18 wp-config.php
drwxrwxr-x 7 bitnami daemon 4096 Oct 17 21:04 wp-content
wp-content のディレクトリ以下をそっくりそのまま入れ替えるだけでOKそうなので、その様に対応しました。
/bitnami/wordpress/ 下にある wp-content は必要ないので消しても良いのですが、念の為に名前を変更してとっておきます。
# mv wp-content wp-content_
cpコマンドにて rsync した wp-content 以下をコピーします。
/bitnami/wordpress/wp-content にて
# cp -a -r /home/bitnami/wordpress/htdocs/wp-content .
新インスタンスでの環境では、htdocs や conf 等が無くなっており、これらの構成状態からそれなりの変更が行われている様子でした。
SSL証明書の移行
旧インスタンスで利用中のSSL証明書を適宜コピーします。
nginx の構成もそれなりに変更があるため、適切に対応します。
ネットワークインターフェースの変更
GCPでは、インスタンスに紐付けられている外部IPアドレスの変更が行なえます。
旧インスタンス に紐付けられている外部IPアドレスはエフェメラルへ変更し、新インスタンスに運用中の同じ外部IPアドレスを設定します。
その様にすることで、DNSサーバーのレコードを変更せずに済みます。
手順としては
- 旧インスタンスを停止
- 新インスタンスを停止
- 旧インスタンスのネットワークインターフェースを「エフェメラル」へ変更
- 新インスタンスのネットワークインターフェースを「外部IPアドレス」へ変更
この間、数分で作業が完了します。
必要に応じて、旧、新インスタンスを起動します。
これで、表向きは同じ外部IPアドレスを用いて、旧 → 新インスタンスの切り替えを行ったことになります。
Nginx設定の確認
memory.conf という新しい定義ファイルが出来ており、内容を確認してみたところ下記の状態でした。
; Bitnami memory configuration for PHP-FPM
;
; Note: This will be modified on server size changes
pm.max_children=30
pm.start_servers=20
pm.min_spare_servers=20
pm.max_spare_servers=22
pm.max_requests=5000
2年ほど前の pm.max_children は 5 の設定であったため、PHP稼働環境周りを含めても向上している様子が見て取れます。
私はこれを 10 に設定変更していましたが、30 という設定で動作が検証されているところを見ると、PHP8になってよっぽど信頼性が増しているのかな?と思うところです。
※ 追記:他案件で偶々使用していた、PHP 7.4 を使っている後継の Bitnamiソリューションでは既にこの構成になっていました。
注意点
- 旧インスタンスの外部IPアドレスをエフェメラルへ設定しても、実質的には外部IPアドレスを用いた稼働を行うため、Coming soon プラグインなどで、メンテナンスモードにしておくか、外部からのアクセスを行わせないためにファイアーウォール制御を行ったほうが無難です。そのうち停止する事になるでしょうから、念の為ということです。
- ネットワークインターフェースの変更前に、新インスンタンスへ実際のドメインで接続検証を行った方が良いでしょう。hosts ファイルの定義によりローカルから実際のドメイン経由で新インスタンスにアクセスして検証するなど、これらの動作検証は大切です。
- 今回の例では wp-content 以外のWordPress関連のファイルは移行していないため、wp-config.php などの個別設定が行われている場合などは、相応に対応が必要です。
- WordPressの利用状態(特にプラグイン)によって行われている事が様々であるため、インスタンス移行が行えるかは十分な検証が必要です。
- 少々掻い摘んでまとめた記事のため、運用状態のWordPressによってはこの通りに移行ができない可能性がありますため検証などは十分に行ってください。
移行後の感想
気分的にスッキリしますね。
WordPressの警告表示が無くなることもありますが、実際にサイトアクセスした際のレスポンスはそれなりに向上した感じを受けます。
WordPress移行というと壮大な感じを想像してしまうかもしれませんが、コンテンツ次第(運用の歴史が浅いWordPress)では比較的容易にインスタンス移行が行えます。
特に、MySQLなどは2世代もバージョンが異なるのに特に違和感なく移行が出来てしまうことには感謝しかありません。
GCP運用に関わらず、当社ではWordPress移行を行っております。是非ご検討ください。
記事の内容が古くなっているものもあり、適宜アップデートされる場合がございます。