WordPress サイトを静的化して S3+CloudFront で配信する方法


とあるプロジェクトで、WordPress サイトを更新していないので S3+CloudFront に移行してほしいと言われました。手順をまとめます。

※寝落ちしそうになっているので、めちゃくちゃ手抜きで、途中の手順を端折ってます。誤字脱字もあると思うので、時間ができた時に修正します。


# WordPress での準備: 動的要素の部分をなくす

## STEP 1: 移行開始前にバックアップを取得する。

なんでもバックアップしましょう。

まず、作業開始前に WordPress のファイル DB をバックアップして、いつでも切り戻せるようにしましょう。

## STEP 2: 動的要素を取り除く。

WordPress 側でページがアクセスされるごと、ユーザーの挙動によって表示が変わるもの。メールフォームなど、情報を一般ユーザーから受け付けるものなどを僕は勝手に「動的要素」と言っています。

- メールフォーム
	- PHP は動かないので、別のサービスを利用するか、お問い合わせフォームだけ、PHP, 
- 画像・テキスト・リンクランダム表示するウィジェット
	- ウィジェットのタイトルを「ランダム」から「ピックアップ」などに変更するだけでも良い
- リンクがランダムで切り替わるもの
- `/?page_id=XXX` などパーマリンクがクエリとして登録されている
	- これ鬼門です

## STEP 3: そもそものサイトの修正できるところを修正する（オプション）

### リンク切れを治す

サイトの中にはコンテンツが古くてリンク先が 404 になっている場合もあります。

リンク切れを探知するツールは、WordPress プラグイン、Chrome 拡張、npm パッケージなど、いろいろあるので、自分の環境に合わせて入れて、リンク切れを確認しましょう。

- WordPress プラグイン: [Broken Link Checker](https://ja.wordpress.org/plugins/broken-link-checker/)
- npm パッケージ: [Broken Link Checker](https://github.com/stevenvachon/broken-link-checker)

WordPress から静的化したら、メンテが面倒になります。WordPress にあるうちにリンク先を修正しましょう。

### Google Analytics Tag を Google Tag Manager に移行する

Google Analytics のタグを直接入れている場合、HTML 化した後に更新するのが面倒いので、Google Tag Manager に移行するとあとはよろしく運用できます。

## STEP 4: 不要なプラグインを無効化する

静的HTMLにすることで、うまく働かないプラグインを無効化しましょう。


## STEP 5: 検索系は無効化＆削除

検索系は外部のサービスを使わなければ、動かなくなります。WordPress で使っている検索系は無効化し、検索語句をいれるテキスト入力欄などを削除しましょう。

## STEP 6: 404 ページを保存

404 などのエラーページを error.html という HTML ファイルで保存し、あとで使えるようにしましょう。

後述の Simply Static プラグインはエラーページを静的化してくれませんでした。

変な置換処理を行なっていなければ Google Chrome などで HTML だけを保存しましょう


## STEP 7: WordPress 静的化アドオンをインストールする。

今回は [Simply Static](https://ja.wordpress.org/plugins/simply-static/) を利用しました。

- プラグインをインストール
- 出力実行

HTML 化したパッケージを入手します。


## STEP 8: S3 バケットを作成 & ファイルをアップロード


任意の名前で S3 バケットを作成します。

- Static Web Hosting を有効化
	- index.html & error.html を設定
- Bucket Policy ではパブリックアクセス許可しましょう

```
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFront",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3::バケット名/*"
        }
    ]
}
```

本当は OAC を有効化したいんですが、index.html や 403 & 404 表示をきちんとさせるために、静的ウェブホスティング機能を使うために、S3 側ではパブリックアクセスを有効化する必要があります。

S3 バケットを作成したら、WordPress から生成した HTML ファイルをアップロードします。

AWS CLI の s3 sync か s3 cp コマンドを使いこなすと、高速でファイル転送ができて便利です。


## STEP 9: CloudFront Function を設定

下層ページでもスラッシュ終わり`/`な URL は、きちんと、そのディレクトリの中にある index.html を見に行くということができません。

代わりに、CloudFront Function を利用します。


名前: redirect-to-indexhtml

```
function handler(event) {
    var request = event.request;
    if (request.uri !== "/" && (request.uri.endsWith("/") || request.uri.lastIndexOf(".") < request.uri.lastIndexOf("/"))) {
        if (request.uri.endsWith("/")) {
            request.uri = request.uri.concat("index.html");
        } else {
            request.uri = request.uri.concat("/index.html");
        }
    }
    return request;
}
```

- 参考: [Redirect to index.html for S3 subfolder](https://stackoverflow.com/questions/49082709/redirect-to-index-html-for-s3-subfolder)

これで、下層パスでも、スラッシュで URL が終わったとしても、/index.html を見に行くようになります。

index.htm など特殊な場合があれば、適宜上記 Javascript を変更してください。


## STEP 10：SSL 証明書を発行する

バージニアリージョン (us-east-1) の ACM で CloudFront で使う SSL 証明書を発行 or 登録しましょう。


## STEP 11: CloudFront の Distribution を作成する

あとは、CloudFront + S3 な静的 Web サイトを作る容量で、Distribition を作成してください。

SSL 証明書を選択。


オリジンは **S3 の静的 Web ホスティングのエンドポイント** を使用します。

403 や 404 などのエラーページを、S3 の設定時に登録した error.html (STEP 6参照) を指定して表示するようにします。


## STEP 12: Hosts を書き換えて表示テスト

切り替える前に表示テストをします。

CloudFront もしくは S3 のエンドポイントを調べて、dig コマンドなどで、その瞬間の A レコードを取得します。

（CloudFront & S3 は頻繁に IP アドレスが変わります)

```
dig xxxxxx.cloudfront.net
```

そうして、自分の PC の hosts を書き換えて、表示テストをします。

```
XXX.XXX.XXX.XXX exmaple.com
```

この際に、SSL 証明書、CloudFront Function のテストもできます。

一番重要なのは、リンク切れなどがないかの確認です。

STEP 3 で紹介した npm パッケージ [Broken Link Checker](https://github.com/stevenvachon/broken-link-checker) を使って、静的HTMLサイト化したあとのサイトのリンク切れ確認もしておきましょう。

僕の場合、画像の一部が正常に出力されていなかったり、テーマフォルダの中の JS、SVG のアセットが正常に HTML パッケージに出力されないといった問題を発見することができました。

ひとまず、最低限必要なファイルは、Google Chrome の Developer ツールを使い 404 になっているファイルを探して、WordPress サイトから手動で移動しました。


## STEP 13: DNS 本番切り替え

DNS を切り替えて、晴れて WordPress サイトが静的化できます。


以上