⚒️

Platforms Starter Kit を使ってマルチテナントアプリケーションをサクッとつくる

2022/05/07に公開

どうも、黒神(@kokushing)です。

新規 CMS 開発案件で Platforms Starter Kit に触れる機会があったので、得た知見を書き残しておきます。

国内での採用事例も少なそうなので、進行形でこの投稿に追記していきます。これから採用を検討する/触れる機会のある方々の助けになれば幸いです。

Platforms Starter Kit とは

Next.js ユーザならお馴染みの Vercel が開発している、マルチテナントアプリケーションを開発するためのスターターキットです。

https://vercel.com/guides/nextjs-multi-tenant-application

以下のような構成に基づいて設計されています:

  • コアフレームワーク: Next.js
  • 認証: NextAuth
  • スタイリング: Tailwind CSS
  • DB: PlanetScale
  • ORM: Prisma
  • ホスティング: Vercel

マルチテナントアプリケーションというのは、複数のユーザが同じサーバやデータベースなどを共有して利用するアプリケーションのことです。

有名どころだと BASE など、自分のアカウント ID がサブドメインになるようなサービスをイメージしてもらえるとわかりやすいかなと思います。

今回はそれぞれのアカウント内で自分のワークスペースを持つことができ、さらにその中に投稿機能があるといった CMS を実装する必要があったため、かなり相性が良いのでは?と考えています。

なお、この Platforms Starter Kit に標準搭載されている機能は下記のような感じです。

  • GitHub ログイン機能
  • サイト作成/編集/削除機能
  • 記事投稿/編集/削除機能
    • 下書き機能
    • 自動保存機能
    • マークダウンエディタ機能
  • サブドメイン/独自ドメイン設定機能

最低限の CMS に必要な機能は実装されていますね。素晴らしい。

実際に実装の流れを見ていきましょう。

実装の流れ

ボイラープレートを展開

下記コマンドで任意のディレクトリ内にボイラープレートを展開できます。

npx create-next-app . --example https://github.com/vercel/platforms/tree/main platforms

.env の用意

.env.example をコピーして .env にリネームします。

cp .env.example .env

SECRET キーの生成

内部的な暗号化で使用されるシークレットキーを下記のサイトで生成して、.env の SECRET に追記します。

https://generate-secret.vercel.app/32

SECRET=3fa29xxxxx...

GitHub App を作成

GitHub の設定ページから App を作成します。

https://github.com/settings/apps

アプリ名や説明文は適当に、Callback URL は下記を指定。

http://app.localhost:3000

Webhook の項目、Active にチェックが入っていたら外しておきます。

入力できたら「Create Github App」をクリックしてアプリを作成します。

続けて「Generate a new client secret」ボタンを押して Client secret を生成します。

取得した Client ID と Client secret を .env に追記します。

GITHUB_ID=Iv1.xxxxx...
GITHUB_SECRET=aa89b0xxxxx...

開発用 MySQL 環境の用意

Platforms Starter Kit は PlanetScale の利用を推奨していますが、開発中はローカルの MySQL を使いたいので、docker でサクッと MySQL の環境を構築します。

compose.yml を作成します。

services:
  db:
    image: mysql:8.0
    ports:
      - 3308:3306
    volumes:
      - db-store:/var/lib/mysql
      - ./mysql_logs:/var/log/mysql
    environment:
      MYSQL_DATABASE: psk_dev
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: password
      TZ: "Asia/Tokyo"
volumes:
  db-store:

※psk_dev は任意の DB 名に書き換えてください

コンテナを立ち上げ:

docker compose up

起動確認したら、.env の DATABASE_URL を編集します。

DATABASE_URL=mysql://root:password@localhost:3308/psk_dev

DB と Prisma を接続し、migrate を実行

MySQL のコンテナが立ち上がっている状態で、下記コマンドを実行し Prisma のマイグレーションファイルを生成します。

npx prisma migrate dev --name init

「Your database is now in sync with your schema」と表示されれば OK

アプリの起動

下記コマンドでローカルサーバを起動します。

npm run dev

http://app.localhost:3000/login にアクセスするとログイン画面が表示されます。

GitHub でログインしましょう。

GitHub連携の確認画面が出るので許可します。

ログインが完了すると http://app.localhost:3000/ にリダイレクトし、ダッシュボード画面が表示されます。

これにて環境構築は完了です。

サイトを追加

ダッシュボードの右上にある「New Site」を押すと、サイトを新規作成する画面に遷移します。

Slack でいうワークスペースを作成する感じですね。

マルチテナントアプリケーションなのでサブドメインも当然設定できます。

自分のサイトを作成できました!

さらに「New Post」から記事を作成して投稿できるようです。

最初から下書き機能とマークダウンエディタが用意されています、すごい。

Vercel にデプロイしていないので Publish しても 404 エラーになってしまいますが、DB を見ると Posts テーブルにしっかりとデータが保存されているのがわかります。

下記コマンドで Prisma Studio を起動し、Posts の中身を覗いてみましょう。

npx prisma studio

Settings タブからは記事の設定を行うことができ、公開 URL 設定や OGP 画像の設定も可能です。

実際に公開して運用する手順

以上で一旦ローカルでの動作確認及び開発は着手できそうですが、実際にマルチテナントアプリケーションとして運用するには Vercel へのデプロイやドメイン設定、 PlanetScale との連携、Cloudinary など CDN との連携が必要になるようです。

この辺りは次の記事でまとめようと思います。

まとめ

驚くほどサクッとマルチテナントアプリケーションを作成することができました。

NextAuth を利用しているので、メールログインや Twitter ログインの実装も簡単ですし、Next.js がベースになっているので API Routes による API 実装も簡単にできそうですね。フロントエンド寄りの知識で完結するのが本当に強い。

近い仕様のマルチテナントアプリケーションを実装する場合は、そのままこのボイラープレートを拡張することで大幅なコストカットになりそうです。

興味のある方はぜひお試しください。

サンプルリポジトリ

記事で利用したソースコードをご覧いただけます。

https://github.com/kokushin/platforms-starter-kit

参考リンク

makery,inc

Discussion