レンタルサーバのWordPressをAWS(S3+CloudFront)に移行した話

# 背景

Webライターを営む妻からある日受けた相談。
レンタルサーバ(エックスサーバ)とWordPressでブログを運営しているが、サーバとかよくわからないから教えてほしい、というかそのままサーバ管理をやってほしいと。
~~良いネタが見つかった~~愛する妻を助けるため~~興味の赴くままに~~頑張った結果、気付いたら爆速かつ低コストなブログが出来あがっていました。

以下実際のブログなのでよければご覧ください！
https://urichiki.com/

# システム構成

## 概要

コンセプトとしては、WordPressをWebサーバとして運用するのではなく、WordPressで作成したコンテンツを静的化（html/css）し、Amazon S3に配置することでサーバレス化することを基本方針としています。
アイデア自体は目新しいものではなくすでに色々な記事で紹介されているので、構築手順や細かい説明は割愛して、簡単に各技術の導入背景等を説明していきます。
技術的な興味を持っていただいた方や、私と同じように静的化したブログ環境を構築したいと考えている方の参考になれば幸いです。

## 構成図

![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668635/fe4934a7-af5c-156d-9668-d14e8f7429fd.png)

### AWS

#### S3

ストレージサービス。このブログの中心部分です。
https://aws.amazon.com/jp/s3/

単純なストレージサービスとしてファイルを保存するだけでなく、保存したファイルをWebホスティングさせることも出来ます。ここでは、Wordpressを静的化したhtml/cssファイル等を配置し、S3からWebホスティングさせることを基本方針としています。

#### CloudFront

CDN(Contents Delivery Network)サービス。
https://aws.amazon.com/jp/cloudfront/

CloudFrontを利用することで世界中に配置されているエッジサーバ経由でオリジンサーバ(今回だとS3)にアクセスが行われ、取得したコンテンツがエッジサーバにキャッシュされます。ネットワーク的に最寄りのエッジサーバ経由でアクセスが行われ、かつキャッシュが有効な間はオリジンサーバへアクセスすることなくコンテンツが取得出来るため、オリジンサーバへのリクエストを大幅に削減することが出来ます。
また、今回はCloudFrontを利用することでHTTPS化にも対応しました。

#### Route 53

DNSサービス。
https://aws.amazon.com/jp/route53/

元々エックスドメイン（エックスサーバのDNSサービス）で管理されていたドメイン(urichiki.com)を、AWSで一元管理するためにRoute 53に管理を移行しました。

#### Lambda

サーバーレスコンピューティングサービス。
https://aws.amazon.com/jp/lambda/

S3に最新記事をアップしても、CloudFrontに古い記事がキャッシュされている間は最新記事が反映されません。この時間差を無くすため、S3に記事がアップされたイベントを検知し、キャッシュの無効化を自動で行うようLambda関数を作成しました。

### WordPress

#### Docker

WordPress自体はdocker-composeを利用し、MySQLとWordPressのコンテナをlocalhost上に立ち上げる構成としました。
コンテナ再起動時に作成した内容が消えてしまわないよう、volumesという設定を利用してコンテナ側ディレクトリをホスト側へマウントさせることで永続化しています。
https://qiita.com/tomokei5634/items/75d2501cfb968d0cfab5

また作成したデータはストレージサービス（ここではGoogle Drive）を利用して同期することで、複数のPCからでも擬似的にWordPressを同じように編集出来るようにしました。
ただし、複数のPCで同時にWordPressを編集した場合に競合してバグる恐れもあるので、編集作業自体は同時には実施しないよう注意する必要があります。今回は、ブログの編集者が私以外には妻だけで、口頭コミュニケーションで充分回避可能なので簡易的にこの構成としましたが、複数人数で編集を行う必要がある場合は普通にサーバを準備した方が無難かと思います。

補足)
当初はEC2にWordpressを配置しようと考えていましたが、以下の理由からDockerでlocalhostにWordpressを立ち上げる構成に変更しました。

