WordPress を AWS(Lightsail)で運用する方法

このブログはWordPressをAWS(Lightsail)で稼働させて運用しているのだが、当初色々と設定周りでかなり試行錯誤したので備忘録として記事にしておく。完成イメージとしては以下の3つが満たされるも。

  • WordPressの中身も興味あったので稼働実サーバにログイン可能なEC2等で動かしたい
  • 独自ドメインで運用させたい
  • CloudFront経由、HTTPSにて配信させたい

WordPress稼働サーバとしてLightsailの選択

色々な記事を調べてみるとEC2を自前で立てつつ、PHP, DB(MySQL) の環境を用意し、そこにWordPressをインストールするという苦行を行う時代では無いことにすぐに気がついた。さらにAWSにはLightsailなる便利なソリューションが最近はあるよう。LightsailはAWSの記事を引用すると以下のように記載されています。

Lightsail は使いやすい仮想プライベートサーバー (VPS) であり、アプリケーションやウェブサイトの構築に必要なすべてのものに加えて、コスト効率が良い月額プランを提供します。クラウドに慣れていないお客様でも、信頼している AWS インフラストラクチャを使用してすぐにクラウドにアクセスしようとしている場合も、対応できます。

https://aws.amazon.com/jp/lightsail/

要はなにかしたい目的があったらそれにふさわしい、必要なものをパッケージ化して提供してあげますよ。ということでしょうか。これにWordPressパッケージがあるようなのでそれを使うことにします。

Lightsailを起動する

AWSのマネージメントコンソールからLightsailを選択する。ちょっとテイストの変わった画面に変わるがそこにある、「インスタンス」という項目にある「インスタンスの作成」を選択する。以下のような画面が表示されるので以下のように選択する

  • 稼働リージョンを「東京
  • インスタンスイメージを「Linux + WordPress
  • インスタンスプランを最も安い「$3.5(最初の 1 か月 (最大 750 時間) 無料 2021.5.9現在 )
  • SSHキーペアマネージャでデフォルトのものをダウンロードしておく(LightsailDefaultKey-ap-northeast-1.pem というファイルがダウンロードされるはず)

その他色々はデフォルトのまま「インスタンスの作成」をクリックする。メインの画面に戻ると右のようにLightsail起動中のインスタンスが1つ登録される(私はこのブログで運用のものがすでにあるのでWordPress-“2” となってる)

もしかすると保留中となるかもしれないが暫く待つと実行中になるはず。右上の3点アイコンをクリックすると「停止」や「再起動」などいわゆるインスタンスの操作がここからできる

パブリックIPの割当

上の例だと起動インスタンスには「18.181.172.174」が割り当てられ、外部からはアクセスできない、また再起動毎に変化するのでので、これに静的IPを付与する。「ネットワーキング」のタブから「静的IPの作成」を選び、インスタンスへのアタッチで作成したインスタンスを選択、「作成」を押すと静的IPがインスタンスに付与される。(静的IPはインスタンスに割り当てている条件で、5つまで無料で付与される。)

元のインスタンスの画面に戻ると先程まで内部IPだったものが割り当てた静的IPに変わっていることが確認できると思う。更にブラウザでHTTPアクセスするとWordPressのデフォルトのページが表示される。

サーバにSSH接続してみる

インスタンスを選択するとインスタンスの詳細が確認できる。「接続」のタブではSSHの方法が記載されている

「SSHを使用して接続」を押すとブラウザ上でターミナルが起動されログインできる。が、いまいち使いにくいので今回はターミナルを利用する。このページの下部に「bitnami」というアカウントで接続できる記載があるのでそれに従う。

# インスタンス作成時にダウンロードしたKey。 パーミッションを変更しておく(初回のみ)
% chmod 400 LightsailDefaultKey-ap-northeast-1.pem  
% ssh -i ./LightsailDefaultKey-ap-northeast-1.pem bitnami@[割り当てられた静的IPアドレス]

特に問題なくログインができると思います。

ログインして中身を探索すると以下のことが分かる

  • “/opt/bitnami/”以下にアプリケーション (WordPress, Apache2, MySQLが配置されている)
  • MySQL, Apache2 (php-fpm) が稼働中
  • phpmyadminがインストールされているようだがLocalHostからの接続のみ許可しているっぽい
  • WordPress は “/ope/bitnami/app/wordpress”
  • 実質のApache DorumentRootは “/opt/bitnami/apps/wordpress/htdocs”

ログインディレクトリ (/home/bitnami) 直下に bitnami_application_passwordbitnami_credentials のファイルがあり、ここにWordPressやMySQLに接続するパスワードが記載されている。試しにMySQLにアクセスしてみる (userはroot、パスワードは bitnami_application_password に記載の文字列)。

