zu-min.com

ブログをサーバーレスにする

サーバーnext.js生成AIインフラlambdaaws
ブログをサーバーレスにする

趣味用サーバーとして VPS を借りていたのですが、最近はブログしか稼働していなかったので費用的にもったいない気がしてきました。 唯一稼働しているブログに関しても、コメント機能や検索機能をあきらめれば SSG にできるので、サーバーレス化してコスト圧縮をしてみます。

課題1:サーバー費用

アクセス数少なめの WordPress ブログしか動かしていないのにサーバーだけで2万円/年かかっている状況です。 プラグインは入ってますがデザインは凝ってないので WordPress.com ならプレミアムの 13,200円/年で十分のはずです。 SaaS ならサーバー自体もサーバーの上に載っているものも気にせずブログ運営できるので、サーバだけ用意するのでこの価格なのはかなり割高に感じます。

課題2:保守コスト

元は WordPress でブログを書いており、Linux + nginx + MySQL + PHP なよくある構成だったのですが、 OS やミドルウェア、言語の更新が手間で放置してしまいがちでした1。 WordPress 自体は自動更新があるので簡単なのですが、それ以外は自動化が難しい部分があったのでこれの改善を目指します。

課題3:記事を書きやすくしたい

WordPress の Gutenberg は「文章を書く」用途の WYSIWYG エディタとしては最高です。 これ以上のものとは出会ったことがありません。 ただ、やはり技術者なのでどうしても文章は markdown で書きたくなってしまいます。

課題4:見た目の修正を簡単にしたい

WordPress だと PHP を書き換える必要があるので、カスタマイズがちょっと面倒です。 PHP の知識に加えて WordPress のプラグインやテーマの知識も必要になります。

CSS と js と HTML のみして、 カスタマイズで考えることを少なくするのが理想です。

課題1と2の解決:サーバーレス化

もともと私はアプリケーション開発の人なので、インフラは本業ではありません。 できるだけアプリケーション開発とブログ記事執筆以外の部分は減らしたいです。

インフラは Vercel にしようか悩みましたが 2、今回は使い慣れた AWS Lambda を使う構成にしました。 多分規模的にも AWS で組んだ方が安くすむ予想です。

インフラ すっきり。

Lambda の中身は next.js と aws-lambda-web-adapter です3

課題3と4の解決:next.js で Markdown を使う

フレームワークに関しては、最近はずっと next.js を触っていたので 深く考えずに next.js にしました。 完全に SSG にして静的な HTML を配置する案も考えましたが、 それだとちょっと面白みがないかなということで動的ページも作れる余地を残しておくことにしました。

ただ、 next.js は React なので、 Markdown を React に変換する必要があります。 ある程度プログラムを書く必要がありました。

あとは WordPress にある既存の記事を Markdown に変換する必要があります。

生成 AI

こういった品質が重要ではない、規模が小さい、一般的な技術しか使わないというような要件は生成 AI の出番です。 今回は大部分を生成 AI に書いてもらいました。

以下のような流れで実装を依頼しました。 色々な生成 AI を試したかったので途中でツールを切り替えています。

  1. ChatGPT で実現方法を探る
  2. 手動で next.js プロジェクトを作り、 ChatGPT が作ったコードをコピー
  3. Codex で機能追加する
  4. Claude Code で機能追加する

自分がやったことと言えば

  • やりたいことを日本語で伝える
    • 例: sitemap.xml を作成してください。 next.js の sitemap.ts を利用してください。
  • コードレビュー
    1. 私: 開発環境だけ下書きの記事を出したい
    2. 生成 AI: NODE_ENV を見て切り替えるコードを書く
    3. 私: 環境ではなく機能フラグを使うようにしてと指摘 4
  • 動作確認結果を伝える
    • CSS がうまく当たってないとき、ブラウザの DevTool 見るとこれが適用されているよ、と言う
  • コード書きたくなった時に書く
  • 色味やレイアウトの微調整は手動で
    • tailwind わからんので頑張った

コードのタイピングとググる回数は減りましたが、 かじ取りは手動で行う必要がある印象です。

チャットのやり取り数

何となくどれくらいのやり取りでこの規模の実装ができるのか知りたかったので、 生成 AI とのやり取りの数を書き出してみます。

