こんにちは!前回のエピソードでは、LMSをProgressive Web App(PWA)に変換し、オフライン機能とプッシュ通知を追加しました。今回は、シリーズの最終回として、LMSをVercelにデプロイし、セキュリティを強化、継続的インテグレーション/デリバリー(CI/CD)を設定します。さらに、AIによるコース推薦や学習分析などの未来の拡張アイデアを提案します。これで、LMSが本番環境で安全かつスケーラブルに運用可能になります!
このエピソードのゴール
- VercelにLMSをデプロイ。
- Supabaseのセキュリティ設定を強化(RLS、環境変数)。
- GitHub ActionsでCI/CDを設定。
- AI推薦や学習分析などの拡張アイデアを提案。
必要なもの
- 前回のプロジェクト(
next-lms
)がセットアップ済み。 - Supabaseプロジェクト(全テーブル設定済み)。
- Vercelアカウント(無料プランで十分)。
- GitHubリポジトリ。
- 基本的なTypeScript、React、Next.js、CI/CDの知識。
ステップ1: Vercelへのデプロイ
Vercelを使ってLMSをデプロイします。
-
GitHubリポジトリの準備:
- プロジェクトをGitHubリポジトリにプッシュ(例:
next-lms
)。 -
.gitignore
に.env.local
を追加し、機密情報が公開されないようにする。
- プロジェクトをGitHubリポジトリにプッシュ(例:
-
Vercelでのプロジェクト設定:
- Vercelダッシュボードにログイン。
- 「New Project」→GitHubリポジトリをインポート。
- 環境変数を設定:
-
NEXT_PUBLIC_SUPABASE_URL
: SupabaseプロジェクトのURL。 -
NEXT_PUBLIC_SUPABASE_ANON_KEY
: Supabaseの公開キー。 -
STRIPE_SECRET_KEY
: Stripeのシークレットキー。 -
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
: Stripeの公開キー。
-
- ビルド設定はデフォルト(Next.js)を選択。
-
カスタムドメインの設定(オプション):
- Vercelの「Domains」セクションでカスタムドメイン(例:
your-lms.com
)を追加。 - DNS設定を更新(Vercelが提供するNSレコードを使用)。
- Vercelの「Domains」セクションでカスタムドメイン(例:
-
デプロイの確認:
- Vercelが自動でビルドとデプロイを実行。
- デプロイURL(例:
https://next-lms.vercel.app
)にアクセスし、コース一覧、ログイン、コメント、決済が正しく動作することを確認。
ステップ2: Supabaseのセキュリティ強化
本番環境では、セキュリティを強化してデータとユーザーを保護します。
-
Row-Level Security(RLS)の確認:
- Supabaseダッシュボードの「Authentication」→「Policies」で以下を確認:
-
courses
: 閲覧は全員、作成/更新はinstructor_id = auth.uid()
。 -
lessons
: 閲覧は全員、作成/更新はコースのinstructor_id = auth.uid()
。 -
purchases
: 閲覧/作成はuser_id = auth.uid()
。 -
comments
: 閲覧は全員、作成/更新/削除はuser_id = auth.uid()
。
-
- テストユーザーで不正アクセスを試み、RLSが正しく機能することを確認。
- Supabaseダッシュボードの「Authentication」→「Policies」で以下を確認:
-
環境変数の保護:
-
.env.local
を.env.production
にコピーし、Vercelの環境変数に設定。 - Supabaseの「Anon Key」を本番用のキーに置き換え(ダッシュボードで生成)。
- Stripeのテストキーを本番キーに変更(Stripeダッシュボードで取得)。
-
-
CORSとリダイレクトの設定:
- Supabaseダッシュボードの「Authentication」→「Redirect URLs」にVercelのデプロイURL(例:
https://next-lms.vercel.app/api/auth/callback
)を追加。 - 「Settings」→「API」でCORS設定を確認(
*
は本番では避け、特定ドメインを指定)。
- Supabaseダッシュボードの「Authentication」→「Redirect URLs」にVercelのデプロイURL(例:
-
データベースのバックアップ:
- Supabaseの「Database」→「Backups」で自動バックアップを有効化。
- 定期的にバックアップをテスト復元し、データ復旧が可能か確認。
ステップ3: GitHub ActionsでCI/CDを設定
GitHub Actionsを使って、コードのテストと自動デプロイをセットアップします。
-
ワークフローファイルの作成:
/.github/workflows/ci-cd.yml
を作成:
name: CI/CD Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build-and-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
NEXT_PUBLIC_SUPABASE_URL: ${{ secrets.NEXT_PUBLIC_SUPABASE_URL }}
NEXT_PUBLIC_SUPABASE_ANON_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_ANON_KEY }}
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: ${{ secrets.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY }}
- name: Build
run: npm run build
deploy:
needs: build-and-test
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
scope: ${{ secrets.VERCEL_ORG_ID }}
-
GitHub Secretsの設定:
- GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」で以下を設定:
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
STRIPE_SECRET_KEY
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
-
VERCEL_TOKEN
: VercelのAPIトークン(Vercelダッシュボードで生成)。 -
VERCEL_ORG_ID
: Vercelの組織ID。 -
VERCEL_PROJECT_ID
: VercelのプロジェクトID。
- GitHubリポジトリの「Settings」→「Secrets and variables」→「Actions」で以下を設定:
-
テストの準備:
- テストが未実装の場合、仮のテストスクリプトを
package.json
に追加:
- テストが未実装の場合、仮のテストスクリプトを
"scripts": {
"test": "echo 'Running tests...' && exit 0"
}
- 本番では、JestやCypressでユニット/統合テストを実装することを推奨。
-
CI/CDの確認:
- コードを
main
ブランチにプッシュ。 - GitHubの「Actions」タブでワークフローが実行され、ビルドとデプロイが成功することを確認。
- Vercelのデプロイが自動更新される。
- コードを
ステップ4: 拡張アイデアの提案
LMSをさらに進化させるためのアイデアを提案します。
-
AIによるコース推薦:
- ユーザーの閲覧履歴や購入履歴をSupabaseに保存(
user_activity
テーブル)。 - xAIのAPI(https://x.ai/api)を活用し、ユーザーデータを基にコースを推薦。
- クライアントサイドで推薦コースを動的に表示:
- ユーザーの閲覧履歴や購入履歴をSupabaseに保存(
// 例: src/components/CourseRecommendations.tsx
'use client';
import { useState, useEffect } from 'react';
import { supabase } from '@/lib/supabase';
export default function CourseRecommendations({ userId }: { userId: string }) {
const [recommendations, setRecommendations] = useState([]);
useEffect(() => {
async function fetchRecommendations() {
// 仮のAPI呼び出し
const response = await fetch('/api/recommendations', {
method: 'POST',
body: JSON.stringify({ userId }),
});
const data = await response.json();
setRecommendations(data.courses);
}
fetchRecommendations();
}, [userId]);
return (
<div>
<h2 className="text-2xl font-semibold mb-4">おすすめコース</h2>
{/* コース一覧を表示 */}
</div>
);
}
-
学習分析ダッシュボード:
- ユーザーの学習進捗を
progress
テーブルに保存(例: レッスン視聴時間、クイズ結果)。 - ダッシュボードページ(
/dashboard
)を拡張し、進捗グラフを表示(例: Chart.js)。 - SupabaseのSQLクエリで進捗データを集計:
- ユーザーの学習進捗を
SELECT
l.title,
COUNT(p.lesson_id) as completions
FROM lessons l
LEFT JOIN progress p ON l.id = p.lesson_id
WHERE p.user_id = 'ユーザーID'
GROUP BY l.title;
-
クイズとゲーミフィケーション:
-
quizzes
テーブルを追加し、レッスンごとのクイズを管理。 - クイズ回答をリアルタイムで採点(Supabase Functions)。
- バッジやポイントシステムを導入し、学習意欲を向上。
-
-
多言語対応:
- Next.jsの
i18next
を統合し、コースとUIを多言語化(例: 英語、ベトナム語)。 - Supabaseに
translations
テーブルを追加し、翻訳データを管理。
- Next.jsの
ステップ5: 動作確認
-
デプロイの確認:
- VercelのデプロイURL(例:
https://next-lms.vercel.app
)にアクセス。 - コース一覧、ログイン、コメント、決済、PWA機能、プッシュ通知が正しく動作。
- モバイルでPWAをインストールし、ネイティブアプリのような体験を確認。
- VercelのデプロイURL(例:
-
セキュリティのテスト:
- 未認証ユーザーで保護されたリソース(例:
/dashboard
)にアクセスし、リダイレクトを確認。 - テストユーザーで不正なコメント投稿を試み、RLSがブロックすることを確認。
- Supabaseのログで異常なアクセスがないか確認。
- 未認証ユーザーで保護されたリソース(例:
-
CI/CDのテスト:
- コードを変更(例: ヘッダーのテキスト)し、
main
にプッシュ。 - GitHub Actionsでビルドとデプロイが成功し、Vercelに反映。
- コードを変更(例: ヘッダーのテキスト)し、
-
パフォーマンスの確認:
- Lighthouseを本番URLで実行し、パフォーマンススコアが90以上であることを確認。
- LCP、CLS、TBTが最適化されていることを再確認。
まとめと今後の展望
この最終エピソードでは、LMSをVercelにデプロイし、セキュリティを強化、CI/CDを設定しました。さらに、AI推薦や学習分析などの拡張アイデアを提案しました。これで、LMSは本番環境で安全かつスケーラブルに運用可能になり、ユーザーに高品質な学習体験を提供できます!
このシリーズを通じて、Next.jsとSupabaseを使ったフル機能のLMSをゼロから構築しました。認証、コース管理、ビデオ配信、決済、リアルタイムコメント、パフォーマンス最適化、PWA、デプロイまでをカバーし、モダンなWebアプリ開発のベストプラクティスを学びました。今後は、ユーザーフィードバックを基に新機能を追加したり、コミュニティ機能を拡張したりして、LMSをさらに成長させましょう!
このシリーズが役に立ったと思ったら、ぜひ「いいね」を押して、ストックしていただければ嬉しいです!皆さんのLMSプロジェクトの成功を祈っています!