- EC2はインスタンスの起動時間に応じて課金される。月1,000円以上のランニングがかかってしまうため、ランニングを抑えるためには毎回インスタンスの起動、停止をしないといけない。
- Wordpressのメイン編集者が妻なので、AWSコンソールに入ってEC2インスタンスの起動と停止を毎回させるのは手間

#### StaticPress

ブログの静的化はStaticPressというプラグインを利用。S3への転送はStaticPressS3というプラグインで、静的化と同時に自動でS3へ転送されるようにしました。
以下参考記事です。
https://qiita.com/Ichiro_Tsuji/items/c6a52ec0ee95ead42f68

#### その他

S3上ではコード実行が出来ないため、Wordpressの動的コンテンツ(コメント機能、ブログ内検索、お問い合わせフォーム等)は利用出来ません。
ここではブログ内検索だけはGoogleカスタム検索を入れて代替し、それ以外の機能は元々使ってなかったようなので特に対応はしませんでした。
なお、CloudFrontからLambda関数を呼び出すなどすれば、動的コンテンツ提供も可能です。

## コスト

### 旧レンタルサーバ（エックスサーバ）

サーバレンタル費用：1,000円/月
ドメイン更新料：1,650円/年

### 現在(AWS)

Route53のHostZone利用料：$0.50(約52円)/月
ドメイン移行費用：$12(約1,254円)　※初期費用のみ
ドメイン更新料：$12(約1,254円)/年

AWSの無料利用期間中のため、現状月のランニング費用は約50円だけです。
無料期間が終わってかつ多少アクセスが増えても、200〜300円/月以内には収まる試算。

## メリット/デメリット

### メリット

- とにかく速い
- ランニングコストが安い。アクセスが少ないうちはほぼノーコスト
- 静的ファイルをS3経由で提供するだけなので、セキュリティ問題とほぼ無縁。特にWordPressの脆弱性との戦いをしなくて良くなる
- もしアクセスが集中してもブログがダウンすることはまず無い

### デメリット

- 動的コンテンツの提供が難しい　※Googleカスタム検索などである程度代替は可能
- 構築に手間がかかり、知識も必要
- S3へのアップロードに時間がかかる

# まとめ

当初はちょっと設定をイジったり他のサーバに移行するぐらいのつもりでしたが、興味の赴くままに色々試していたら気づけばこの構成に。。。不思議ですね。
だいぶ寄り道しながら調べながら構築したので結構時間がかかってしまいましたが、結果それなりのものが出来たかなと思ってます。
妻も~~中身はよくわかってないみたいですが~~大変満足してくれたようです。

# 余談

## StaticPress プラグイン
StaticPressが、wp-admin配下等の静的サイトとしては不要なページまでファイル出力する仕様になっていたため、対処としてプラグインのソースコードを修正して不要なファイルが出力対象外になるようにしました。
ただ、プラグインのアップデートをするとこの修正が上書きされてしまうので、この手段はあまり好ましい手段では無かったかなと思います。
静的化プラグインは他にもいくつか選択肢があるみたいなので、安易にプラグインに手を加えてしまう前に他のプラグインを試してみるべきでした。

## PageSpeed Insights

体感的にはかなり爆速になったのですが、[PageSpeed Insights]("https://developers.google.com/speed/pagespeed/insights/")で見てみたところスコアがモバイル30点台、パソコン60点台と悲惨な点数に。。。
どうやらGoogleAdsenseがスコアに大きく影響する模様。
GoogleAdsenseの自動広告をマニュアル設定に変更したり、他にもWordPress側でプラグインや設定変更を少し試してみましたが、多少改善してパソコンは90点前後になったもののモバイルは50点前後止まり。
明らかに広告だけ遅延して表示されますが記事は爆速で表示されるので、ユーザの体感的には全く問題無いだろうということで時間との兼ね合いでここは諦めることに。悔しいのでそのうちどこかで再チャレンジしようと思います。