Ubuntu 16.04 + nginx + PHP 7.2 環境に WordPress を手動で移行する

# やりたいこと
共用レンタルサーバから VPS に WordPress を移行する。
VPS を使う理由は、Ruby on Rails を使いたいから。

将来的に WordPress から Ruby on Rails へ切り替え予定のため、ドキュメントルート下に WordPress 用のサブフォルダを作り、そこに移行元 WordPress のファイル／フォルダを入れる。

今回は WordPress の移行ツールやプラグインを使用せず、手動でデータを移行した。

# 環境
## 移行元サーバ

ディストリビューションのバージョンは分からなかった。
Linux カーネルのバージョンは以下の通り。

```console:198.51.100.10
$ cat /proc/version
Linux version 2.6.32-673.26.1.lve1.4.20.el6.x86_64 (mockbuild@build.cloudlinux.com) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC) ) #1 SMP Tue Dec 27 17:42:53 EST 2016
```

サーバプログラムのバージョン情報は専用のコントロールパネルより取得。

| サーバプログラム | バージョン |
| :-- | :-- |
| Apache | 2.2.32 |
| PHP5 | 5.6.30 |
| MySQL5 | 5.6.35 |

サーバアドレスは`198.51.100.10`、ユーザアカウントは`hoge`とする。SSH 接続で使用するポート番号は`2222`である。
また、WordPress のインストールディレクトリは`/home/hoge/public_html/example.com`とする。 

## 移行先サーバ
```console:203.0.113.100
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"
$ cat /proc/version
Linux version 4.4.0-116-generic (buildd@lgw01-amd64-021) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9) ) #140-Ubuntu SMP Mon Feb 12 21:23:04 UTC 2018
$ nginx -v
nginx version: nginx/1.12.2
$ php-fpm7.2 -v
PHP 7.2.3-1+ubuntu16.04.1+deb.sury.org+1 (fpm-fcgi) (built: Mar  6 2018 11:18:25)
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.3-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.21, for Linux (x86_64) using  EditLine wrapper
```

サーバアドレスは`203.0.113.100`、ユーザアカウントは`foo`とする。SSH 接続で使用するポート番号は`22`である（注：本番環境は別のポート番号を指定しています）。
nginx のドキュメントルートは`/usr/share/nginx/html/`と設定しており、ホームディレクトリ直下に`www`という名前のシンボリックリンクを作成している。

# 移行元サーバ側での事前作業
## 不要なバックアップデータの削除、バックアッププラグインの停止
BackWPup という WordPress プラグインを使用していたが、バックアップデータが巨大化していた。データ転送量を増やしたくないので、このバックアップデータを削除し、プラグインを一旦停止。
（そもそも移行元サーバの cPanel が定期的にバックアップを取っていたから、プラグインによるバックアップ自体が不要だった）

## キャッシュデータの削除、キャッシュプラグインの削除
移行元サーバでは、以下の WordPress キャッシュプラグインを使用していた。

- W3 Total Cache
- Autoptimize

これらのプラグインも停止し、以下のコマンドでキャッシュフォルダごと削除した。

```console:198.51.100.10
$ rm -rf ~/public_html/example.com/wp-content/cache
```

001 Prime Strategy Translate Accelerator はプラグインフォルダの下にキャッシュを生成していたため、管理画面側でキャッシュを削除。

## WordPress インストールディレクトリの直書き箇所の修正
僕は WordPress の機能の一部をカスタマイズしており、その際に `/home/hoge/public_html/example.com/` と WordPress のインストールディレクトリを直書きしていた箇所があったので、`ABSPATH` に置き換えた。

# WordPress ファイル／フォルダの移行
## 移行元 WordPress ファイル／フォルダのアーカイブ化と圧縮

```console:198.51.100.10
$ cd ~/public_html
$ tar zcvf ~/example-wp.tar.gz example.com
```

## 圧縮したアーカイブファイルを移行先サーバへ転送
```console:203.0.113.100
$ scp -P 2222 hoge@198.51.100.10:~/example-wp.tar.gz ~/
```

移行元／移行先どちらで行なっても良いが、移行先サーバが公開鍵認証のみ許可しているので、移行元サーバの鍵作成＆登録の手間を省くため移行先で`scp`を実行した。

移行元から`scp`を使用したい場合は、以下のようにする。

```console:198.51.100.10
$ scp ~/example-wp.tar.gz foo@203.0.113.100:~/
```

## WordPress アーカイブファイルの解凍と展開
`~/www/wordpress`ディレクトリに展開する。

```console:203.0.113.100
$ cd ~/www
$ tar zxvf ~/example-wp.tar.gz
$ mv example.com wordpress
```

アクセス権限も変更しておく。

```console:203.0.113.100
$ sudo chown -R nginx:nginx wordpress
$ sudo find wordpress -type d -exec chmod 4775 {} \;
$ sudo find wordpress -type f -exec chmod 664 {} \;
$ sudo chmod 660 wordpress/wp-config.php
```

アクセス権限の設定は以下のサイトを参考にした。

