WordPressのマイグレーション・引越し作業まとめ
Amazon Linuxが2020年にサポート終了となるため、Amazon LinuxからAmazon Linux 2へのお引越し作業を少しずつはじめました。
この機会にコンテナの構成を変えたり、PHPやMySQLのバージョンアップをしたりなど、よりモダンな基盤にアップデートすることに。
AWS以外でも作業の流れは同じと思いますので、似たような作業に遭遇することを考え、メモを残します。
バックアップ
WordPressのバックアップ
特に重要なのは__wp-content__配下にあるファイル群なので、基本的にはこれらを対象にバックアップをとります。
├── wp-content
│ ├── ewww
│ ├── languages
│ ├── plugins
│ ├── themes
│ ├── upgrade
│ └── uploads
しかし私は分けて管理するのが面倒だったため、全てのデータを丸ごとバックアップしています。
SSL/TLS証明書のバックアップ
新規に発行し直しても良いのですが、ローカルでテストもしたかったため、証明書類もバックアップをとりました。
MySQLデータのバックアップ
MySQLのデータのバックアップを行う前に、MySQL5.7から8へのバージョンアップしても問題ないかチェックします。
チェックするためにはMySQL Shellというツールをインストールします。このツールに__Upgrade Checker Utility__という関数がありまして、これを実行するとMySQLのアップグレードの際にエラーがないかとか、どこに注意してバージョンアップすれば良いのか分かり、事前に対策を打つことができます。
MySQL Shellのインストール
Upgrade Checker Utilityを使うには、MySQLを動かしているサーバーでMySQL Shellをインストールする必要があります。
↓インストール方法
https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-install.html
Upgrade Checker Utilityの実行
まずMySQL Shellを実行します。
mysqlsh --uri root@localhost
MySQLのShellに接続されるので、次にupgrade checkerを起動。
util.checkForServerUpgrade("root@localhost:3306")
↓こんな感じで出力結果が表示されます。
MySQL localhost JS > util.checkForServerUpgrade("root@localhost:3306")
Please provide the password for 'root@localhost:3306': ***************
Save password for 'root@localhost:3306'? [Y]es/[N]o/Ne[v]er (default No): y
The MySQL server at localhost:3306, version 5.7.19 - MySQL Community Server
(GPL), will now be checked for compatibility issues for upgrade to MySQL
8.0.15...
1) Usage of old temporal type
No issues found
2) Usage of db objects with names conflicting with reserved keywords in 8.0
ERROR: Cannot proceed because system tables used by Event Scheduler were found damaged at server start
More information:
https://dev.mysql.com/doc/refman/en/keywords.html
3) Usage of utf8mb3 charset
Warning: The following objects use the utf8mb3 character set.
....
↓私の環境ではエラーが1つと警告が2つありました。
# エラーの内容
Cannot proceed because system tables used by Event Scheduler were found damaged at server start
このエラーについては、 mysql_upgrade
を実行することで解決しました。
警告は下記のような内容でした。
# 警告その1
3) Usage of utf8mb3 charset
Warning: The following objects use the utf8mb3 character set. It is
recommended to convert them to use utf8mb4 instead, for improved Unicode
support.
More information:
https://dev.mysql.com/doc/refman/8.0/en/charset-unicode-utf8mb3.html
xxxxxx.wp_ewwwio_queue.gallery - column's default character set: utf8
# 警告その2
15) New default authentication plugin considerations
Warning: The new default authentication plugin 'caching_sha2_password' offers
more secure password hashing than previously used 'mysql_native_password'
(and consequent improved client connection authentication). However, it also
has compatibility implications that may affect existing MySQL installations.
If your MySQL installation must serve pre-8.0 clients and you encounter
compatibility issues after upgrading, the simplest way to address those
issues is to reconfigure the server to revert to the previous default
authentication plugin (mysql_native_password). For example, use these lines
in the server option file:
[mysqld]
default_authentication_plugin=mysql_native_password
However, the setting should be viewed as temporary, not as a long term or
permanent solution, because it causes new accounts created with the setting
in effect to forego the improved authentication security.
If you are using replication please take time to understand how the
authentication plugin changes may impact you.
More information:
https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatibility-issues
https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-replication
警告1について - Usage of utf8mb3 charset
ユニコードサポートを改善するために、文字コードはutf8mb4への変換を推奨 されています。
既存DBの文字コード変換については↓こちらの記事にまとめました。
https://hodalog.com/modify-the-character-encode-of-mysql/
警告2について - New default authentication plugin considerations
MySQL 8からデフォルトの認証プラグインが caching_sha2_password
というものに変更されます。それに伴い問題が発生する可能性があるという内容の警告です。
新しいデフォルトの認証プラグイン ‘caching_sha2_password’は、以前使用されていた ‘mysql_native_password’よりも安全なパスワードハッシュを提供します。しかし既存のMySQLに影響を与える可能性もあります。
もしアップグレード後に問題が発生した場合は、次の環境変数を設定することで、暫定対策が可能なようです。
[mysqld]
default_authentication_plugin=mysql_native_password
MySQLダンプ-データの吸い出し
エラーと警告の対応ができたので、mysqldumpでデータを吸い出してバックアップをとります。
mysqldump db_name > backup-file.sql
コンテナの実行・動作確認
これまで一つのコンテナにPHP、MySQL、WordPress、Nginxを入れて動かしていたのですが、このマイグレーションを機に3つのマルチコンテナで運用することにしました。
使用するDockerイメージは下記の3つです。
- php:7.3-fpm-alpine
- nginx:1.15-alpine
- mysql:8
ディレクトリ構成
今回は下記のような構成で行きました。
.
├── DockerfileNginx
├── DockerfileWeb
├── code
│ ├── certificate
~ ~ └── #ここに証明書ファイルなどを置く
│ ├── db
│ │ ├── .env #DBのユーザやパスワードの情報を格納したファイル
│ │ └── backup-file.sql #MySQLのダンプデータ
│ ├── nginx
│ │ └── conf.d
│ │ └── nginx.conf #Nginxのコンフィグデータ
│ └── web
~ ~ └── #ここにWordPressのディレクトリを置く
└── docker-compose.yml
DockerfileNginx
NginxコンテナのDockerfileです。証明書の更新にCertbotを使うため、ここでインストールしています。
FROM nginx:1.15-alpine
RUN apk --update upgrade \
&& apk add --no-cache --no-progress certbot \
&& mkdir -p /etc/letsencrypt/live /var/www/html
DockerfileWeb
WordPressを動かすためのDockerfileです。WordPressのイメージをそのまま使うか悩みましたが、WordPressのディレクトリは私の方でバックアップしたものをそのまま使いたかったため、PHPのイメージを採用し、WordPressの公式イメージのDockerfileを流用しています。
docker-compose.yml
YMLファイルの中身です。詳細は省きますが、MySQLの初期ユーザやパスワード、データベースを起動時にセットアップしたり、全て自動で設定が完了するように仕掛けています。
version: '3.7'
services:
db:
container_name: hodalog_db
image: mysql:8
command: --default-authentication-plugin=mysql_native_password
env_file: ./code/db/.env
volumes:
- db_data:/var/lib/mysql
- ./code/db/backup-file.sql:/docker-entrypoint-initdb.d/backup-file.sql
ports:
- "3306"
web:
container_name: hodalog_web
build:
context: .
dockerfile: DockerfileWeb
volumes:
- ./code/web:/var/www/html
ports:
- "9000"
depends_on:
- db
nginx:
container_name: hodalog_nginx
build:
context: .
dockerfile: DockerfileNginx
volumes:
- ./code/web:/var/www/html
- ./code/nginx/conf.d:/etc/nginx/conf.d
- ./code/certificate:/etc/letsencrypt/live
ports:
- "80:80"
- "443:443"
depends_on:
- web
volumes:
db_data:
このYMLファイルで指定したサービス名とポート番号に合わせて、Nginxのコンフィグとwp-config.phpは少し修正します。
# nginx.conf
server {
listen 80;
server_name your-domain.com;
expires $expires;
root /var/www/html/hogehoge;
...
location ~ \.php$ {
...
fastcgi_pass wordpress:9000; #←これ
...
}
# wp-config.php
define('DB_HOST', 'db:3306');
移行先の準備
よしなに移行先を用意します。
監視の停止
モニタリングしている場合は止めます。私はUptimeRobotでpingとport監視、Mackerelでメトリクス監視をしていたので、一旦全部止めました。
切り替え作業
先のdockerファイルとYMLファイル、WordPressとSQLのバックアップ、SSL/TLS証明書一式を移行先へ持ち込み、デプロイします。
デプロイ後、エラーなどが発生していないか確認。今回はdocker-composeでデプロイしたので、 docker container logs
、 docker-compose logs
などで確認しました。
私はAWS内でのお引越しだったため、Route 53のゾーンはそのままに、ElasticIPを古いインスタンスから新しいインスタンスへ付け替えるだけで完了しました。
まとめ
Amazon LinuxからAmazon Linux2へのマイグレーションが無事完了しました。合わせてコンテナの分割とPHP7.1→7.3、MySQL5.7→8.0へのバージョンアップも終わり、非常にスッキリした環境に生まれ変わりました。
レガシーな手法ではありますが、インフラ周りの基本的な整備や扱いはもうバッチリですね。HexoやNuxt.js、Gatsbyなどの静的ジェネレータが気になっているので、転機がきたらそちらへ移行します。