Webサイトをr2+Cloudflare CDNに移行した
はじめに
長らくOCI(Oracle Cloud Infrastructure)上で稼働していた本サイトのフロントエンドをCloudflare R2+CDNに移行してみた。 移行の目的はOCIへの負荷集中を解消し、サーバーレスな静的配信構成、かつセキュリティを上げるために切り替えることだった。
移行前後の構成比較
移行で発生した課題と対処
1. mt-search.cgiが使えなくなった
原因
R2は静的ファイル配信のみでCGIを実行できない。またDBへの接続もR2からだとできない。
対処 Pagefindを導入し、静的な検索インデックスを生成する方式に切り替えてみた。
- MTの再構築時にPagefindがHTMLを解析してインデックスを生成
- インデックスファイルもR2に同期
- ブラウザ上でJavaScriptのみで検索が完結(サーバー不要)
pagefind --site /var/www/html/ --output-path /var/www/html/pagefind
UIはモーダル表示を採用。検索アイコンをクリックするとモーダルが開き、リアルタイムで結果が表示されるように。
2. ブログ記事一覧のページネーションが壊れた
原因
従来のページネーションはmt-search.cgiのURLを生成するMTタグに依存してR2ではエラーが出てしまう。
対処
全記事を1つのHTMLに出力し、JavaScriptで10件ずつ表示・切り替えるページネーションに変更した。
var items = Array.from(document.querySelectorAll('#entry-list .entry-item'));
var perPage = 10;
var totalPages = Math.ceil(items.length / perPage);
記事が増えても自動でページ数が増えるためテンプレートの変更が不要になった。
3. シンボリックリンク配下のCSSが転送されない
原因
/var/www/html/mt-static がシンボリックリンクになっており、rcloneがリンク先を追跡しなかった。
※これは実は自分の環境の問題なので一応事例まで。
対処
一時ディレクトリにすべてのファイルを実体として集約してからR2に転送する方式に変更した。
cp -rp /var/www/html/. $TEMP_DIR/
rm -rf $TEMP_DIR/mt-static
cp -rp /var/www/html/mt-static/. $TEMP_DIR/mt-static/
cp -rp /var/www/html/support/theme_static/. $TEMP_DIR/mt-static/support/theme_static/
デプロイスクリプト(mt-deploy.sh)
再構築後に以下のスクリプトを実行するだけで本番に反映されるように。
# 1. Pagefindインデックス生成
pagefind --site /var/www/html/ --output-path /var/www/html/pagefind
# 2. 一時ディレクトリに全ファイルを集約・URL置換
rm -rf /tmp/mt-deploy
cp -rp /var/www/html/. /tmp/mt-deploy/
find /tmp/mt-deploy -name "*.html" -exec \
sed -i 's|mt-oci\.xichtech\.com/|xichtech.com/|g' {} \;
# 3. R2へ差分同期
rclone sync /tmp/mt-deploy r2:xichtech-web/ --checksum
# 4. Cloudflareキャッシュパージ
curl -X POST "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/purge_cache" \
-H "Authorization: Bearer ${API_TOKEN}" \
-d '{"purge_everything":true}'
またMTの自動再構築cronと直列で実行されるため、記事公開から本番反映まで自動化されている。
*/10 9-21 * * * cd /var/www/cgi-bin/mt && ./tools/run-periodic-tasks && /usr/local/bin/mt-deploy.sh
まとめ
| 項目 | 移行前 | 移行後 |
|---|---|---|
| フロントエンド配信 | OCI(Apache) | Cloudflare R2 + CDN |
| 検索機能 | mt-search.cgi(動的) | Pagefind(静的インデックス) |
| ページネーション | mt-search.cgi依存 | JavaScript |
| Egress費用 | OCI転送費用あり | R2は無料 |
| スケール性 | OCIスペック依存 | Cloudflare側で自動吸収 |
| OCI役割 | フル稼働 | MT管理・再構築専用 |
移行作業は思ったより課題が多かったが、完成した構成はシンプルで運用しやすい。 記事が増えてもPagefindとJSページネーションが自動対応するため、しばらくはこの構成で運用していく予定。
↓↓↓
ちなみにこの記事の99.99999%は今回大活躍したClaudeに書いてもらいました!!!