- [WordPressのファイルのパーミッションはどうすべきなのか(WordPress the Right Way)](https://php-java.com/archives/622)

# nginx の設定
## nginx 設定ファイルの編集
```console:203.0.113.100
$ sudo vi /etc/nginx/conf.d/default.conf
```

```nginx:/etc/nginx/conf.d/default.conf
server {
  listen 80;
  server_name example.com;
  root /usr/share/nginx/html/wordpress;
  index index.php index.html;

  location / {
    try_files $uri $uri/ @wordpress;
  }

  location ~* /wp-config.php {
    deny all;
  }

  location ~ [^/]\.php$ {
    try_files $uri @wordpress;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }

  location @wordpress {
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_pass unix:/run/php/php7.2-fpm.sock;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/wordpress/index.php;
  }
}
```

nginx の設定は以下のサイトを参考にした。

- [nginxでwordpressのパーマリンクをデフォルト以外に対応する](https://qiita.com/egnr-in-6matroom/items/a08f4851bf16d0131e60)
- [nginx fastcgi_params を include する箇所、割と皆間違ってるよね？](https://qiita.com/kotarella1110/items/f1ad0bb40b84567cea66)

## nginx 設定ファイルのテスト
```console:203.0.113.100
$ sudo service nginx configtest
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

上記では`/etc/nginx/nginx.conf`をテストしているように見えるが、同ファイル内で`/etc/nginx/conf.d/default.conf`をインクルードしているので、変更したファイルも問題なくテストできている。

## nginx の再起動
```console:203.0.113.100
$ sudo systemctl restart nginx.service
```

## nginx の設定反映確認
`wp-config.php`がアクセスできないことだけ確認しておく。

Webブラウザで`http://203.0.113.100/wp-config.php`にアクセスすると、`403 Forbidden`と nginx のエラーメッセージが表示された。

ちなみに設定前に`wp-config.php`にアクセスすると、何も表示されない。`wp-config.php`は標準出力を使用していないからである。

# WordPress データベースの移行
## データベース情報の確認
```console:198.51.100.10
$ cat ~/public_html/example.com/wp-config.php | grep DB_
define('DB_NAME', 'example_wp');
define('DB_USER', 'example_wp');
define('DB_PASSWORD', 'p@sSw0rD');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
```

## 移行元データベースのエクスポート
`mysqldump`コマンドで SQL ファイルを出力。

```console:198.51.100.10
$ mysqldump -u example_wp -p'p@sSw0rD' -r ~/example_wp.sql --single-transaction example_wp
```

注意点として、`-p`とパスワードの間にスペースは入れない。
パスワードが画面に表示されるのが嫌であれば、`-p`とだけ打てば対話式でパスワードを入力できる。

転送用に SQL ファイルを圧縮。

```console:198.51.100.10
$ cd ~
$ tar zcvf db_example_wp.tar.gz example_wp.sql
```

## エクスポートファイルを移行先サーバへ転送
```console:203.0.113.100
$ cd ~
$ scp -P 2222 hoge@198.51.100.10:~/db_example_wp.tar.gz .
```

## MySQL データベース＆ユーザ作成と権限付与
エクスポートした SQL にはデータベース作成コマンドが含まれていないため、エクスポート前に作成が必要。
WordPress アクセス用の MySQL ユーザもこのタイミングで作成し、データベースのアクセス権限を作成したユーザに付与する。

```console:203.0.113.100
$ sudo mysql -u root
```

```sql:mysql
> create database example_wp;
> create user example_wp@localhost identified by 'p@sSw0rD';
> grant all on example_wp.* to example_wp@localhost identified by 'p@sSw0rD';
> flush privileges;
> [Ctrl+D]
```

## データベースのインポート
転送した圧縮ファイルを解凍する。

```console:203.0.113.100
$ tar zxvf db_example_wp.tar.gz
```

移行元の OS ユーザアカウントと移行先の OS ユーザアカウントが異なる （今回はそれぞれ`hoge`と`foo`のため、異なる）場合、SQL ファイルから以下の行を削除する必要がある。

```sql:example_wp.sql
/*!50013 DEFINER=`hoge`@`localhost` SQL SECURITY DEFINER */
```

SQL ファイルを実行し、移行先データベースにデータをインポート。

```console:203.0.113.100
$ mysql -u example_wp -p'p@sSw0rD' example_wp < example_wp.sql
```

## データベース移行で参考にしたサイト
- [MySQLのデータインポート・エクスポート](https://qiita.com/rato303/items/2e614f23e5feee150ffc)
- [mysql ユーザー作成＆権限追加](https://qiita.com/YoheiMiyamoto/items/f454a6c759f2245b085f)
- [MySQLのデータベースをまるっとお引越し。 (エクスポート/インポート)](https://qiita.com/sango/items/84a45e5911d719a2c08c)
- [ダンプリストア時にAccess denied; you need (at least one of) the SUPER privilege(s) for this operation](https://qiita.com/bourbonizable/items/4f13ca2327b6e0347d76)

# 稼動確認
Web ブラウザから`http://203.0.113.100/`にアクセスしてみる。
トップページ、個別記事、カテゴリ一覧、タグ一覧、検索結果などを開き、表示に問題がないことを確認。

キャッシュの設定をしていないのにも関わらず、応答が早い。さすが VPS、さすが nginx である。

# 後始末
移行時に作成した中間ファイルを削除する。

```console:198.51.100.10
$ rm ~/example-wp.tar.gz ~/db_example_wp.tar.gz ~/example_wp.sql
```
```console:203.0.113.100
$ rm ~/example-wp.tar.gz ~/db_example_wp.tar.gz ~/example_wp.sql
```

# 参考サイト
設定の全体の流れは以下のサイトを参考にした。

- [nginxでwordpressを動かすには](https://qiita.com/fk1/items/3ef1d989d1d5e44a1d03)
- [WordPressの他サーバーからの移転方法（プラグイン不使用）](https://support.mixhost.jp/375)