2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsとSupabaseでオンライ学習プラットフォーム(LMS)を構築する | エピソード10: デプロイとセキュリティ強化、未来の拡張アイデア

Posted at

こんにちは!前回のエピソードでは、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をデプロイします。

  1. GitHubリポジトリの準備

    • プロジェクトをGitHubリポジトリにプッシュ(例: next-lms)。
    • .gitignore.env.localを追加し、機密情報が公開されないようにする。
  2. 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)を選択。
  3. カスタムドメインの設定(オプション)

    • Vercelの「Domains」セクションでカスタムドメイン(例: your-lms.com)を追加。
    • DNS設定を更新(Vercelが提供するNSレコードを使用)。
  4. デプロイの確認

    • Vercelが自動でビルドとデプロイを実行。
    • デプロイURL(例: https://next-lms.vercel.app)にアクセスし、コース一覧、ログイン、コメント、決済が正しく動作することを確認。

ステップ2: Supabaseのセキュリティ強化

本番環境では、セキュリティを強化してデータとユーザーを保護します。

  1. 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が正しく機能することを確認。
  2. 環境変数の保護

    • .env.local.env.productionにコピーし、Vercelの環境変数に設定。
    • Supabaseの「Anon Key」を本番用のキーに置き換え(ダッシュボードで生成)。
    • Stripeのテストキーを本番キーに変更(Stripeダッシュボードで取得)。
  3. CORSとリダイレクトの設定

    • Supabaseダッシュボードの「Authentication」→「Redirect URLs」にVercelのデプロイURL(例: https://next-lms.vercel.app/api/auth/callback)を追加。
    • 「Settings」→「API」でCORS設定を確認(*は本番では避け、特定ドメインを指定)。
  4. データベースのバックアップ

    • Supabaseの「Database」→「Backups」で自動バックアップを有効化。
    • 定期的にバックアップをテスト復元し、データ復旧が可能か確認。

ステップ3: GitHub ActionsでCI/CDを設定

GitHub Actionsを使って、コードのテストと自動デプロイをセットアップします。

  1. ワークフローファイルの作成
    /.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 }}
  1. 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。
  2. テストの準備

    • テストが未実装の場合、仮のテストスクリプトをpackage.jsonに追加:
"scripts": {
  "test": "echo 'Running tests...' && exit 0"
}
  • 本番では、JestやCypressでユニット/統合テストを実装することを推奨。
  1. CI/CDの確認
    • コードをmainブランチにプッシュ。
    • GitHubの「Actions」タブでワークフローが実行され、ビルドとデプロイが成功することを確認。
    • Vercelのデプロイが自動更新される。

ステップ4: 拡張アイデアの提案

LMSをさらに進化させるためのアイデアを提案します。

  1. AIによるコース推薦
// 例: 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>
  );
}
  1. 学習分析ダッシュボード
    • ユーザーの学習進捗を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;
  1. クイズとゲーミフィケーション

    • quizzesテーブルを追加し、レッスンごとのクイズを管理。
    • クイズ回答をリアルタイムで採点(Supabase Functions)。
    • バッジやポイントシステムを導入し、学習意欲を向上。
  2. 多言語対応

    • Next.jsのi18nextを統合し、コースとUIを多言語化(例: 英語、ベトナム語)。
    • Supabaseにtranslationsテーブルを追加し、翻訳データを管理。

ステップ5: 動作確認

  1. デプロイの確認

    • VercelのデプロイURL(例: https://next-lms.vercel.app)にアクセス。
    • コース一覧、ログイン、コメント、決済、PWA機能、プッシュ通知が正しく動作。
    • モバイルでPWAをインストールし、ネイティブアプリのような体験を確認。
  2. セキュリティのテスト

    • 未認証ユーザーで保護されたリソース(例: /dashboard)にアクセスし、リダイレクトを確認。
    • テストユーザーで不正なコメント投稿を試み、RLSがブロックすることを確認。
    • Supabaseのログで異常なアクセスがないか確認。
  3. CI/CDのテスト

    • コードを変更(例: ヘッダーのテキスト)し、mainにプッシュ。
    • GitHub Actionsでビルドとデプロイが成功し、Vercelに反映。
  4. パフォーマンスの確認

    • Lighthouseを本番URLで実行し、パフォーマンススコアが90以上であることを確認。
    • LCP、CLS、TBTが最適化されていることを再確認。

まとめと今後の展望

この最終エピソードでは、LMSをVercelにデプロイし、セキュリティを強化、CI/CDを設定しました。さらに、AI推薦や学習分析などの拡張アイデアを提案しました。これで、LMSは本番環境で安全かつスケーラブルに運用可能になり、ユーザーに高品質な学習体験を提供できます!

このシリーズを通じて、Next.jsとSupabaseを使ったフル機能のLMSをゼロから構築しました。認証、コース管理、ビデオ配信、決済、リアルタイムコメント、パフォーマンス最適化、PWA、デプロイまでをカバーし、モダンなWebアプリ開発のベストプラクティスを学びました。今後は、ユーザーフィードバックを基に新機能を追加したり、コミュニティ機能を拡張したりして、LMSをさらに成長させましょう!


このシリーズが役に立ったと思ったら、ぜひ「いいね」を押して、ストックしていただければ嬉しいです!皆さんのLMSプロジェクトの成功を祈っています!

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?