bitnami@ip-172-26-11-246:~$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 18
Server version: 8.0.23 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| bitnami_wordpress  |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

mysql> connect bitnami_wordpress
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Connection id:    19
Current database: bitnami_wordpress

mysql> show tables;
+-----------------------------+
| Tables_in_bitnami_wordpress |
+-----------------------------+
| wp_commentmeta              |
| wp_comments                 |
| wp_links                    |
| wp_options                  |
| wp_postmeta                 |
| wp_posts                    |
| wp_term_relationships       |
| wp_term_taxonomy            |
| wp_termmeta                 |
| wp_terms                    |
| wp_usermeta                 |
| wp_users                    |
+-----------------------------+
12 rows in set (0.00 sec)

という風にMySQLにログインでき、WordPress関連Tableも確認できる。一旦ログアウトして、WordPressの管理画面にアクセスしてみる。 http://[割り当てられた静的IP]/wp-admin にアクセスする. ログイン画面がでるので、bitnami_credentials に記載されたログイン情報を入力するとWordPress管理画面が表示される

CloudFront経由のHTTPS環境を整える

このままだと、HTTPでの配信、固定IPの露出などWordPressを公開できる状態にはない。CloudFrontを経由させてドメイン、HTTPSにてアクセスできる環境を整える。 このブログを構築時ここが一番ハマったところであり、この記事もこの部分の備忘録だが、イマイチな部分もあるのでベストのやり方ではないと思うのでその辺は真似をされる方は注意されたし

本来なら目的の一つの独自ドメインの運用を実現する場合はこの手順より先に、「AWS Certificate Manager」にて独自ドメインの取得管理が必要。今回はここの説明をするとかなり長くなるので省略する。(ここもかなりハマった..)

一応こんな感じまで持ってくるとあとは色々できるところを晒しておく。(リージョンを「バージニア北部」で行う必要があったり色々大変、詳しくはいろいろな記事を参照)

さて、CloudFrontの画面を開く、としたいところだが、まずはRoute53の設定をします。

左のような通信フローをとり、CloudFrontのオリジン先の登録はIPアドレスは不可のためLightsailで設定した静的アドレスに固定ドメインを登録する必要があります。

Route53でwp2.hiyuzawa.jpというWordPressを実サーバ(静的IP)に対応するオリジンを作成しました。

