落ちないWebサイトの構築
先日、このサイトとは別に運用しているWordPressの1つが不安定になってしまい、不具合の原因を調べたところMySQLのアップグレードが原因でutf8mb4の文字コード指定に異常が発生していた。
復旧のために対象DBの文字コードの異常を修正する必要があったので、一度Dumpしてからリストアを実行し復旧させた。
復旧は軽微な対応で済んだのだけど、今後は手間をかけずに、サーバーレス的な継続的な改善ができるようにしたい。
今回の課題
- 現行のWordPressサイトの本番環境を手間をかけずに安定運用させる
- まず最低限の機能で構築
- 保守コスト優先、WordPressの管理画面をベースにする
- CloudFrontでホスティングすることでサーバレスな機能を運用する
- 構築後に検索やSEO対策の機能を実装する
- WordPressなのでセキュリティリスクが発生しないように注意する
実現方法の候補
- StaticPress
日本人の開発者が作ったWordPressのプラグイン。
オリジナルは3年以上メンテナンスされていないため脆弱性の懸念がある。古くからあるプラグインのため、脆弱性やバグ対策のソースコードも公開されている。 - WP2Static
元はSimpleStaticという名前だったWordPressのプラグイン。完全なOSSで公開されていて自由なカスタマイズが可能。WP CLIにも対応しているので自分でWordpressを管理できる人にはとても都合がよい。CDNに乗せれば高機能かつ安定運用が可能になる。 - Hugo
Go言語にHugoというフレームワークがあり、高機能なhtmlテンプレートエンジンとして利用が可能。CDNに乗せれば格安で高機能かつ安定運用が可能になる。ただしWordPressの機能やノウハウを捨てることになる。 - Shifter(サービス)
Wordpressを静的サイトで公開するホスティングサービス。価格も良心的。ただしCDN等へ配置してバックエンドをカスタマイズしたい場合は2度手間になってしまう。 - kusanagi(サービス)
WordpressをフルカスタマイズしたOSSソリューション。日本のベンダが提供しているためサポートも信頼できるがシステムとして導入すると価格が高い。(1インスタンス15万円)
レンタルサーバで提供されているkusanagiを利用する場合はホスティング費用だけでよいのでコストパフォーマンスは悪くない。ただ、どの程度サポートされるのか、プラグインやテーマは全て利用可能なのか、自前でWordPressのソースやnginxもカスタマイズ可能なのか、WPとKusanagiの二重運用になりコストが高くなる。
元がWordPressなのでGPLとしてOSS版も提供されているが、最適化のためにNginxからビルドする前提になっておりWordPressと別のノウハウも必要になるため運用コストがかかる。良くも悪くもWordPressのカスタマイズバージョン。 - k8s
WordPressの勉強会でREST-APIでヘッドレス運用してk8sに乗せてCDN配信する話を聞いた。CDN配信のソースをk8sへデプロイしてCIは外部のSaaSへお任せというのは贅沢で良いけど、本番が静的ページでCDNに乗せるならk8sにする意味はあるのか(S3やGCSで良いのでは?)、Pod上で静的ページだけではなくvueでREST-APIと通信しているならWordPressのような記事ベースのコンテンツでは脆弱性が含まれるのではないか。色々と疑問が残る。
WP2Staticを利用する
-
今回の課題解決はWordPressのサイト全体を静的なhtmlに変換してくれるWP2StaticというWPプラグインを利用する。
-
■採用の理由
- WordPressの機能を引き継げるので、サイトのテンプレートデザインや面倒なSEOの設定を管理しやすい
- プラグインのフル機能がOSSで提供されているため問題があれば改修できる
- WP管理画面からの操作だけでなく WP CLIにも対応しているためバッチ処理で管理できる
- 本番サイトを静的ページで運用できるため大部分のセキュリティリスクを回避できる
- AMPやSEO用のメタタグ等、多くのWordPressの便利機能を利用することができる
アーキテクチャ
- 現在のWordPress環境はSTG環境として運用する
- 本番サイトはAWS S3に配置してCloudFrontで配信する
- 自動化を前提にWP CLIで運用できる構成にする
- クローリングは可能な限りWP2Staticで行う(WP CLIで制御可能なため)
- WP2Staticではトップページ以外のクローリングができないため、ページネーションのインデックスは独自スクリプトを構築する
- サイト内検索はいったん排除する(後日にJavascriptのサイト内検索を設置する。検索URLのみ動的サーバへ転送することもできるがセキュリティリスクを避けて本番はサーバレス構成で運用する)
- Lambda Edgeの処理が可能になるのでnodejsで動的処理をする
- 汎用的な顧客の問い合わせ機能や予約フォームは、CRMやMA,GoogleForm等で提供することでセキュリティリスクを抑えて機能を提供し、かつ一元管理が可能になる
- 顧客対応用の恒久的な問い合わせページはMauticを利用する
- アンケートや不特定多数からの問い合わせ、予約受付等はGoogle Formを利用する
- マイクロサービス(フロントエンドやバックエンドのAPI連携等)は、Lambda Edgeを利用する
WP2Staticの課題と対策
-
日本語URLのクローリングとファイル出力
- 対策
パーマリンクを記事IDベースに変更
- 対策
-
ページ分割された過去記事(pagenation)のクローリングが不完全で出力されない
- 対策
毎回すべての記事をページングするスクリプトを別途作成しておく
※1度に10件以上の投稿をしなければトップページのクロールだけで記事を正しく出力できるが、10件以上登録したときにページングの整合性があわなくなる可能性があるため対策を設計しておく
- 対策
-
投稿の属性(カテゴリ、タグ、日付)を含めたURLが出力されない
- 対策
前項の対策と同じようにWP CLI等で全ての記事を出力できるスクリプトを作成しておくとよい。
- 対策
-
サイト内検索の機能が提供できない
- 対策
※aを検討中 - a. mecab等で検索インデックスを構築して、本番の検索フォームと紐付ける
- b. STG環境のWordPressのAPIとPOSTで通信させる
- c. AWS Cloud Serarch等のサイト内検索用のWebサービスを契約する(コストが高い)
- 対策
-
投稿記事(single)のAMPが出力されない
- 対策
WP2Staticへ明示的に"/amp"もしくは"?amp"のページを登録するとAMP用の静的ページが生成される
- 対策
まとめ・雑感
- 「WP2Static」で構築したサイトは「AMP」プラグインのページ出力も正常に機能している
- 「WordPress ping Optimizer」は残念ながら正常に機能しなかった(元サイトのURLをベースに通知してしまう)
- CloudFrontへ配置したサイトをLighthouseで計測すると、初回実行Performance98、2回目以降はPerformance100になった。(CDN配信なので2回めから早い)
元が軽量なページなので高速化していないが静的サイト化で悪化するようなことはなかった。