最近ブログの管理画面を操作していると、しばしば挙動が重くなるようになってしまった…
LightsailのインスタンスにSSHで接続してtopコマンドでリソースの使用料を見てみると、CPUとかメモリとかのリソースは…まあ足りてそう?

ただ、今後投稿数が増えていってインスタンス内に保管されるデータが増えていったら、それを遅延なく処理させるためにはメモリ1GBのインスタンスじゃ足りなかったかな…と思いつつ、インスタンスサイズを上げてみようかと思ったら。どうやらインスタンスサイズをそのまま上げることができず、一旦スナップショットを取得してからインスタンスサイズを大きくした新規インスタンスとして立ち上げる、って形になる様子。
ちょっとそこまでやるのは…というのと。サイズを上げると当然利用料も上がる訳で。。。
安易にサイズを上げる前にメモリも含めたリソース消費量を減らせないか、とGeminiに相談してみたところ、画像データを「外部(S3)に保存」し、「画像データの配信にCDN(CloudFront)を使用」することをおススメされた。
まあ、画像データは今のところ30MBくらいしか使って無さそうなんだけど、技術ブログの性質上スクショが多いので今後もがっつり増えていくだろう(そうだといいな)、っていうのを見越して早めに対処しておくことにする。
ちなみに、CDNやストレージのサービスとしてLightsail自身にその機能が具備されているが、今回はCloudFront/S3を使うことにした。
理由はそっちの方が安いから(*’ω’*)
いや、Lightsailを使った方が構築自体は簡単なんですがね…(遠い目
というのも、Lightsailの場合それぞれのサービスはサブスク形式で、5GBまで/約150円(Lightsailストレージ)とか50GBまで/約375円(Lightsailディストリビューション)、みたいにある一定の使用量に対して固定で料金がかかる。(1ドル=150円換算)
一方でAWSサービスの方だと、5GB(従量課金)/約15円(S3)、100GBまで/0円(CloudFront)くらい。
なお、CloudFrontの無料プランをサブスク登録すると、5GBまで無料のS3ストレージが付属するとのこと。
(静的ウェブサイトホスティングとかでCloudFrontとS3を紐付けて使用することを想定している模様。)
他にも色々WAFとか機能が付属する。

ってことで一旦AWSサービスの方を使って構築してみる。
(技術ブログなんだから難しい方でやろうぜ、っていうのもあったりなかったりw)
(使用量が増えてサブスクの方が安いなってなったらそっちに切り替えてみた、って記事をまた別途書くことになりそうですww)
とりあえずCloudFrontとS3を一回で導入するとトラブった時ややこしくなりそうなので、一旦S3から導入する。(CloudFront導入編は次回投稿あたりでやる予定。)
目次
S3構築手順
とりあえずS3の構築。と言ってもこっちはそんなに難しいことは無いけども。
1.S3画面左ペインの「汎用バケット」から「バケットを作成」をクリック

2.以下の通り値を入力
| 項目 | 値 | 備考 |
|---|---|---|
| バケットタイプ | 汎用 | |
| バケット名前空間 | アカウントのリージョナル名前空間 | 推奨と書いてあったのでこちらを選択したけど、グローバル名前空間でも良さそう |
| バケット名の接頭辞 | 任意の値を入力 | 名前空間にグローバルを選んでいるとここは「バケット名」になる |
| オブジェクトの所有者 | ACL有効 → 「オブジェクトライター」を選択 | |
| ブロックパブリックアクセス設定 | 「パブリックアクセスをすべてブロック」のチェックを外す (以下4つのチェックもすべて外したまま) | 警告文が出てくるので「~を承認します」のチェックを付けるのを忘れずに。 |
| バージョニング | 任意で設定 | |
| タグ | 任意で設定 | |
| 暗号化タイプ | S3マネージドキーを使用したサーバー側の暗号化(SSE-S3) | デフォルト値 |
| バケットキー | 有効にする | デフォルト値 |
| オブジェクトロック | 任意で設定 |

(以下デフォルト値 or 任意の設定なのでスクショは省略)
※ ここでパブリックアクセスを一部許可する設定をしているが、警告にあるようにこの設定は本来推奨されない。(後段でバケットポリシーを設定するが)S3のURLを知っているクライアントはこのS3バケット内のデータにアクセスできてしまう。取り扱いには厳重に注意すること。
※ なお、Redherringの場合、次回あたりにCloudFront化する予定があるため、一旦割り切って本構成を許容することにする。CloudFrontを使う場合はパブリックアクセスは全拒否でOKにできるので。
3.作成したバケットの詳細画面から「アクセス許可」を開き、バケットポリシー欄の「編集」をクリック



4.以下ポリシーを入力して「変更の保存」をクリック
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::【バケット名】/*"
}
]
}
ここまでで一旦S3の設定はOK。
IAMアクセスキーの作成
ここからWordpressがS3に画像データをアップロードするためのアクセスキーを作成する。
(今時アクセスキー作るのかよ、と思ったそこの貴方。私も思いましたw)
(EC2で立てていればIAMロールを割り当てて…ってできるんですが。Lightsailの場合IAMロールを割り当てる、っていう項目自体が無さそうなので已む無く。)
1.IAM画面の左ペインから「IAMユーザー」を選択し、「ユーザーの作成」をクリック

2.ユーザ名に任意の名前を入力して「次へ」
※ マネコンへのユーザアクセスは許可しなくてOK

3.ポリシーの選択画面で「ポリシーを直接アタッチする」から「ポリシーの作成」をクリック

4.別タブでポリシーの作成画面が開くので、エディタをJSONに切り替えてから以下コードを設定
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"s3:ListAccessPointsForObjectLambda",
"s3:GetAccessPoint",
"s3:PutAccountPublicAccessBlock",
"s3:ListAccessPoints",
"s3:CreateStorageLensGroup",
"s3:ListJobs",
"s3:PutStorageLensConfiguration",
"s3:ListMultiRegionAccessPoints",
"s3:ListStorageLensGroups",
"s3:ListStorageLensConfigurations",
"s3:GetAccountPublicAccessBlock",
"s3:ListAllMyBuckets",
"s3:ListAccessGrantsInstances",
"s3:PutAccessPointPublicAccessBlock",
"s3:CreateJob"
],
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"【バケット名】/*",
"【バケット名】"
]
}
]
}
5.ポリシー名と説明欄に任意の値を設定してから「ポリシーの作成」をクリック

6.IAMユーザー作成画面のタブに戻って、ポリシー一覧をリロードした後、作成したポリシーを検索・洗濯して「次へ」をクリック

7.内容を確認して、「ユーザの作成」をクリック

8.作成したIAMユーザの詳細を開き、「セキュリティ認証情報」タブから「アクセスキーを作成」をクリック

9.ユースケースで「サードパーティーサービス」を選択し、「確認」欄のチェックを付けてから「次へ」

10.「説明タグ」については任意で設定してから、「アクセスキーを作成」をクリック。
(特段載せる必要性を感じなかったのでスクショは省略)
11.アクセスキーが表示されたらアクセスキー/シークレットアクセスキーをそれぞれメモしておく。
警告が表示されているように、以降シークレットアクセスキーは二度と表示されないため、CSVファイルをダウンロードしておくことをおススメする。終わり次第「完了」をクリック。

ここまででIAMアクセスキー絡みの設定は完了。
Lightsail(WordPress)の設定
ここから作成したアクセスキーをWordPressに設定していく。といってもWordPressの管理画面からではなく、設定ファイルを直接編集するためLightsail側からアクセスする必要がある。
1.Lightsailインスタンスの管理画面から「SSHを使用して接続k」をクリックし、ターミナルを起動

2./var/www/wp-config.phpファイルを開いて編集する
### 書き込み権限の確認と付与
$ ls -la /var/www/wp-config.php
-r--r----- 1 admin www-data 3932 Jul 22 14:02 wp-config.php
$ sudo chmod u+w /var/www/wp-config.php
$ ls -la /var/www/wp-config.php
-rw-r----- 1 admin www-data 3932 Jul 22 14:02 wp-config.php
### 設定ファイルの編集(エディタは好みのもので可)
$ sudo chmod
sudo vi /var/www/wp-config.php
(略)
define( 'WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] . '/' );
define( 'WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/' );
define( 'WP_AUTO_UPDATE_CORE', 'minor' );
/* ここから追記 */
define( 'AS3CF_SETTINGS', serialize( array(
'provider' => 'aws',
'access-key-id' => '【アクセスキー】',
'secret-access-key' => '【シークレットアクセスキー】',
)));
/* ここまで追記 */
/* That's all, stop editing! Happy publishing. */
(略)
### 書き込み権限削除
$ sudo chmod u-w /var/www/wp-config.php
$ ls -la /var/www/wp-config.php
-r--r----- 1 admin www-data 3932 Jul 22 14:02 wp-config.php
WP Offload Media Lite(Wordpressプラグイン)の導入と設定
ここまでで一通りAWS側の設定はできたので、Wordpress自身を弄っていく。
1.WP Offload Media Liteプラグインのインストールと有効化
ここではインストールとか有効化の手順は記載しない。そんなに難しいことないので。。。
一応念のため、導入したプラグインのスクショだけ貼っておく。

2.プラグインの設定画面を開くとS3のバケット情報を聞かれるので、「Use Existing Bucket」にチェックがついていることを確認しつつ、「Enter bucket name」から作成したS3のバケット名を入力する
ちなみに、IAMポリシーで制限をかけているため、「Browse existing buckets」を選ぶと権限エラーになります…が正常動作です💦

3.S3バケットの追加設定を聞かれるけどスルーして続行
内容的には、「パブリックアクセスのブロック」「オブジェクトの所有者の強制」を有効にするかどうか、を聞かれてる。ただ、CloudFront使ってないみたいだからそのままでいいよ、的なことも書いてある。
その通りなのでそのままでOK。

4.Storage Settingsタブの真ん中位に「Storage provide is successfully connected ~」と表示されていればOK。

5.Storage Settingsは基本そのままでOK。上から順に設定を解説すると。
- Offload Media:画像データをS3にアップロードするか否か
- Remove Local Media:S3にアップロードした画像をローカルから削除するか(今はまだOFFで良い)
- Add Prefix to Bucket Path:指定したパスを使ってバケット内にフォルダを構成するか
- Add Year & Month to Bucket Path: yyyy/mm/のように年月ごとにフォルダを区切るか
- Add Object Version to Bucket Path:同一の画像をアップロードした際にURLが重複しないように識別用の文字を自動で追加するか

動作確認
ここまでできたら、動作確認をしてみる。
WordPressの管理画面上にある「メディア」から、或いは投稿上に画像を直接貼り付ける、などでもよいので、画像データを保存してみる。
その後S3バケットを確認し、画像が保存されていればOK。
ちなみにRedherringは一回やったら上手くいかず。。。
もともとIAMポリシーを絞っていたのを、フルアクセスにしたり。
ACL無効にしていたのを有効にしてみたりしてやっと通るようになりました…
(あ、本投稿のものはすでに変更してあるのでご安心ください👍)
既存の画像のS3移行
とここまで進めてきてから知ったが、既存の画像をS3に移行するには有料ライセンスが必要とのこと…
(商売のやり方が上手いなぁ…良いところを攻めてくるw)
そのあたりを一括でやるには別のプラグイン(Media Cloud)の方が良いとのこと。
直接的な画像数はそこまで多くないとは言え。手動で再編集するのも面倒だしプラグインを切り替えようかなぁ…と思っていたら。
Gemini曰く、S3(の同じフォルダ配下)に同じファイルがあれば自動的に参照先をそっちに切り替えてくれるといわれたので、WinSCPを繋いで画像ファイルを一括ダウンロードして、S3にアップロードしてみた…物の状況変わらず(´;ω;`)
もう一回Geminiに聞いたらそれじゃできないです、って。(喧嘩売ってんのかww)
ということでまたGeminiに聞きつつネットの海を彷徨ってみたところ。
どうやら画像データの再生成・再アップロードを自動でしてくれるプラグインがあるとのこと。
今回WP Offload Media Liteを入れた後にアップロードされた画像は自動でS3に格納されるため、それなら大丈夫そうかな、ってことでRegenerate Thumbnailsプラグイン導入して有効化。

WordPress管理画面左ペインの「ツール」から「Regenerate Thumbnails」をクリックすると設定画面が開く。
チェックボックスは両方とも外してから「~の添付ファイルすべてからサムネイルを再生成」をクリック。

こんな感じでログが流れ出すので待機。

完了したら、同じ要領でアイキャッチ画像の方も再生成しておく。
再生成終了後、(比較的数は少ないとはいえ)WP Offload Media LiteがS3に移行するまでちょっと時間がかかるのでもうちょっと待つ。
ちなみに進捗状況はプラグインの画面にて確認できるので、プログレスバーが伸びていくのを眺めながら待つ。

100% OffloadedになったらS3への移行完了(/・ω・)/
念のため確認したい方は、S3とかメディアライブラリにある任意の画像データのファイルのURLがS3のものになっているかを確認しておくと良き。
Regenerate Thumbnailsは多分もう要らない気がするので(お好みで)無効化・削除しておく。
WP Offload Media Liteの設定画面にあった「Remove Local Media」は、ちょっと今すぐチェックを入れるのは怖いのでw
もう少し様子見て大丈夫そうなら適宜チェックを入れることにする。
ということで今回はここまで。
次回はCloudFront使ってCDNを導入する予定です!