(結局ここで hiyuzawa.jp という独自ドメインが存在する前提の手順となってしまったが、これが不要でオリジンにDNSを割り当てる方法は無いのかな… (CloudFrontのオリジンに指定するだけの用途なのでAWSが勝手に用意した任意のもので構わないのだけど…)

次にCloudFrontの設定をする。CloudFrontの画面を開き、「Create Distribution」を選択する。色々設定項目があるがひとまず以下だけを登録して作成する。Cache Policyのところを一旦キャッシュを利かさないデフォルトの「Managed-CachingDisabled」を選択しておく。

しばらく待つと、StatusがDeployedに変わり、準備完了になります。

CloudFrontで割り当てられたドメインでアクセスすると、CSSが当たってない形なWordPressが表示されます。

GoogleChromeの開発モードで原因を調べると、HTTPSでのアクセスにおいてJavaScriptファイルなどがHTTPでアクセスをしているのでブロックされていることが原因です。

WordPressのHTTPS対応プラグインのインストール

上記問題を解決するために、WordPressのプラグインをインストールします。再び静的IPでWordPressの管理画面にログインしてください。まずは、日本語設定に変えちゃいましょう。左メニューの「Setting > General」と選んで Site Language を日本語に設定しましょう。

左メニュー「プラグイン > 新規追加」として「SSL Insecure Content Fixer」と検索。出てきたプラグインの「今すぐインストール」をクリックします。インストールが完了するとボタンが「有効化」と変わりますので、このボタンもクリックしてプラグインを有効化します。

インストールが完了すると、インストール済みプラグイン一覧画面になりますので、今インストールした「SSL Insecure Content Fixer」を探して「設定」をクリックします。設定画面では唯一、HTTPSの検出方法という項目で「HTTP_CLOUDFRONT_FORWARDED_PROTO (Amazon CloudFront HTTPS キャッシュ済みコンテンツ)」を選択して設定を保存としてください。

CloudFrontとWordPress(Lightsail)の間はHTTP。この設定により、CloudFront経由でのアクセスにはHTTP_CLOUDFRONT_FORWARDED_PROTOというヘッダが付与されてアクセスされるのでその場合は、HTTPSでアクセスされたという前提で処理してほしい(JavaScriptなどの参照はHTTPSとする)と指示をしていることになります。

さて、この状態で、CloudFront経由で再びアクセスしてみてください。残念ながらこれだけでは状況は変わらないはずです。先程のヘッダをオリジンに付与する設定をCloudFrontの設定で行う必要があります。

CloudFrontの設定 (Cache Policy)

この辺からかなり正解なやり方ではない気がします。本記事はとりあえず目的通りに動かすことを主眼においてますので、正確に理解したい場合は他のドキュメント等を参照ください。

CloudFrontの管理画面の左メニューから「Policies」を選択して「Create cache policy」を選択して新規にキャッシュポリシーを作成します。作成メニューではPolicy名を適当に入力します。

  • TTL Settings を Minimum TTL = 0 Maximum TTL = 1 Default TTL = 0 にセットします
  • Cache key Contents の Headers 項目を Whitelist を選択
  • すぐ下の虫眼鏡を選択すると色々出てくるのでそこから「CloudFront-Forwarded-Proto」と「Hosts」を選択
  • あとはそのまま 「Save Policy」で保存。

続けて、このPolicyをDistributionに割り当てます。CloudFrontメイン画面のDistributionで作成した設定を選択し詳細を開きます(IDの欄をクリックすると詳細になります)。 上部にタブが並びますが、「Behaviors」を選択、リストされた該当項目のラジオボタンをチェックして「Edit」を押します。Edit画面の中のCache Policyという項目の設定で先程つくったPolicyが選択できるのでそれを選択して画面下部の「Yes Edit」を選択します。

CloudFrontは設定を変えるたびにしばらく反映まで時間がかかります。メイン画面のステータスが「Deployed」となるまで待って、再びCloudFront経由でWordPressにアクセスしてみます。

無事にHTTPSで画面が表示されるはずです。

CloudFrontの設定 (Origin Request Policy)

ようやく終わったと思いきや、まだ続きます。CloudFront経由で管理画面にログインを試みてください。ログインができないと思います(おそらく、「Cookieを有効化すべき」とかそんなエラーになっていると思います。)

CloudFrontからオリジンまでの経路でCloudFrontの外側から来たCookie等がオリジンまで転送されていないことが原因です。ここの設定が必要です。

Cache Policy でアクセスした Policies を開き、上部のタブから「Origin request policy」の方を選択します。

Create origin request policy」を選択し、以下のように設定して新しいpolicy を作成します。

  • Name は適当に
  • Headers は 「All viewer headers」を選択
  • Cookies と Query Strings はどちらも 「All」を選択

作成が完了したら、Cache Policyを Distribution に割り当てた画面に再び表示し、 Cache Policyの設定のすぐ下にある「Origin Request Policy」に作成したPolicy を割り当てます。

これで再びログインしてみてください。ログインできると思います。

終わりに

これで、CloudFront経由、HTTPSでWordPressが運用可能です。これから

  • WordPressの管理者ユーザを別に作成 (デフォルトユーザは削除)
  • 画面左下にあるBitnamiのアイコンの削除
  • テーマ等のデザインの設定
  • 色々プラグインを入れたり消したり…

をしましょう。この部分の説明は割愛。色々な関連記事があります。

補足

本記事ではとりあえず目的通りに動作させることを優先したためおそらく、長期運用にはマズイ点が数箇所あります(詳しい人から言わせたらもっとあるかも…)

Cache Policyの設定の見直し

全てのCloudFrontのアクセスを実質キャッシュなしでオリジンまで通している。LightsailのIN/OUTの転送量にかかるコストを考慮すると、またCloudFront経由にしている意味を考えると、適切に設定すべき。全体的にTTLを伸ばすのは安直だが、管理者アクセスにて記事を記載&プレビューのときにまでキャッシュが効くと扱いづらい。

おそらく、この辺のAWSのドキュメントを参照しつつ、パス単位でCache Policyを設定するといい感じの設定が可能と思われる。(巷の技術記事にもこの辺の設定を説明したものもいくつか見つけることができる)

カスタムドメインでの運用

こちらはまずい点ではないが、CloudFrontのドメインをそのまま個人ブログサイトとして運用するのは相当カッコ悪い。ということでカスタムドメインを取得し割り当てることは必須でしょう。ドメインは各種サイトで取得可能だが、AWSでも取得できる(少しお高いが設定は楽)。Route53でのドメインの設定は「AWS Certificate Manager」で検索するとたくさん記事がでるのでそのとおりにやればOK。

CloudFrontへの設定は DistributionのGeneral 設定で可能。Alternate Domain Names (CNAMEs)に設定したいドメイン名、SSL Certificate を Custom SSL Certificate を選択して、「Certificate Manager」で登録したドメインを選択する。

更にRoute53にて カスタムドメイン に対してクラウドフロントドメインをマッピングすればOK