稼働中のWordPressをAWS Lightsailに移行する


## はじめに
会社で運用しているWordPressサイトをLightsailに移行したので、備忘録として残します。

WordPressサイトのサーバ移行には、プラグインを使う方法もありますが動作がブラックボックスではまることが多いので、手動でサーバ移行を行いました。
稼働中のWordPressは動かしたまま、Lightsailに同じWordPressを複製して、最後にドメインの向き先をLightsailに向ける、という流れで行っています。

## LightsailでWordPressを作成する
まずはじめに、AWSマネージメントコンソールのLightsailページで、移行先となるWordPressを新規に立ち上げます。
プラットフォームは「Linux/Unix」、設計図は「アプリ＋OS」の「WordPress」 を選択します。
![スクリーンショット 2020-11-16 14.58.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/831572/175888ce-a92b-0ffa-cb1c-c07e657914d7.png)

インスタンスが起動したら、静的IPを作成して起動したインスタンスに紐付けます。
ここらへんの流れはネットで検索すると画像付きの解説をされてるサイトがたくさんでてきます。

ブラウザからIPにアクセスしてWordPressの初期画面が表示されればOKです。

#### 移行前にWordPressのバージョンを合わせる
LightsailのWordPressはバージョンを選択できません（記事書いてる時点で5.4.2固定）
もし移行予定のWordPressが古い場合は、事前にアップグレードしてバージョンを近づけておいた方が確実です。
ただ私の環境では事情によりアップグレードができなかったので、4.7.3のWordPressをそのまま移行しましたが特に問題は起きませんでした。

## WordPress本体を移行する
WordPress本体にはたくさんのファイルが存在しますが、コアファイル群は新規に作成したWordPressのものをそのまま使い、プラグインやテーマが入っているwp-contentディレクトリのみ旧WordPressから移行します。

LightsailにSSHで入り以下を実行

```shell
# 旧WordPressをLightsailの中に持ってくる
git clone git@github.com:best-teacher-production/myapp.git
# LightsailのWordpress本体が配置されているディレクトリに移動
cd /home/bitnami/apps/wordpress/htdocs
# 新WordPressのwp-contentをリネームして
mv wp-content/ wp-content.original
# 旧WordPressのwp-contentのシンボリックリンクを貼る
ln -s /home/bitnami/myapp/wp-content
```
WordPressサイトをgit管理しているので少し面倒なことをしていますが、git管理不要であれば単純に`/home/bitnami/apps/wordpress/htdocs/wp-conent/`を旧WordPressのwp-contentに差し替えるだけで問題ありません。

## wp-config.phpの修正
Lightsailのwp-config.phpは`/home/bitnami/apps/wordpress/htdocs/wp-config.php`にあります。

デフォルトの設定ではサイト内のリンクアドレスがIPアドレスになっているので、ドメイン名にするために以下の修正をします。

```diff
- define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST'] . '/');
- define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST'] . '/');
+ define('WP_SITEURL', 'https://自分のドメイン名');
+ define('WP_HOME', 'https://自分のドメイン名');
```

また、wp-config.phpに独自の設定を追加している場合（自分で定義した定数など）は新しいwp-config.phpに設定を移行します。

設定変更したらApacheを再起動して反映させます。

```shell
sudo /opt/bitnami/ctlscript.sh restart apache
```

## DBデータを移行する
DBデータは、旧WordPressのMySQLデータを丸ごとmysqldumpして、新WordPressのMySQLにリストアします。

ダンプファイルbackup.sqlをLightsailに移して以下コマンドを実行

```shell
# ユーザー名とパスワードは/apps/wordpress/htdocs/wp-config.phpで確認可
mysql -u ユーザー名 -pパスワード bitnami_wordpress < backup.sql
```

私の環境では、バージョン4.7.3のデータを5.4.2のWordPressにリストアしたので、リストア後ダッシュボードに「データベースの更新が必要です」というメッセージが出ましたが、更新ボタンを押して正常に更新できました。WordPressがアプリとDBのバージョン差を検知して更新してくれます。

## SSL対応
DNSを切り替える前に、事前にSSL証明書を移行しておきます。
SSL証明書の移行は、現サーバーの証明書を引き続き使うか、新しく作り直すか、どちらでも可能なので状況に応じて選択します。
Let's Encryptのような無料証明書を使ってる場合は、その後の更新のことも考えると新しいサーバで新しく作り直してしまった方が楽です。
今回はcertbotというツールを使って証明書を新しく作ることにしました。
https://github.com/certbot/certbot

