📝

Next.js + Auth.js + Docker でTo-Doアプリを作った話

2024/09/13に公開

はじめに

Next.js アプリケーション開発の勉強をしています。
Auth.js (v5) によるGithub OAuth認証と、Drizzle ORMによるMySQLデータベース処理を行います。

データ取得はNext.jsサーバからHTMLを返す際に一緒に行うため、 SWRtRPC といったクライアントサイドでのデータ取得用のライブラリを使用しません。

この記事は Next.js で何かWebアプリケーションを作りたいなーという人向けに、技術スタック(どんなフレームワーク、ライブラリを組み合わせているか)の一例を示すような内容になっているのではと思います。

App Router + Server Action 等、Next.js が推している新しい技術を利用し、こんな感じになっています。

https://faveo-systema.net/sekirei-todo

Githubリポジトリはこちら。

https://github.com/daiius/sekirei-todo

認証部分

Next.jsはRC版(v15.0.0-rc.0)、Auth.jsはベータ版(5.0.0-beta.20)を使用しています。

詳しい解説は公式ドキュメントや他の記事にお願いして、大雑把な全体のコードを示します。

src/auth.ts

Auth.jsの初期化・設定や一部の処理内容を記述します。
https://github.com/Daiius/sekirei-todo/blob/main/src/auth.ts

src/middleware.ts

Next.jsのmiddleware機能の設定をします。
https://github.com/Daiius/sekirei-todo/blob/main/src/middleware.ts

今回は/tasks/の2つのパスにだけ、認証有無のチェックを設定しています。

src/actions/authenticate.ts

ログインボタンが押された際の処理、より正確にはformDataを受け取ってAuth.jsに処理を委譲する部分です。
https://github.com/Daiius/sekirei-todo/blob/main/src/actions/authenticate.ts

データベース部分

Drizzle ORM によるデータベース管理を行っています。Prismaといった大御所はありますが、TypeScriptのみでスキーマ定義やマイグレーションが完結する部分に魅力を感じ採用しています。

src/db/schema.ts

テーブル2つから成ります...が、2つ目のtasksテーブルしか使っていません。
https://github.com/Daiius/sekirei-todo/blob/main/src/db/schema.ts

src/db/index.ts

データベースとの接続関連の設定が入ります。
https://github.com/Daiius/sekirei-todo/blob/main/src/db/index.ts

src/actions/tasksActions.ts

タスク関連のサーバ側で行う処理をServer Actionとして定義しています。
https://github.com/Daiius/sekirei-todo/blob/main/src/actions/tasksActions.ts

Dockerを使った開発環境

Next.js + MySQL 環境を Docker (Docker Compose) で管理します。
https://github.com/Daiius/sekirei-todo/blob/main/docker-compose.yml
上記docker-compose.ymlファイルのdatabase-preparationサービスでは、Drizzle ORM(正確にはデータベース管理用のdrizzle-kitパッケージ)を使って開発環境に対して適切なテーブル生成とテスト用データを追加します。

Dockerを使ったDistroless本番環境

Next.jsアプリケーションを本番環境に配置する際にもDockerを使います。こちらの記事を参考にしています。
https://zenn.dev/kazumax4395/articles/427cc791f6145b

https://github.com/Daiius/sekirei-todo/blob/main/Dockerfile.nextjs.prod

この様なスクリプトで本番用コンテナをビルドします。
https://github.com/Daiius/sekirei-todo/blob/main/docker-build-production.sh

ポートフォワード関連のことが書いてあるのは...

本番環境用コンテナをビルドする際には、本番環境DBに接続できるようにメッセージを出しています。
直接外部からアクセスできない用にしているので、SSHポートフォワードを行ってから実行するようにしています。

(後発のプロジェクト用の設定で、このアプリケーションでは不要な設定です)

おわりに

素の React で SPA を作っていた時と比べ、Next.js は本当に出来ることが多く、難しく感じます。
でも逆に Next.js の範囲内で出来ることが把握できるほど、頼もしい存在にも思えます。

ベストプラクティスが何か中々分からない状況になった際には、公式ドキュメントに戻って考えるようにしています。

To-Doアプリという性格上、ほとんどのページが Dynamic Rendering になりましたが、次は静的なコンテンツを扱う際に Static Rendering も積極的に取り入れるものにしてみたいです(Static & Dynamic Rendering については こちら)。

Discussion