ChatGPT

  • next.js で markdown のブログサイトを構築する方法を教えてください
    • 4回やりとり

ここでは記事一覧と記事ページのみを作成

Codex (VS Code 拡張)

  • wordpress のブログ記事をマークダウンとして出力する方法はありますか?
    • 30回
    • WordPress eXtended RSS から markdown へ変換するツール作成
  • この React コンポーネントを tailwind で置き換えてください
    • 28回
    • ChatGPT が作成したブログアプリケーションの修正を行う

Codex とのチャット ちょっと無視しても怒られない

Claude Code (VS Code 拡張)

  • タグクラウドとタグの記事一覧ページを作って
    • 6回
  • デプロイ時、画像は S3 に上げて
    • 8回
  • 画像のベース URL (ドメイン) は環境変数からとってきて
    • 1回
  • Dockerfile の npm ci についてレイヤを最適化して
    • 3回
  • tailwind でダークモード切替を実装して
    • 2回
  • tailwind で薄い文字色を定義して
    • 1回
  • 前の記事、次の記事リンクを作成して
    • 1回
  • 下書き機能を追加して
    • 7回
  • デプロイ時に CloudFront のキャッシュを invalidate してる処理と、 CloudFront キャッシュビヘイビアを修正してもらう
    • 10回
  • WordPress の XML から markdown へ変換する時、公開中の記事と下書き中の記事の変換結果を別のディレクトリに配置して
    • 2回
  • 下書き記事はタイトルに「下書き」と出すようにして
    • 1回
  • 記事ページにその記事のタグを出すようにして
    • 1回
  • 記事ページのタグについて、ライトモードで背景色が適用されません。ブラウザで反映されている css を貼る
    • 4回
  • next.js でハッシュリンクで遷移する時に target 疑似要素のスタイルが適用されません
    • 2回(未解決
  • RSS 用の Atom フィードを出すようにして
    • 1回
  • sitemap.xml を出すようにして
    • 3回
  • /_next/image パスの CloudFront キャッシュ設定を追加して
    • 2回
  • Google Analytics と AdSense のタグを追加して
    • 1回
  • about ページを追加して
    • 2回。中身は自分で旧サイトから移植しました
  • Cookie バナーを作って
    • 2回
  • not found ページを作成して
    • 1回
  • CloudFront に HTTP2/3 と代替ドメインを設定して
    • 2回
  • ビルド速度改善のためキャッシュを入れて
    • 3回

感想

VS Code 立ち上げるほどの気分になっていない段階では、 ブラウザ開いて ChatGPT に聞くのは手軽でとてもよいです。

Codex はなんとなくレスポンスが速いような気がします。 正確さより会話の回数を増やしてどんどん試行錯誤していく感じでした。

Claude Code でチャットの数が多くなるのは チャットを簡単に追加しやすい UI になっているからで、 Web ブラウザのタブ並みに溜まってしまいました。 最後の方はこのサクサクとチャットを立ち上げるノリを気に入って ずっと Claude Code を使っていました。

Gemini もインストールしてましたが使うのを忘れてました。

置き換えた結果

Markdown 快適です。 文章を書くための必要最低限の機能しかないので書くことに集中できます。

CloudFront で画像だけでなくページもキャッシュするようにしたのでちょっと早くなりました5

TOC と Footnotes もきれいになったと思います。 WordPress では入れるの面倒だったのであきらめてましたが、 ようやくほしいものを実装できました。

あと React と tailwind 楽しいです6

Footnotes

  1. 記事自体も2年半くらい書いてないが

  2. 今は衆院選の時期なので投票先を調べているのですが、某政党の収支明細に vercel の請求が入っていてなんとなく出遅れた気持ちになっています

  3. 最近更新されていないのでちょっと不安

  4. こういう時は環境名ではなく機能フラグで分岐した方が使いやすい。たとえば開発環境で本番と同様の表示を確認したい場合など。

  5. 過去に WordPress でやろうとして管理用ツールバーをキャッシュしたトラウマを克服

  6. これを機に、Wordpress テーマ変更のたびにだんだん劣化している見た目、というか記事の読みやすさを改善したい。広告に関してはご容赦いただけると・・・