注意点として、この段階でドメインはまだLightsailに向いてないので、`DNS-01`というチャレンジ方式で証明書を作成する必要があります。
（certbotコマンドをネットで検索すると大抵`HTTP-01`チャレンジ方式で紹介されています。ドメインが既に自分のサーバに向いている場合のみこのチャレンジ方式が可能です）

チャレンジ方式について
https://letsencrypt.org/ja/docs/challenge-types/

certbotコマンドについては以下のドキュメントが詳しいです。
https://certbot.eff.org/docs/

```shell
# certbotをgit cloneする
git clone https://github.com/certbot/certbot
cd certbot
# チャレンジ方式にDNS-01を指定してSSL証明書を作成するコマンド
./certbot-auto certonly --manual --preferred-challenges dns-01 -d 自分のドメイン名
```

このコマンドを打つと以下のようにログが流れます。

```shell
Requesting to rerun ./certbot-auto with root privileges...
./certbot-auto has insecure permissions!
To learn how to fix them, visit https://community.letsencrypt.org/t/certbot-auto-deployment-best-practices/91979/
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for 自分のドメイン名

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.

Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.自分のドメイン名 with the following value:

# ここに認証文字列が表示される

Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
```

ここでログが止まるので、指示された通り、表示された認証文字列をDNSのTXTレコードに登録し、Enterを押します。
正常に認証されたら、SSL証明書が作成されます。

作成されたSSL証明書をApacheに配置して再起動します。

```shell
sudo cp /etc/letsencrypt/live/自分のドメイン名/fullchain.pem /opt/bitnami/apache2/conf/server.crt
sudo cp /etc/letsencrypt/live/自分のドメイン名/privkey.pem /opt/bitnami/apache2/conf/server.key
sudo /opt/bitnami/ctlscript.sh restart apache
```


#### httpsアクセスを強制する
SSL対応してもhttp直打ちすればアクセスできてしまうので、httpのアクセスをhttpsにリダイレクトさせます。
Lightsailでは`/opt/bitnami/apps/wordpress/conf/httpd-prefix.conf`で設定できます。

```diff
- RewriteCond "%{HTTP_HOST}" ^ec2-([0-9]{1,3})-([0-9]{1,3})-([0-9]{1,3})-([0-9]{1,3})\..*\.amazonaws.com(:[0-9]*)?$
- RewriteRule "^/?(.*)" "%{REQUEST_SCHEME}://%1.%2.%3.%4%5/$1" [L,R=302,NE]
+ RewriteCond %{HTTPS} !=on
+ RewriteRule ^/(.*) https://自分のドメイン名/$1 [R,L]
```
修正したらApache再起動します。

```shell
sudo /opt/bitnami/ctlscript.sh restart apache
```

## ドメインの参照先を変更
準備が整ったら最後にDNSレコードを修正してドメインの向き先を旧サーバからLightsailに切り替えます。
ブラウザから`https://自分のドメイン名`にアクセスして、以下のアクセスログにログが流れれば移行完了です。

```shell
tail -f /opt/bitnami/apache2/logs/access_log
```


## その他の設定

#### 環境変数を設定する
環境変数を使う場合は、`/opt/bitnami/php/etc/php-fpm.conf`に設定します。
このファイルを変更したらphp-fpmを再起動します。

```shell
sudo /opt/bitnami/ctlscript.sh restart php-fpm
```

#### .htaccessファイル
Basic認証などアクセス制限をかける時は、通常のWebサーバでは.htaccessファイルを使いますが、Lightsailでは`/home/bitnami/apps/wordpress/conf/htaccess.conf`という設定ファイルが用意されているので、このファイルに設定を記述します。


## おわりに
今回はLightsailに移行しましたが、違う環境に移行する場合でも応用が効くと思います。
やることは同じで、まっさらなWordPressを用意して、そこにwp-contentとDBデータを移行するだけです。

Lightsailは各種設定ファイルの配置場所が特殊なので、最初は少し戸惑いました。Bitnamiというソフトウェアが元になってるので、困った時はBitnami WordPressで検索すると情報が見つかりやすかったです。